From ab1bd2fd07b535209dd57ea00df4dc5794f9827f Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Sun, 4 Jan 2015 16:33:25 +0100 Subject: [PATCH 001/370] app_server: rename DrawingContext to Canvas * Better reflects the purpose of the class: an interface for things in which we can draw (e.g. a View) * Accordingly rename OffscreenContext to OffscreenCanvas --- .../app/{DrawingContext.cpp => Canvas.cpp} | 57 ++-- .../app/{DrawingContext.h => Canvas.h} | 25 +- src/servers/app/Jamfile | 10 +- src/servers/app/ServerPicture.cpp | 286 +++++++++--------- src/servers/app/ServerPicture.h | 4 +- src/servers/app/View.h | 4 +- src/servers/app/drawing/AlphaMask.cpp | 16 +- src/tests/servers/app/Jamfile | 6 +- 8 files changed, 205 insertions(+), 203 deletions(-) rename src/servers/app/{DrawingContext.cpp => Canvas.cpp} (80%) rename src/servers/app/{DrawingContext.h => Canvas.h} (90%) diff --git a/src/servers/app/DrawingContext.cpp b/src/servers/app/Canvas.cpp similarity index 80% rename from src/servers/app/DrawingContext.cpp rename to src/servers/app/Canvas.cpp index 8a61f9b00a..715c6a1f05 100644 --- a/src/servers/app/DrawingContext.cpp +++ b/src/servers/app/Canvas.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2014, Haiku, Inc. + * Copyright (c) 2001-2015, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: @@ -9,10 +9,11 @@ * Stephan Aßmus * Marcus Overhagen * Adrien Destugues */ -#include "DrawingContext.h" +#include "Canvas.h" #include @@ -27,27 +28,27 @@ #include "DrawState.h" -DrawingContext::DrawingContext() +Canvas::Canvas() : fDrawState(new(std::nothrow) DrawState()) { } -DrawingContext::DrawingContext(const DrawState& state) +Canvas::Canvas(const DrawState& state) : fDrawState(new(std::nothrow) DrawState(state)) { } -DrawingContext::~DrawingContext() +Canvas::~Canvas() { } status_t -DrawingContext::InitCheck() const +Canvas::InitCheck() const { if (fDrawState == NULL) return B_NO_MEMORY; @@ -57,7 +58,7 @@ DrawingContext::InitCheck() const void -DrawingContext::PushState() +Canvas::PushState() { DrawState* newState = fDrawState->PushState(); if (newState) @@ -66,7 +67,7 @@ DrawingContext::PushState() void -DrawingContext::PopState() +Canvas::PopState() { if (fDrawState->PreviousState() == NULL) return; @@ -83,7 +84,7 @@ DrawingContext::PopState() void -DrawingContext::SetDrawingOrigin(BPoint origin) +Canvas::SetDrawingOrigin(BPoint origin) { fDrawState->SetOrigin(origin); @@ -94,7 +95,7 @@ DrawingContext::SetDrawingOrigin(BPoint origin) BPoint -DrawingContext::DrawingOrigin() const +Canvas::DrawingOrigin() const { BPoint origin(fDrawState->Origin()); float scale = Scale(); @@ -107,7 +108,7 @@ DrawingContext::DrawingOrigin() const void -DrawingContext::SetScale(float scale) +Canvas::SetScale(float scale) { fDrawState->SetScale(scale); @@ -118,31 +119,31 @@ DrawingContext::SetScale(float scale) float -DrawingContext::Scale() const +Canvas::Scale() const { return fDrawState->Scale(); } void -DrawingContext::SetUserClipping(const BRegion* region) +Canvas::SetUserClipping(const BRegion* region) { fDrawState->SetClippingRegion(region); - // rebuild clipping (for just this context) + // rebuild clipping (for just this canvas) RebuildClipping(false); } void -DrawingContext::SetAlphaMask(AlphaMask* mask) +Canvas::SetAlphaMask(AlphaMask* mask) { fDrawState->SetAlphaMask(mask); } AlphaMask* -DrawingContext::GetAlphaMask() const +Canvas::GetAlphaMask() const { return fDrawState->GetAlphaMask(); } @@ -150,7 +151,7 @@ DrawingContext::GetAlphaMask() const //! converts a point from local *drawing* to screen coordinate system void -DrawingContext::ConvertToScreenForDrawing(BPoint* point) const +Canvas::ConvertToScreenForDrawing(BPoint* point) const { fDrawState->Transform(point); // NOTE: from here on, don't use the @@ -161,7 +162,7 @@ DrawingContext::ConvertToScreenForDrawing(BPoint* point) const //! converts a rect from local *drawing* to screen coordinate system void -DrawingContext::ConvertToScreenForDrawing(BRect* rect) const +Canvas::ConvertToScreenForDrawing(BRect* rect) const { fDrawState->Transform(rect); // NOTE: from here on, don't use the @@ -172,7 +173,7 @@ DrawingContext::ConvertToScreenForDrawing(BRect* rect) const //! converts a region from local *drawing* to screen coordinate system void -DrawingContext::ConvertToScreenForDrawing(BRegion* region) const +Canvas::ConvertToScreenForDrawing(BRegion* region) const { fDrawState->Transform(region); // NOTE: from here on, don't use the @@ -183,7 +184,7 @@ DrawingContext::ConvertToScreenForDrawing(BRegion* region) const //! converts a gradient from local *drawing* to screen coordinate system void -DrawingContext::ConvertToScreenForDrawing(BGradient* gradient) const +Canvas::ConvertToScreenForDrawing(BGradient* gradient) const { switch (gradient->GetType()) { case BGradient::TYPE_LINEAR: @@ -266,7 +267,7 @@ DrawingContext::ConvertToScreenForDrawing(BGradient* gradient) const //! converts points from local *drawing* to screen coordinate system void -DrawingContext::ConvertToScreenForDrawing(BPoint* dst, const BPoint* src, int32 num) const +Canvas::ConvertToScreenForDrawing(BPoint* dst, const BPoint* src, int32 num) const { // TODO: optimize this, it should be smarter while (num--) { @@ -283,7 +284,7 @@ DrawingContext::ConvertToScreenForDrawing(BPoint* dst, const BPoint* src, int32 //! converts rects from local *drawing* to screen coordinate system void -DrawingContext::ConvertToScreenForDrawing(BRect* dst, const BRect* src, int32 num) const +Canvas::ConvertToScreenForDrawing(BRect* dst, const BRect* src, int32 num) const { // TODO: optimize this, it should be smarter while (num--) { @@ -300,7 +301,7 @@ DrawingContext::ConvertToScreenForDrawing(BRect* dst, const BRect* src, int32 nu //! converts regions from local *drawing* to screen coordinate system void -DrawingContext::ConvertToScreenForDrawing(BRegion* dst, const BRegion* src, int32 num) const +Canvas::ConvertToScreenForDrawing(BRegion* dst, const BRegion* src, int32 num) const { // TODO: optimize this, it should be smarter while (num--) { @@ -317,20 +318,20 @@ DrawingContext::ConvertToScreenForDrawing(BRegion* dst, const BRegion* src, int3 //! converts a point from screen to local coordinate system void -DrawingContext::ConvertFromScreenForDrawing(BPoint* point) const +Canvas::ConvertFromScreenForDrawing(BPoint* point) const { ConvertFromScreen(point); fDrawState->InverseTransform(point); } -// #pragma mark - OffscreenContext +// #pragma mark - OffscreenCanvas -OffscreenContext::OffscreenContext(DrawingEngine* engine, +OffscreenCanvas::OffscreenCanvas(DrawingEngine* engine, const DrawState& state) : - DrawingContext(state), + Canvas(state), fDrawingEngine(engine) { ResyncDrawState(); @@ -338,7 +339,7 @@ OffscreenContext::OffscreenContext(DrawingEngine* engine, void -OffscreenContext::ResyncDrawState() +OffscreenCanvas::ResyncDrawState() { fDrawingEngine->SetDrawState(fDrawState); } diff --git a/src/servers/app/DrawingContext.h b/src/servers/app/Canvas.h similarity index 90% rename from src/servers/app/DrawingContext.h rename to src/servers/app/Canvas.h index 621ed0a920..c8efc4c612 100644 --- a/src/servers/app/DrawingContext.h +++ b/src/servers/app/Canvas.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2014, Haiku, Inc. + * Copyright (c) 2001-2015, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: @@ -9,9 +9,10 @@ * Stephan Aßmus * Marcus Overhagen * Adrien Destugues + * Julian Harnath */ -#ifndef DRAWING_CONTEXT_H -#define DRAWING_CONTEXT_H +#ifndef CANVAS_H +#define CANVAS_H #include @@ -27,11 +28,11 @@ class IntRect; class ServerPicture; -class DrawingContext { +class Canvas { public: - DrawingContext(); - DrawingContext(const DrawState& state); - virtual ~DrawingContext(); + Canvas(); + Canvas(const DrawState& state); + virtual ~Canvas(); status_t InitCheck() const; @@ -47,10 +48,10 @@ public: void SetUserClipping(const BRegion* region); // region is expected in view coordinates - + void SetAlphaMask(AlphaMask* mask); AlphaMask* GetAlphaMask() const; - + void ConvertToScreenForDrawing(BPoint* point) const; void ConvertToScreenForDrawing(BRect* rect) const; void ConvertToScreenForDrawing(BRegion* region) const; @@ -82,9 +83,9 @@ protected: }; -class OffscreenContext: public DrawingContext { +class OffscreenCanvas : public Canvas { public: - OffscreenContext(DrawingEngine* engine, + OffscreenCanvas(DrawingEngine* engine, const DrawState& state); // Screen and View coordinates are the same for us. @@ -108,4 +109,4 @@ private: }; -#endif +#endif // CANVAS_H diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index 024088b061..aebc6c8580 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -32,10 +32,10 @@ local font_src = ; UseBuildFeatureHeaders freetype ; -Includes [ FGristFiles AppServer.cpp BitmapManager.cpp +Includes [ FGristFiles AppServer.cpp BitmapManager.cpp Canvas.cpp ClientMemoryAllocator.cpp Desktop.cpp DesktopSettings.cpp - DrawState.cpp DrawingContext.cpp DrawingEngine.cpp ServerApp.cpp - ServerBitmap.cpp ServerCursor.cpp ServerFont.cpp ServerPicture.cpp + DrawState.cpp DrawingEngine.cpp ServerApp.cpp + ServerBitmap.cpp ServerCursor.cpp ServerFont.cpp ServerPicture.cpp ServerWindow.cpp View.cpp Window.cpp WorkspacesView.cpp $(decorator_src) $(font_src) ] : [ BuildFeatureAttribute freetype : headers ] ; @@ -51,6 +51,7 @@ Server app_server : AppServer.cpp #BitfieldRegion.cpp BitmapManager.cpp + Canvas.cpp ClientMemoryAllocator.cpp CursorData.cpp CursorManager.cpp @@ -59,7 +60,6 @@ Server app_server : DesktopListener.cpp DesktopSettings.cpp DirectWindowInfo.cpp - DrawingContext.cpp DrawState.cpp EventDispatcher.cpp EventStream.cpp @@ -97,7 +97,7 @@ Server app_server : # libraries : libtranslation.so libbe.so libbnetapi.so - libaslocal.a $(BROKEN_64)libasremote.a $(BROKEN_64)libashtml5.a + libaslocal.a $(BROKEN_64)libasremote.a $(BROKEN_64)libashtml5.a libasdrawing.a libpainter.a libagg.a [ BuildFeatureAttribute freetype : library ] libstackandtile.a liblinprog.a libtextencoding.so libshared.a diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index 1c115dcf6c..6f09cb0d70 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -44,7 +44,7 @@ using std::stack; class ShapePainter : public BShapeIterator { public: - ShapePainter(DrawingContext* context); + ShapePainter(Canvas* canvas); virtual ~ShapePainter(); status_t Iterate(const BShape* shape); @@ -59,15 +59,15 @@ public: void Draw(BRect frame, bool filled); private: - DrawingContext* fContext; + Canvas* fCanvas; stack fOpStack; stack fPtStack; }; -ShapePainter::ShapePainter(DrawingContext* context) +ShapePainter::ShapePainter(Canvas* canvas) : - fContext(context) + fCanvas(canvas) { } @@ -203,10 +203,10 @@ ShapePainter::Draw(BRect frame, bool filled) fPtStack.pop(); } - BPoint offset(fContext->CurrentState()->PenLocation()); - fContext->ConvertToScreenForDrawing(&offset); - fContext->GetDrawingEngine()->DrawShape(frame, opCount, opList, - ptCount, ptList, filled, offset, fContext->Scale()); + BPoint offset(fCanvas->CurrentState()->PenLocation()); + fCanvas->ConvertToScreenForDrawing(&offset); + fCanvas->GetDrawingEngine()->DrawShape(frame, opCount, opList, + ptCount, ptList, filled, offset, fCanvas->Scale()); delete[] opList; delete[] ptList; @@ -253,23 +253,23 @@ nop() static void -move_pen_by(DrawingContext* context, BPoint delta) +move_pen_by(Canvas* canvas, BPoint delta) { - context->CurrentState()->SetPenLocation( - context->CurrentState()->PenLocation() + delta); + canvas->CurrentState()->SetPenLocation( + canvas->CurrentState()->PenLocation() + delta); } static void -stroke_line(DrawingContext* context, BPoint start, BPoint end) +stroke_line(Canvas* canvas, BPoint start, BPoint end) { BPoint penPos = end; - context->ConvertToScreenForDrawing(&start); - context->ConvertToScreenForDrawing(&end); - context->GetDrawingEngine()->StrokeLine(start, end); + canvas->ConvertToScreenForDrawing(&start); + canvas->ConvertToScreenForDrawing(&end); + canvas->GetDrawingEngine()->StrokeLine(start, end); - context->CurrentState()->SetPenLocation(penPos); + canvas->CurrentState()->SetPenLocation(penPos); // the DrawingEngine/Painter does not need to be updated, since this // effects only the view->screen coord conversion, which is handled // by the view only @@ -277,109 +277,109 @@ stroke_line(DrawingContext* context, BPoint start, BPoint end) static void -stroke_rect(DrawingContext* context, BRect rect) +stroke_rect(Canvas* canvas, BRect rect) { - context->ConvertToScreenForDrawing(&rect); - context->GetDrawingEngine()->StrokeRect(rect); + canvas->ConvertToScreenForDrawing(&rect); + canvas->GetDrawingEngine()->StrokeRect(rect); } static void -fill_rect(DrawingContext* context, BRect rect) +fill_rect(Canvas* canvas, BRect rect) { - context->ConvertToScreenForDrawing(&rect); - context->GetDrawingEngine()->FillRect(rect); + canvas->ConvertToScreenForDrawing(&rect); + canvas->GetDrawingEngine()->FillRect(rect); } static void -draw_round_rect(DrawingContext* context, BRect rect, BPoint radii, bool fill) +draw_round_rect(Canvas* canvas, BRect rect, BPoint radii, bool fill) { - context->ConvertToScreenForDrawing(&rect); - float scale = context->CurrentState()->CombinedScale(); - context->GetDrawingEngine()->DrawRoundRect(rect, radii.x * scale, + canvas->ConvertToScreenForDrawing(&rect); + float scale = canvas->CurrentState()->CombinedScale(); + canvas->GetDrawingEngine()->DrawRoundRect(rect, radii.x * scale, radii.y * scale, fill); } static void -stroke_round_rect(DrawingContext* context, BRect rect, BPoint radii) +stroke_round_rect(Canvas* canvas, BRect rect, BPoint radii) { - draw_round_rect(context, rect, radii, false); + draw_round_rect(canvas, rect, radii, false); } static void -fill_round_rect(DrawingContext* context, BRect rect, BPoint radii) +fill_round_rect(Canvas* canvas, BRect rect, BPoint radii) { - draw_round_rect(context, rect, radii, true); + draw_round_rect(canvas, rect, radii, true); } static void -stroke_bezier(DrawingContext* context, const BPoint* viewPoints) +stroke_bezier(Canvas* canvas, const BPoint* viewPoints) { BPoint points[4]; - context->ConvertToScreenForDrawing(points, viewPoints, 4); + canvas->ConvertToScreenForDrawing(points, viewPoints, 4); - context->GetDrawingEngine()->DrawBezier(points, false); + canvas->GetDrawingEngine()->DrawBezier(points, false); } static void -fill_bezier(DrawingContext* context, const BPoint* viewPoints) +fill_bezier(Canvas* canvas, const BPoint* viewPoints) { BPoint points[4]; - context->ConvertToScreenForDrawing(points, viewPoints, 4); + canvas->ConvertToScreenForDrawing(points, viewPoints, 4); - context->GetDrawingEngine()->DrawBezier(points, true); + canvas->GetDrawingEngine()->DrawBezier(points, true); } static void -stroke_arc(DrawingContext* context, BPoint center, BPoint radii, +stroke_arc(Canvas* canvas, BPoint center, BPoint radii, float startTheta, float arcTheta) { BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x - 1, center.y + radii.y - 1); - context->ConvertToScreenForDrawing(&rect); - context->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, false); + canvas->ConvertToScreenForDrawing(&rect); + canvas->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, false); } static void -fill_arc(DrawingContext* context, BPoint center, BPoint radii, +fill_arc(Canvas* canvas, BPoint center, BPoint radii, float startTheta, float arcTheta) { BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x - 1, center.y + radii.y - 1); - context->ConvertToScreenForDrawing(&rect); - context->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, true); + canvas->ConvertToScreenForDrawing(&rect); + canvas->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, true); } static void -stroke_ellipse(DrawingContext* context, BPoint center, BPoint radii) +stroke_ellipse(Canvas* canvas, BPoint center, BPoint radii) { BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x - 1, center.y + radii.y - 1); - context->ConvertToScreenForDrawing(&rect); - context->GetDrawingEngine()->DrawEllipse(rect, false); + canvas->ConvertToScreenForDrawing(&rect); + canvas->GetDrawingEngine()->DrawEllipse(rect, false); } static void -fill_ellipse(DrawingContext* context, BPoint center, BPoint radii) +fill_ellipse(Canvas* canvas, BPoint center, BPoint radii) { BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x - 1, center.y + radii.y - 1); - context->ConvertToScreenForDrawing(&rect); - context->GetDrawingEngine()->DrawEllipse(rect, true); + canvas->ConvertToScreenForDrawing(&rect); + canvas->GetDrawingEngine()->DrawEllipse(rect, true); } static void -stroke_polygon(DrawingContext* context, int32 numPoints, +stroke_polygon(Canvas* canvas, int32 numPoints, const BPoint* viewPoints, bool isClosed) { if (numPoints <= 0) @@ -391,12 +391,12 @@ stroke_polygon(DrawingContext* context, int32 numPoints, char data[200 * sizeof(BPoint)]; BPoint* points = (BPoint*)data; - context->ConvertToScreenForDrawing(points, viewPoints, numPoints); + canvas->ConvertToScreenForDrawing(points, viewPoints, numPoints); BRect polyFrame; get_polygon_frame(points, numPoints, &polyFrame); - context->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, + canvas->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, false, isClosed && numPoints > 2); } else { // avoid constructor/destructor calls by @@ -405,12 +405,12 @@ stroke_polygon(DrawingContext* context, int32 numPoints, if (points == NULL) return; - context->ConvertToScreenForDrawing(points, viewPoints, numPoints); + canvas->ConvertToScreenForDrawing(points, viewPoints, numPoints); BRect polyFrame; get_polygon_frame(points, numPoints, &polyFrame); - context->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, + canvas->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, false, isClosed && numPoints > 2); free(points); } @@ -418,7 +418,7 @@ stroke_polygon(DrawingContext* context, int32 numPoints, static void -fill_polygon(DrawingContext* context, int32 numPoints, +fill_polygon(Canvas* canvas, int32 numPoints, const BPoint* viewPoints) { if (numPoints <= 0) @@ -430,12 +430,12 @@ fill_polygon(DrawingContext* context, int32 numPoints, char data[200 * sizeof(BPoint)]; BPoint* points = (BPoint*)data; - context->ConvertToScreenForDrawing(points, viewPoints, numPoints); + canvas->ConvertToScreenForDrawing(points, viewPoints, numPoints); BRect polyFrame; get_polygon_frame(points, numPoints, &polyFrame); - context->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, + canvas->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, true, true); } else { // avoid constructor/destructor calls by @@ -444,12 +444,12 @@ fill_polygon(DrawingContext* context, int32 numPoints, if (points == NULL) return; - context->ConvertToScreenForDrawing(points, viewPoints, numPoints); + canvas->ConvertToScreenForDrawing(points, viewPoints, numPoints); BRect polyFrame; get_polygon_frame(points, numPoints, &polyFrame); - context->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, + canvas->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, true, true); free(points); } @@ -457,9 +457,9 @@ fill_polygon(DrawingContext* context, int32 numPoints, static void -stroke_shape(DrawingContext* context, const BShape* shape) +stroke_shape(Canvas* canvas, const BShape* shape) { - ShapePainter drawShape(context); + ShapePainter drawShape(canvas); drawShape.Iterate(shape); drawShape.Draw(shape->Bounds(), false); @@ -467,9 +467,9 @@ stroke_shape(DrawingContext* context, const BShape* shape) static void -fill_shape(DrawingContext* context, const BShape* shape) +fill_shape(Canvas* canvas, const BShape* shape) { - ShapePainter drawShape(context); + ShapePainter drawShape(canvas); drawShape.Iterate(shape); drawShape.Draw(shape->Bounds(), true); @@ -477,21 +477,21 @@ fill_shape(DrawingContext* context, const BShape* shape) static void -draw_string(DrawingContext* context, const char* string, float deltaSpace, +draw_string(Canvas* canvas, const char* string, float deltaSpace, float deltaNonSpace) { // NOTE: the picture data was recorded with a "set pen location" // command inserted before the "draw string" command, so we can // use PenLocation() - BPoint location = context->CurrentState()->PenLocation(); + BPoint location = canvas->CurrentState()->PenLocation(); escapement_delta delta = { deltaSpace, deltaNonSpace }; - context->ConvertToScreenForDrawing(&location); - location = context->GetDrawingEngine()->DrawString(string, strlen(string), + canvas->ConvertToScreenForDrawing(&location); + location = canvas->GetDrawingEngine()->DrawString(string, strlen(string), location, &delta); - context->ConvertFromScreenForDrawing(&location); - context->CurrentState()->SetPenLocation(location); + canvas->ConvertFromScreenForDrawing(&location); + canvas->CurrentState()->SetPenLocation(location); // the DrawingEngine/Painter does not need to be updated, since this // effects only the view->screen coord conversion, which is handled // by the view only @@ -499,7 +499,7 @@ draw_string(DrawingContext* context, const char* string, float deltaSpace, static void -draw_pixels(DrawingContext* context, BRect src, BRect dest, int32 width, +draw_pixels(Canvas* canvas, BRect src, BRect dest, int32 width, int32 height, int32 bytesPerRow, int32 pixelFormat, int32 options, const void* data) { @@ -511,31 +511,31 @@ draw_pixels(DrawingContext* context, BRect src, BRect dest, int32 width, memcpy(bitmap.Bits(), data, height * bytesPerRow); - context->ConvertToScreenForDrawing(&dest); - context->GetDrawingEngine()->DrawBitmap(&bitmap, src, dest, options); + canvas->ConvertToScreenForDrawing(&dest); + canvas->GetDrawingEngine()->DrawBitmap(&bitmap, src, dest, options); } static void -draw_picture(DrawingContext* context, BPoint where, int32 token) +draw_picture(Canvas* canvas, BPoint where, int32 token) { - ServerPicture* picture = context->GetPicture(token); + ServerPicture* picture = canvas->GetPicture(token); if (picture != NULL) { - context->PushState(); - context->SetDrawingOrigin(where); + canvas->PushState(); + canvas->SetDrawingOrigin(where); - context->PushState(); - picture->Play(context); - context->PopState(); + canvas->PushState(); + picture->Play(canvas); + canvas->PopState(); - context->PopState(); + canvas->PopState(); picture->ReleaseReference(); } } static void -set_clipping_rects(DrawingContext* context, const BRect* rects, +set_clipping_rects(Canvas* canvas, const BRect* rects, uint32 numRects) { // TODO: This might be too slow, we should copy the rects @@ -543,13 +543,13 @@ set_clipping_rects(DrawingContext* context, const BRect* rects, BRegion region; for (uint32 c = 0; c < numRects; c++) region.Include(rects[c]); - context->SetUserClipping(®ion); - context->UpdateCurrentDrawingRegion(); + canvas->SetUserClipping(®ion); + canvas->UpdateCurrentDrawingRegion(); } static void -clip_to_picture(DrawingContext* context, BPicture* picture, BPoint pt, +clip_to_picture(Canvas* canvas, BPicture* picture, BPoint pt, bool clipToInverse) { printf("ClipToPicture(picture, BPoint(%.2f, %.2f), %s)\n", @@ -558,20 +558,20 @@ clip_to_picture(DrawingContext* context, BPicture* picture, BPoint pt, static void -push_state(DrawingContext* context) +push_state(Canvas* canvas) { - context->PushState(); + canvas->PushState(); } static void -pop_state(DrawingContext* context) +pop_state(Canvas* canvas) { - context->PopState(); + canvas->PopState(); BPoint p(0, 0); - context->ConvertToScreenForDrawing(&p); - context->GetDrawingEngine()->SetDrawState(context->CurrentState(), + canvas->ConvertToScreenForDrawing(&p); + canvas->GetDrawingEngine()->SetDrawState(canvas->CurrentState(), (int32)p.x, (int32)p.y); } @@ -579,42 +579,42 @@ pop_state(DrawingContext* context) // TODO: Be smart and actually take advantage of these methods: // only apply state changes when they are called static void -enter_state_change(DrawingContext* context) +enter_state_change(Canvas* canvas) { } static void -exit_state_change(DrawingContext* context) +exit_state_change(Canvas* canvas) { - context->ResyncDrawState(); + canvas->ResyncDrawState(); } static void -enter_font_state(DrawingContext* context) +enter_font_state(Canvas* canvas) { } static void -exit_font_state(DrawingContext* context) +exit_font_state(Canvas* canvas) { - context->GetDrawingEngine()->SetFont(context->CurrentState()->Font()); + canvas->GetDrawingEngine()->SetFont(canvas->CurrentState()->Font()); } static void -set_origin(DrawingContext* context, BPoint pt) +set_origin(Canvas* canvas, BPoint pt) { - context->CurrentState()->SetOrigin(pt); + canvas->CurrentState()->SetOrigin(pt); } static void -set_pen_location(DrawingContext* context, BPoint pt) +set_pen_location(Canvas* canvas, BPoint pt) { - context->CurrentState()->SetPenLocation(pt); + canvas->CurrentState()->SetPenLocation(pt); // the DrawingEngine/Painter does not need to be updated, since this // effects only the view->screen coord conversion, which is handled // by the view only @@ -622,65 +622,65 @@ set_pen_location(DrawingContext* context, BPoint pt) static void -set_drawing_mode(DrawingContext* context, drawing_mode mode) +set_drawing_mode(Canvas* canvas, drawing_mode mode) { - context->CurrentState()->SetDrawingMode(mode); - context->GetDrawingEngine()->SetDrawingMode(mode); + canvas->CurrentState()->SetDrawingMode(mode); + canvas->GetDrawingEngine()->SetDrawingMode(mode); } static void -set_line_mode(DrawingContext* context, cap_mode capMode, join_mode joinMode, +set_line_mode(Canvas* canvas, cap_mode capMode, join_mode joinMode, float miterLimit) { - DrawState* state = context->CurrentState(); + DrawState* state = canvas->CurrentState(); state->SetLineCapMode(capMode); state->SetLineJoinMode(joinMode); state->SetMiterLimit(miterLimit); - context->GetDrawingEngine()->SetStrokeMode(capMode, joinMode, miterLimit); + canvas->GetDrawingEngine()->SetStrokeMode(capMode, joinMode, miterLimit); } static void -set_pen_size(DrawingContext* context, float size) +set_pen_size(Canvas* canvas, float size) { - context->CurrentState()->SetPenSize(size); - context->GetDrawingEngine()->SetPenSize( - context->CurrentState()->PenSize()); + canvas->CurrentState()->SetPenSize(size); + canvas->GetDrawingEngine()->SetPenSize( + canvas->CurrentState()->PenSize()); // DrawState::PenSize() returns the scaled pen size, so we // need to use that value to set the drawing engine pen size. } static void -set_fore_color(DrawingContext* context, rgb_color color) +set_fore_color(Canvas* canvas, rgb_color color) { - context->CurrentState()->SetHighColor(color); - context->GetDrawingEngine()->SetHighColor(color); + canvas->CurrentState()->SetHighColor(color); + canvas->GetDrawingEngine()->SetHighColor(color); } static void -set_back_color(DrawingContext* context, rgb_color color) +set_back_color(Canvas* canvas, rgb_color color) { - context->CurrentState()->SetLowColor(color); - context->GetDrawingEngine()->SetLowColor(color); + canvas->CurrentState()->SetLowColor(color); + canvas->GetDrawingEngine()->SetLowColor(color); } static void -set_stipple_pattern(DrawingContext* context, pattern p) +set_stipple_pattern(Canvas* canvas, pattern p) { - context->CurrentState()->SetPattern(Pattern(p)); - context->GetDrawingEngine()->SetPattern(p); + canvas->CurrentState()->SetPattern(Pattern(p)); + canvas->GetDrawingEngine()->SetPattern(p); } static void -set_scale(DrawingContext* context, float scale) +set_scale(Canvas* canvas, float scale) { - context->CurrentState()->SetScale(scale); - context->ResyncDrawState(); + canvas->CurrentState()->SetScale(scale); + canvas->ResyncDrawState(); // Update the drawing engine draw state, since some stuff // (for example the pen size) needs to be recalculated. @@ -688,94 +688,94 @@ set_scale(DrawingContext* context, float scale) static void -set_font_family(DrawingContext* context, const char* family) +set_font_family(Canvas* canvas, const char* family) { FontStyle* fontStyle = gFontManager->GetStyleByIndex(family, 0); ServerFont font; font.SetStyle(fontStyle); - context->CurrentState()->SetFont(font, B_FONT_FAMILY_AND_STYLE); + canvas->CurrentState()->SetFont(font, B_FONT_FAMILY_AND_STYLE); } static void -set_font_style(DrawingContext* context, const char* style) +set_font_style(Canvas* canvas, const char* style) { - ServerFont font(context->CurrentState()->Font()); + ServerFont font(canvas->CurrentState()->Font()); FontStyle* fontStyle = gFontManager->GetStyle(font.Family(), style); font.SetStyle(fontStyle); - context->CurrentState()->SetFont(font, B_FONT_FAMILY_AND_STYLE); + canvas->CurrentState()->SetFont(font, B_FONT_FAMILY_AND_STYLE); } static void -set_font_spacing(DrawingContext* context, int32 spacing) +set_font_spacing(Canvas* canvas, int32 spacing) { ServerFont font; font.SetSpacing(spacing); - context->CurrentState()->SetFont(font, B_FONT_SPACING); + canvas->CurrentState()->SetFont(font, B_FONT_SPACING); } static void -set_font_size(DrawingContext* context, float size) +set_font_size(Canvas* canvas, float size) { ServerFont font; font.SetSize(size); - context->CurrentState()->SetFont(font, B_FONT_SIZE); + canvas->CurrentState()->SetFont(font, B_FONT_SIZE); } static void -set_font_rotate(DrawingContext* context, float rotation) +set_font_rotate(Canvas* canvas, float rotation) { ServerFont font; font.SetRotation(rotation); - context->CurrentState()->SetFont(font, B_FONT_ROTATION); + canvas->CurrentState()->SetFont(font, B_FONT_ROTATION); } static void -set_font_encoding(DrawingContext* context, int32 encoding) +set_font_encoding(Canvas* canvas, int32 encoding) { ServerFont font; font.SetEncoding(encoding); - context->CurrentState()->SetFont(font, B_FONT_ENCODING); + canvas->CurrentState()->SetFont(font, B_FONT_ENCODING); } static void -set_font_flags(DrawingContext* context, int32 flags) +set_font_flags(Canvas* canvas, int32 flags) { ServerFont font; font.SetFlags(flags); - context->CurrentState()->SetFont(font, B_FONT_FLAGS); + canvas->CurrentState()->SetFont(font, B_FONT_FLAGS); } static void -set_font_shear(DrawingContext* context, float shear) +set_font_shear(Canvas* canvas, float shear) { ServerFont font; font.SetShear(shear); - context->CurrentState()->SetFont(font, B_FONT_SHEAR); + canvas->CurrentState()->SetFont(font, B_FONT_SHEAR); } static void -set_font_face(DrawingContext* context, int32 face) +set_font_face(Canvas* canvas, int32 face) { ServerFont font; font.SetFace(face); - context->CurrentState()->SetFont(font, B_FONT_FACE); + canvas->CurrentState()->SetFont(font, B_FONT_FACE); } static void -set_blending_mode(DrawingContext* context, int16 alphaSrcMode, int16 alphaFncMode) +set_blending_mode(Canvas* canvas, int16 alphaSrcMode, int16 alphaFncMode) { - context->CurrentState()->SetBlendingMode((source_alpha)alphaSrcMode, + canvas->CurrentState()->SetBlendingMode((source_alpha)alphaSrcMode, (alpha_function)alphaFncMode); } @@ -1068,7 +1068,7 @@ ServerPicture::SetFontFromLink(BPrivate::LinkReceiver& link) void -ServerPicture::Play(DrawingContext* target) +ServerPicture::Play(Canvas* target) { // TODO: for now: then change PicturePlayer // to accept a BPositionIO object diff --git a/src/servers/app/ServerPicture.h b/src/servers/app/ServerPicture.h index 6f27d38c2a..f559b45b59 100644 --- a/src/servers/app/ServerPicture.h +++ b/src/servers/app/ServerPicture.h @@ -18,7 +18,7 @@ class BFile; -class DrawingContext; +class Canvas; class ServerApp; class View; @@ -49,7 +49,7 @@ public: void SyncState(View* view); void SetFontFromLink(BPrivate::LinkReceiver& link); - void Play(DrawingContext* target); + void Play(Canvas* target); void PushPicture(ServerPicture* picture); ServerPicture* PopPicture(); diff --git a/src/servers/app/View.h b/src/servers/app/View.h index b2291afe47..7bdc31a78d 100644 --- a/src/servers/app/View.h +++ b/src/servers/app/View.h @@ -14,7 +14,7 @@ #define VIEW_H -#include "DrawingContext.h" +#include "Canvas.h" #include "IntRect.h" #include @@ -37,7 +37,7 @@ class ServerCursor; class ServerPicture; class BGradient; -class View: public DrawingContext { +class View: public Canvas { public: View(IntRect frame, IntPoint scrollingOffset, const char* name, int32 token, diff --git a/src/servers/app/drawing/AlphaMask.cpp b/src/servers/app/drawing/AlphaMask.cpp index 2a595fca86..2b744cd548 100644 --- a/src/servers/app/drawing/AlphaMask.cpp +++ b/src/servers/app/drawing/AlphaMask.cpp @@ -12,7 +12,7 @@ #include "BitmapHWInterface.h" #include "BitmapManager.h" -#include "DrawingContext.h" +#include "Canvas.h" #include "DrawingEngine.h" #include "ServerBitmap.h" #include "ServerPicture.h" @@ -56,7 +56,7 @@ AlphaMask::Update(BRect bounds, BPoint offset) { fViewBounds = bounds; fViewOffset = offset; - + if (fPreviousMask != NULL) fPreviousMask->Update(bounds, offset); } @@ -98,7 +98,7 @@ AlphaMask::Generate() delete[] fCachedBitmap; fCachedBitmap = new(std::nothrow) uint8[width * height]; } - + // If rendering the picture fails, we will draw without any clipping. ServerBitmap* bitmap = _RenderPicture(); if (bitmap == NULL || fCachedBitmap == NULL) { @@ -140,7 +140,7 @@ AlphaMask::Generate() transferBitmap = false; } } - + if (transferBitmap) { for (uint32 y = 0; y < height; y++) { for (uint32 x = 0; x < width; x++) { @@ -194,8 +194,8 @@ AlphaMask::_RenderPicture() const return NULL; } - OffscreenContext context(engine, fDrawState); - context.PushState(); + OffscreenCanvas canvas(engine, fDrawState); + canvas.PushState(); if (engine->LockParallelAccess()) { // FIXME ConstrainClippingRegion docs says passing NULL disables @@ -203,11 +203,11 @@ AlphaMask::_RenderPicture() const BRegion clipping; clipping.Include(fViewBounds); engine->ConstrainClippingRegion(&clipping); - fPicture->Play(&context); + fPicture->Play(&canvas); engine->UnlockParallelAccess(); } - context.PopState(); + canvas.PopState(); delete engine; return bitmap; diff --git a/src/tests/servers/app/Jamfile b/src/tests/servers/app/Jamfile index 376d56291d..0a5daf047e 100644 --- a/src/tests/servers/app/Jamfile +++ b/src/tests/servers/app/Jamfile @@ -152,8 +152,8 @@ SharedLibrary libtestappserver.so : AlphaMask.cpp BitmapHWInterface.cpp + Canvas.cpp DesktopSettings.cpp - DrawingContext.cpp OffscreenServerWindow.cpp OffscreenWindow.cpp RegionPool.cpp @@ -173,9 +173,9 @@ SharedLibrary libtestappserver.so : [ BuildFeatureAttribute freetype : library ] ; -Includes [ FGristFiles AppServer.cpp BitmapManager.cpp +Includes [ FGristFiles AppServer.cpp BitmapManager.cpp Canvas.cpp ClientMemoryAllocator.cpp Desktop.cpp DesktopSettings.cpp - DrawState.cpp DrawingContext.cpp DrawingEngine.cpp ServerApp.cpp + DrawState.cpp DrawingEngine.cpp ServerApp.cpp ServerBitmap.cpp ServerCursor.cpp ServerFont.cpp ServerPicture.cpp ServerWindow.cpp View.cpp Window.cpp WorkspacesView.cpp $(decorator_src) $(font_src) ] From 6f2a446e2eb8362b92dd6c12c8ed7274d110a9b1 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Mon, 6 Apr 2015 14:43:24 +0200 Subject: [PATCH 002/370] app_server: extract coordinate conversion class * Move coordinate conversion into a new class SimpleTransform. It supports scaling and translation which is sufficient for conversion between screen, local and pen (drawing) coordinates. * Because all the overloaded methods for converting BPoint/BRect/BRegion/etc are now within the single SimpleTransform class, the interfaces of Canvas, View, DrawState, etc. are slimmed down. These classes have too many responsibilities, so some will be factored out into separate classes, this being the first. --- src/servers/app/Canvas.cpp | 205 +++++------------------- src/servers/app/Canvas.h | 46 ++---- src/servers/app/DrawState.cpp | 90 ++--------- src/servers/app/DrawState.h | 14 +- src/servers/app/ServerPicture.cpp | 47 +++--- src/servers/app/ServerWindow.cpp | 130 +++++++++------ src/servers/app/SimpleTransform.h | 243 +++++++++++++++++++++++++++++ src/servers/app/View.cpp | 230 ++++----------------------- src/servers/app/View.h | 31 +--- src/servers/app/Window.cpp | 2 +- src/servers/app/WorkspacesView.cpp | 6 +- 11 files changed, 462 insertions(+), 582 deletions(-) create mode 100644 src/servers/app/SimpleTransform.h diff --git a/src/servers/app/Canvas.cpp b/src/servers/app/Canvas.cpp index 715c6a1f05..4fd87a0322 100644 --- a/src/servers/app/Canvas.cpp +++ b/src/servers/app/Canvas.cpp @@ -17,17 +17,22 @@ #include -#include -#include -#include -#include -#include #include #include "DrawingEngine.h" #include "DrawState.h" +#if __GNUC__ >= 3 +# define GCC_2_NRV(x) + // GCC >= 3.1 doesn't need it anymore +#else +# define GCC_2_NRV(x) return x; + // GCC 2 named return value syntax + // see http://gcc.gnu.org/onlinedocs/gcc-2.95.2/gcc_5.html#SEC106 +#endif + + Canvas::Canvas() : fDrawState(new(std::nothrow) DrawState()) @@ -149,179 +154,49 @@ Canvas::GetAlphaMask() const } -//! converts a point from local *drawing* to screen coordinate system -void -Canvas::ConvertToScreenForDrawing(BPoint* point) const +SimpleTransform +Canvas::LocalToScreenTransform() const GCC_2_NRV(transform) { - fDrawState->Transform(point); - // NOTE: from here on, don't use the - // "*ForDrawing()" versions of the parent! - ConvertToScreen(point); +#if __GNUC__ >= 3 + SimpleTransform transform; +#endif + _LocalToScreenTransform(transform); + return transform; } -//! converts a rect from local *drawing* to screen coordinate system -void -Canvas::ConvertToScreenForDrawing(BRect* rect) const +SimpleTransform +Canvas::ScreenToLocalTransform() const GCC_2_NRV(transform) { - fDrawState->Transform(rect); - // NOTE: from here on, don't use the - // "*ForDrawing()" versions of the parent! - ConvertToScreen(rect); +#if __GNUC__ >= 3 + SimpleTransform transform; +#endif + _ScreenToLocalTransform(transform); + return transform; } -//! converts a region from local *drawing* to screen coordinate system -void -Canvas::ConvertToScreenForDrawing(BRegion* region) const +SimpleTransform +Canvas::PenToScreenTransform() const GCC_2_NRV(transform) { - fDrawState->Transform(region); - // NOTE: from here on, don't use the - // "*ForDrawing()" versions of the parent! - ConvertToScreen(region); +#if __GNUC__ >= 3 + SimpleTransform transform; +#endif + fDrawState->Transform(transform); + _LocalToScreenTransform(transform); + return transform; } -//! converts a gradient from local *drawing* to screen coordinate system -void -Canvas::ConvertToScreenForDrawing(BGradient* gradient) const +SimpleTransform +Canvas::ScreenToPenTransform() const GCC_2_NRV(transform) { - switch (gradient->GetType()) { - case BGradient::TYPE_LINEAR: - { - BGradientLinear* linear = (BGradientLinear*) gradient; - BPoint start = linear->Start(); - BPoint end = linear->End(); - fDrawState->Transform(&start); - ConvertToScreen(&start); - fDrawState->Transform(&end); - ConvertToScreen(&end); - linear->SetStart(start); - linear->SetEnd(end); - break; - } - case BGradient::TYPE_RADIAL: - { - BGradientRadial* radial = (BGradientRadial*) gradient; - BPoint center = radial->Center(); - fDrawState->Transform(¢er); - ConvertToScreen(¢er); - radial->SetCenter(center); - break; - } - case BGradient::TYPE_RADIAL_FOCUS: - { - BGradientRadialFocus* radialFocus = (BGradientRadialFocus*) gradient; - BPoint center = radialFocus->Center(); - BPoint focal = radialFocus->Focal(); - fDrawState->Transform(¢er); - ConvertToScreen(¢er); - fDrawState->Transform(&focal); - ConvertToScreen(&focal); - radialFocus->SetCenter(center); - radialFocus->SetFocal(focal); - break; - } - case BGradient::TYPE_DIAMOND: - { - BGradientDiamond* diamond = (BGradientDiamond*) gradient; - BPoint center = diamond->Center(); - fDrawState->Transform(¢er); - ConvertToScreen(¢er); - diamond->SetCenter(center); - break; - } - case BGradient::TYPE_CONIC: - { - BGradientConic* conic = (BGradientConic*) gradient; - BPoint center = conic->Center(); - fDrawState->Transform(¢er); - ConvertToScreen(¢er); - conic->SetCenter(center); - break; - } - case BGradient::TYPE_NONE: - { - break; - } - } - - // Make sure the gradient is fully padded so that out of bounds access - // get the correct colors - gradient->SortColorStopsByOffset(); - - BGradient::ColorStop* end = gradient->ColorStopAtFast( - gradient->CountColorStops() - 1); - - if (end->offset != 255) - gradient->AddColor(end->color, 255); - - BGradient::ColorStop* start = gradient->ColorStopAtFast(0); - - if (start->offset != 0) - gradient->AddColor(start->color, 0); - - gradient->SortColorStopsByOffset(); -} - - -//! converts points from local *drawing* to screen coordinate system -void -Canvas::ConvertToScreenForDrawing(BPoint* dst, const BPoint* src, int32 num) const -{ - // TODO: optimize this, it should be smarter - while (num--) { - *dst = *src; - fDrawState->Transform(dst); - // NOTE: from here on, don't use the - // "*ForDrawing()" versions of the parent! - ConvertToScreen(dst); - src++; - dst++; - } -} - - -//! converts rects from local *drawing* to screen coordinate system -void -Canvas::ConvertToScreenForDrawing(BRect* dst, const BRect* src, int32 num) const -{ - // TODO: optimize this, it should be smarter - while (num--) { - *dst = *src; - fDrawState->Transform(dst); - // NOTE: from here on, don't use the - // "*ForDrawing()" versions of the parent! - ConvertToScreen(dst); - src++; - dst++; - } -} - - -//! converts regions from local *drawing* to screen coordinate system -void -Canvas::ConvertToScreenForDrawing(BRegion* dst, const BRegion* src, int32 num) const -{ - // TODO: optimize this, it should be smarter - while (num--) { - *dst = *src; - fDrawState->Transform(dst); - // NOTE: from here on, don't use the - // "*ForDrawing()" versions of the parent! - ConvertToScreen(dst); - src++; - dst++; - } -} - - -//! converts a point from screen to local coordinate system -void -Canvas::ConvertFromScreenForDrawing(BPoint* point) const -{ - ConvertFromScreen(point); - fDrawState->InverseTransform(point); +#if __GNUC__ >= 3 + SimpleTransform transform; +#endif + _ScreenToLocalTransform(transform); + fDrawState->InverseTransform(transform); + return transform; } diff --git a/src/servers/app/Canvas.h b/src/servers/app/Canvas.h index c8efc4c612..acb52d09e5 100644 --- a/src/servers/app/Canvas.h +++ b/src/servers/app/Canvas.h @@ -17,6 +17,8 @@ #include +#include "SimpleTransform.h" + class AlphaMask; class BGradient; @@ -52,25 +54,10 @@ public: void SetAlphaMask(AlphaMask* mask); AlphaMask* GetAlphaMask() const; - void ConvertToScreenForDrawing(BPoint* point) const; - void ConvertToScreenForDrawing(BRect* rect) const; - void ConvertToScreenForDrawing(BRegion* region) const; - void ConvertToScreenForDrawing(BGradient* gradient) const; - - void ConvertToScreenForDrawing(BPoint* dst, const BPoint* src, int32 num) const; - void ConvertToScreenForDrawing(BRect* dst, const BRect* src, int32 num) const; - void ConvertToScreenForDrawing(BRegion* dst, const BRegion* src, int32 num) const; - - void ConvertFromScreenForDrawing(BPoint* point) const; - // used when updating the pen position - - virtual void ConvertToScreen(BPoint* point) const = 0; - virtual void ConvertToScreen(IntPoint* point) const = 0; - virtual void ConvertToScreen(BRect* rect) const = 0; - virtual void ConvertToScreen(IntRect* rect) const = 0; - virtual void ConvertToScreen(BRegion* region) const = 0; - - virtual void ConvertFromScreen(BPoint* point) const = 0; + SimpleTransform LocalToScreenTransform() const; + SimpleTransform ScreenToLocalTransform() const; + SimpleTransform PenToScreenTransform() const; + SimpleTransform ScreenToPenTransform() const; virtual DrawingEngine* GetDrawingEngine() const = 0; virtual ServerPicture* GetPicture(int32 token) const = 0; @@ -78,6 +65,12 @@ public: virtual void ResyncDrawState() {}; virtual void UpdateCurrentDrawingRegion() {}; +protected: + virtual void _LocalToScreenTransform( + SimpleTransform& transform) const = 0; + virtual void _ScreenToLocalTransform( + SimpleTransform& transform) const = 0; + protected: DrawState* fDrawState; }; @@ -88,22 +81,17 @@ public: OffscreenCanvas(DrawingEngine* engine, const DrawState& state); - // Screen and View coordinates are the same for us. - // DrawState already takes care of World<>View - // conversions. - virtual void ConvertToScreen(BPoint*) const {} - virtual void ConvertToScreen(IntPoint*) const {} - virtual void ConvertToScreen(BRect*) const {} - virtual void ConvertToScreen(IntRect*) const {} - virtual void ConvertToScreen(BRegion*) const {} - virtual void ConvertFromScreen(BPoint*) const {} - virtual DrawingEngine* GetDrawingEngine() const { return fDrawingEngine; } virtual void RebuildClipping(bool deep) { /* TODO */ } virtual void ResyncDrawState(); virtual ServerPicture* GetPicture(int32 token) const { /* TODO */ return NULL; } + +protected: + virtual void _LocalToScreenTransform(SimpleTransform&) const {} + virtual void _ScreenToLocalTransform(SimpleTransform&) const {} + private: DrawingEngine* fDrawingEngine; }; diff --git a/src/servers/app/DrawState.cpp b/src/servers/app/DrawState.cpp index 23c358fe6e..d7f88bc922 100644 --- a/src/servers/app/DrawState.cpp +++ b/src/servers/app/DrawState.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2008, Haiku. + * Copyright 2001-2015, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -8,6 +8,7 @@ * Stephan Aßmus * Axel Dörfler, axeld@pinc-software.de * Michael Pfeiffer + * Julian Harnath */ //! Data classes for working with BView states and draw parameters @@ -211,7 +212,7 @@ DrawState::ReadFromLink(BPrivate::LinkReceiver& link) ViewSetStateInfo info; link.Read(&info); - + fPenLocation = info.penLocation; fPenSize = info.penSize; fHighColor = info.highColor; @@ -407,8 +408,9 @@ DrawState::GetCombinedClippingRegion(BRegion* region) const { if (fClippingRegion != NULL) { BRegion localTransformedClipping(*fClippingRegion); - Transform(&localTransformedClipping); - + SimpleTransform penTransform; + Transform(penTransform); + penTransform.Apply(&localTransformedClipping); if (fPreviousState != NULL && fPreviousState->GetCombinedClippingRegion(region)) { localTransformedClipping.IntersectWith(region); @@ -438,7 +440,7 @@ DrawState::SetAlphaMask(AlphaMask* mask) fAlphaMask = mask; if (fAlphaMask != NULL && fPreviousState != NULL) fAlphaMask->SetPrevious(fPreviousState->fAlphaMask); - + } @@ -453,83 +455,19 @@ DrawState::GetAlphaMask() const void -DrawState::Transform(float* x, float* y) const +DrawState::Transform(SimpleTransform& transform) const { - // scale relative to origin, therefore - // scale first then translate to - // origin - *x *= fCombinedScale; - *y *= fCombinedScale; - *x += fCombinedOrigin.x; - *y += fCombinedOrigin.y; + transform.AddOffset(fCombinedOrigin.x, fCombinedOrigin.y); + transform.SetScale(fCombinedScale); } void -DrawState::InverseTransform(float* x, float* y) const +DrawState::InverseTransform(SimpleTransform& transform) const { - *x -= fCombinedOrigin.x; - *y -= fCombinedOrigin.y; - if (fCombinedScale != 0.0) { - *x /= fCombinedScale; - *y /= fCombinedScale; - } -} - - -void -DrawState::Transform(BPoint* point) const -{ - Transform(&(point->x), &(point->y)); -} - - -void -DrawState::Transform(BRect* rect) const -{ - Transform(&(rect->left), &(rect->top)); - Transform(&(rect->right), &(rect->bottom)); -} - - -void -DrawState::Transform(BRegion* region) const -{ - if (fCombinedScale == 1.0) { - region->OffsetBy(fCombinedOrigin.x, fCombinedOrigin.y); - } else { - // TODO: optimize some more - BRegion converted; - int32 count = region->CountRects(); - for (int32 i = 0; i < count; i++) { - BRect r = region->RectAt(i); - BPoint lt(r.LeftTop()); - BPoint rb(r.RightBottom()); - // offset to bottom right corner of pixel before transformation - rb.x++; - rb.y++; - // apply transformation - Transform(<.x, <.y); - Transform(&rb.x, &rb.y); - // reset bottom right to pixel "index" - rb.x--; - rb.y--; - // add rect to converted region - // NOTE/TODO: the rect would not have to go - // through the whole intersection test process, - // it is guaranteed not to overlap with any rect - // already contained in the region - converted.Include(BRect(lt, rb)); - } - *region = converted; - } -} - - -void -DrawState::InverseTransform(BPoint* point) const -{ - InverseTransform(&(point->x), &(point->y)); + transform.AddOffset(-fCombinedOrigin.x, -fCombinedOrigin.y); + if (fCombinedScale != 0.0) + transform.SetScale(1.0 / fCombinedScale); } diff --git a/src/servers/app/DrawState.h b/src/servers/app/DrawState.h index 48508ed6cf..392549789f 100644 --- a/src/servers/app/DrawState.h +++ b/src/servers/app/DrawState.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2008, Haiku. + * Copyright 2001-2015, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -7,6 +7,7 @@ * Adi Oanca * Stephan Aßmus * Axel Dörfler, axeld@pinc-software.de + * Julian Harnath */ #ifndef _DRAW_STATE_H_ #define _DRAW_STATE_H_ @@ -20,6 +21,7 @@ #include "ServerFont.h" #include "PatternHandler.h" +#include "SimpleTransform.h" class AlphaMask; class BRegion; @@ -78,14 +80,8 @@ public: AlphaMask* GetAlphaMask() const; // coordinate transformations - void Transform(float* x, float* y) const; - void InverseTransform(float* x, float* y) const; - - void Transform(BPoint* point) const; - void Transform(BRect* rect) const; - void Transform(BRegion* region) const; - - void InverseTransform(BPoint* point) const; + void Transform(SimpleTransform& transform) const; + void InverseTransform(SimpleTransform& transform) const; // color void SetHighColor(rgb_color color); diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index 6f09cb0d70..d03ddb29e3 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -204,7 +204,7 @@ ShapePainter::Draw(BRect frame, bool filled) } BPoint offset(fCanvas->CurrentState()->PenLocation()); - fCanvas->ConvertToScreenForDrawing(&offset); + fCanvas->PenToScreenTransform().Apply(&offset); fCanvas->GetDrawingEngine()->DrawShape(frame, opCount, opList, ptCount, ptList, filled, offset, fCanvas->Scale()); @@ -265,8 +265,9 @@ stroke_line(Canvas* canvas, BPoint start, BPoint end) { BPoint penPos = end; - canvas->ConvertToScreenForDrawing(&start); - canvas->ConvertToScreenForDrawing(&end); + const SimpleTransform transform = canvas->PenToScreenTransform(); + transform.Apply(&start); + transform.Apply(&end); canvas->GetDrawingEngine()->StrokeLine(start, end); canvas->CurrentState()->SetPenLocation(penPos); @@ -279,7 +280,7 @@ stroke_line(Canvas* canvas, BPoint start, BPoint end) static void stroke_rect(Canvas* canvas, BRect rect) { - canvas->ConvertToScreenForDrawing(&rect); + canvas->PenToScreenTransform().Apply(&rect); canvas->GetDrawingEngine()->StrokeRect(rect); } @@ -287,7 +288,7 @@ stroke_rect(Canvas* canvas, BRect rect) static void fill_rect(Canvas* canvas, BRect rect) { - canvas->ConvertToScreenForDrawing(&rect); + canvas->PenToScreenTransform().Apply(&rect); canvas->GetDrawingEngine()->FillRect(rect); } @@ -295,7 +296,7 @@ fill_rect(Canvas* canvas, BRect rect) static void draw_round_rect(Canvas* canvas, BRect rect, BPoint radii, bool fill) { - canvas->ConvertToScreenForDrawing(&rect); + canvas->PenToScreenTransform().Apply(&rect); float scale = canvas->CurrentState()->CombinedScale(); canvas->GetDrawingEngine()->DrawRoundRect(rect, radii.x * scale, radii.y * scale, fill); @@ -320,8 +321,7 @@ static void stroke_bezier(Canvas* canvas, const BPoint* viewPoints) { BPoint points[4]; - canvas->ConvertToScreenForDrawing(points, viewPoints, 4); - + canvas->PenToScreenTransform().Apply(points, viewPoints, 4); canvas->GetDrawingEngine()->DrawBezier(points, false); } @@ -330,8 +330,7 @@ static void fill_bezier(Canvas* canvas, const BPoint* viewPoints) { BPoint points[4]; - canvas->ConvertToScreenForDrawing(points, viewPoints, 4); - + canvas->PenToScreenTransform().Apply(points, viewPoints, 4); canvas->GetDrawingEngine()->DrawBezier(points, true); } @@ -342,7 +341,7 @@ stroke_arc(Canvas* canvas, BPoint center, BPoint radii, { BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x - 1, center.y + radii.y - 1); - canvas->ConvertToScreenForDrawing(&rect); + canvas->PenToScreenTransform().Apply(&rect); canvas->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, false); } @@ -353,7 +352,7 @@ fill_arc(Canvas* canvas, BPoint center, BPoint radii, { BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x - 1, center.y + radii.y - 1); - canvas->ConvertToScreenForDrawing(&rect); + canvas->PenToScreenTransform().Apply(&rect); canvas->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, true); } @@ -363,7 +362,7 @@ stroke_ellipse(Canvas* canvas, BPoint center, BPoint radii) { BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x - 1, center.y + radii.y - 1); - canvas->ConvertToScreenForDrawing(&rect); + canvas->PenToScreenTransform().Apply(&rect); canvas->GetDrawingEngine()->DrawEllipse(rect, false); } @@ -373,7 +372,7 @@ fill_ellipse(Canvas* canvas, BPoint center, BPoint radii) { BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x - 1, center.y + radii.y - 1); - canvas->ConvertToScreenForDrawing(&rect); + canvas->PenToScreenTransform().Apply(&rect); canvas->GetDrawingEngine()->DrawEllipse(rect, true); } @@ -391,8 +390,7 @@ stroke_polygon(Canvas* canvas, int32 numPoints, char data[200 * sizeof(BPoint)]; BPoint* points = (BPoint*)data; - canvas->ConvertToScreenForDrawing(points, viewPoints, numPoints); - + canvas->PenToScreenTransform().Apply(points, viewPoints, numPoints); BRect polyFrame; get_polygon_frame(points, numPoints, &polyFrame); @@ -405,8 +403,7 @@ stroke_polygon(Canvas* canvas, int32 numPoints, if (points == NULL) return; - canvas->ConvertToScreenForDrawing(points, viewPoints, numPoints); - + canvas->PenToScreenTransform().Apply(points, viewPoints, numPoints); BRect polyFrame; get_polygon_frame(points, numPoints, &polyFrame); @@ -430,8 +427,7 @@ fill_polygon(Canvas* canvas, int32 numPoints, char data[200 * sizeof(BPoint)]; BPoint* points = (BPoint*)data; - canvas->ConvertToScreenForDrawing(points, viewPoints, numPoints); - + canvas->PenToScreenTransform().Apply(points, viewPoints, numPoints); BRect polyFrame; get_polygon_frame(points, numPoints, &polyFrame); @@ -444,8 +440,7 @@ fill_polygon(Canvas* canvas, int32 numPoints, if (points == NULL) return; - canvas->ConvertToScreenForDrawing(points, viewPoints, numPoints); - + canvas->PenToScreenTransform().Apply(points, viewPoints, numPoints); BRect polyFrame; get_polygon_frame(points, numPoints, &polyFrame); @@ -486,11 +481,11 @@ draw_string(Canvas* canvas, const char* string, float deltaSpace, BPoint location = canvas->CurrentState()->PenLocation(); escapement_delta delta = { deltaSpace, deltaNonSpace }; - canvas->ConvertToScreenForDrawing(&location); + canvas->PenToScreenTransform().Apply(&location); location = canvas->GetDrawingEngine()->DrawString(string, strlen(string), location, &delta); - canvas->ConvertFromScreenForDrawing(&location); + canvas->PenToScreenTransform().Apply(&location); canvas->CurrentState()->SetPenLocation(location); // the DrawingEngine/Painter does not need to be updated, since this // effects only the view->screen coord conversion, which is handled @@ -511,7 +506,7 @@ draw_pixels(Canvas* canvas, BRect src, BRect dest, int32 width, memcpy(bitmap.Bits(), data, height * bytesPerRow); - canvas->ConvertToScreenForDrawing(&dest); + canvas->PenToScreenTransform().Apply(&dest); canvas->GetDrawingEngine()->DrawBitmap(&bitmap, src, dest, options); } @@ -570,7 +565,7 @@ pop_state(Canvas* canvas) canvas->PopState(); BPoint p(0, 0); - canvas->ConvertToScreenForDrawing(&p); + canvas->PenToScreenTransform().Apply(&p); canvas->GetDrawingEngine()->SetDrawState(canvas->CurrentState(), (int32)p.x, (int32)p.y); } diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 242438faf2..81892f939c 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -351,7 +351,7 @@ ServerWindow::_Show() fDesktop->ShowWindow(fWindow); if (fDirectWindowInfo && fDirectWindowInfo->IsFullScreen()) _ResizeToFullScreen(); - + fDesktop->LockSingleWindow(); } @@ -1964,7 +1964,7 @@ fDesktop->LockSingleWindow(); } else { _UpdateCurrentDrawingRegion(); BRegion region(fCurrentDrawingRegion); - fCurrentView->ConvertFromScreen(®ion); + fCurrentView->ScreenToLocalTransform().Apply(®ion); fLink.AttachRegion(region); } fLink.Flush(); @@ -2254,8 +2254,10 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, info.endPoint.x, info.endPoint.y)); BPoint penPos = info.endPoint; - fCurrentView->ConvertToScreenForDrawing(&info.startPoint); - fCurrentView->ConvertToScreenForDrawing(&info.endPoint); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); + transform.Apply(&info.startPoint); + transform.Apply(&info.endPoint); drawingEngine->StrokeLine(info.startPoint, info.endPoint); // We update the pen here because many DrawingEngine calls which @@ -2279,7 +2281,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, fCurrentView->Name(), rect.left, rect.top, rect.right, rect.bottom)); - fCurrentView->ConvertToScreenForDrawing(&rect); + fCurrentView->PenToScreenTransform().Apply(&rect); drawingEngine->InvertRect(rect); break; } @@ -2294,7 +2296,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, fCurrentView->Name(), rect.left, rect.top, rect.right, rect.bottom)); - fCurrentView->ConvertToScreenForDrawing(&rect); + fCurrentView->PenToScreenTransform().Apply(&rect); drawingEngine->StrokeRect(rect); break; } @@ -2309,7 +2311,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, fCurrentView->Name(), rect.left, rect.top, rect.right, rect.bottom)); - fCurrentView->ConvertToScreenForDrawing(&rect); + fCurrentView->PenToScreenTransform().Apply(&rect); drawingEngine->FillRect(rect); break; } @@ -2326,8 +2328,10 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, fCurrentView->Name(), rect.left, rect.top, rect.right, rect.bottom)); - fCurrentView->ConvertToScreenForDrawing(&rect); - fCurrentView->ConvertToScreenForDrawing(gradient); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); + transform.Apply(&rect); + transform.Apply(gradient); drawingEngine->FillRect(rect, *gradient); delete gradient; break; @@ -2356,7 +2360,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, info.viewRect.left, info.viewRect.top, info.viewRect.right, info.viewRect.bottom)); - fCurrentView->ConvertToScreenForDrawing(&info.viewRect); + fCurrentView->PenToScreenTransform().Apply(&info.viewRect); // TODO: Unbreak... // if ((info.options & B_WAIT_FOR_RETRACE) != 0) @@ -2382,7 +2386,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, if (link.Read(&span) != B_OK) break; - fCurrentView->ConvertToScreenForDrawing(&r); + fCurrentView->PenToScreenTransform().Apply(&r); drawingEngine->DrawArc(r, angle, span, code == AS_FILL_ARC); break; } @@ -2399,8 +2403,10 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BGradient* gradient; if (link.ReadGradient(&gradient) != B_OK) break; - fCurrentView->ConvertToScreenForDrawing(&r); - fCurrentView->ConvertToScreenForDrawing(gradient); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); + transform.Apply(&r); + transform.Apply(gradient); drawingEngine->FillArc(r, angle, span, *gradient); delete gradient; break; @@ -2411,11 +2417,13 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, DTRACE(("ServerWindow %s: Message AS_STROKE/FILL_BEZIER\n", Title())); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); BPoint pts[4]; status_t status; for (int32 i = 0; i < 4; i++) { status = link.Read(&(pts[i])); - fCurrentView->ConvertToScreenForDrawing(&pts[i]); + transform.Apply(&pts[i]); } if (status != B_OK) break; @@ -2428,15 +2436,17 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, GTRACE(("ServerWindow %s: Message AS_FILL_BEZIER_GRADIENT\n", Title())); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); BPoint pts[4]; for (int32 i = 0; i < 4; i++) { link.Read(&(pts[i])); - fCurrentView->ConvertToScreenForDrawing(&pts[i]); + transform.Apply(&pts[i]); } BGradient* gradient; if (link.ReadGradient(&gradient) != B_OK) break; - fCurrentView->ConvertToScreenForDrawing(gradient); + transform.Apply(gradient); drawingEngine->FillBezier(pts, *gradient); delete gradient; break; @@ -2451,7 +2461,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, if (link.Read(&rect) != B_OK) break; - fCurrentView->ConvertToScreenForDrawing(&rect); + fCurrentView->PenToScreenTransform().Apply(&rect); drawingEngine->DrawEllipse(rect, code == AS_FILL_ELLIPSE); break; } @@ -2465,8 +2475,10 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BGradient* gradient; if (link.ReadGradient(&gradient) != B_OK) break; - fCurrentView->ConvertToScreenForDrawing(&rect); - fCurrentView->ConvertToScreenForDrawing(gradient); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); + transform.Apply(&rect); + transform.Apply(gradient); drawingEngine->FillEllipse(rect, *gradient); delete gradient; break; @@ -2485,7 +2497,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, if (link.Read(&yRadius) != B_OK) break; - fCurrentView->ConvertToScreenForDrawing(&rect); + fCurrentView->PenToScreenTransform().Apply(&rect); float scale = fCurrentView->CurrentState()->CombinedScale(); drawingEngine->DrawRoundRect(rect, xRadius * scale, yRadius * scale, code == AS_FILL_ROUNDRECT); @@ -2504,8 +2516,10 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BGradient* gradient; if (link.ReadGradient(&gradient) != B_OK) break; - fCurrentView->ConvertToScreenForDrawing(&rect); - fCurrentView->ConvertToScreenForDrawing(gradient); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); + transform.Apply(&rect); + transform.Apply(gradient); drawingEngine->FillRoundRect(rect, xrad, yrad, *gradient); delete gradient; break; @@ -2516,18 +2530,20 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, DTRACE(("ServerWindow %s: Message AS_STROKE/FILL_TRIANGLE\n", Title())); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); BPoint pts[3]; BRect rect; for (int32 i = 0; i < 3; i++) { link.Read(&(pts[i])); - fCurrentView->ConvertToScreenForDrawing(&pts[i]); + transform.Apply(&pts[i]); } if (link.Read(&rect) != B_OK) break; - fCurrentView->ConvertToScreenForDrawing(&rect); + transform.Apply(&rect); drawingEngine->DrawTriangle(pts, rect, code == AS_FILL_TRIANGLE); break; } @@ -2536,18 +2552,20 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, DTRACE(("ServerWindow %s: Message AS_FILL_TRIANGLE_GRADIENT\n", Title())); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); BPoint pts[3]; BRect rect; for (int32 i = 0; i < 3; i++) { link.Read(&(pts[i])); - fCurrentView->ConvertToScreenForDrawing(&pts[i]); + transform.Apply(&pts[i]); } link.Read(&rect); BGradient* gradient; if (link.ReadGradient(&gradient) != B_OK) break; - fCurrentView->ConvertToScreenForDrawing(&rect); - fCurrentView->ConvertToScreenForDrawing(gradient); + transform.Apply(&rect); + transform.Apply(gradient); drawingEngine->FillTriangle(pts, rect, *gradient); delete gradient; break; @@ -2567,11 +2585,13 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, link.Read(&isClosed); link.Read(&pointCount); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); BPoint* pointList = new(nothrow) BPoint[pointCount]; if (link.Read(pointList, pointCount * sizeof(BPoint)) >= B_OK) { for (int32 i = 0; i < pointCount; i++) - fCurrentView->ConvertToScreenForDrawing(&pointList[i]); - fCurrentView->ConvertToScreenForDrawing(&polyFrame); + transform.Apply(&pointList[i]); + transform.Apply(&polyFrame); drawingEngine->DrawPolygon(pointList, pointCount, polyFrame, code == AS_FILL_POLYGON, isClosed && pointCount > 2); @@ -2590,14 +2610,16 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, link.Read(&polyFrame); link.Read(&pointCount); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); BPoint* pointList = new(nothrow) BPoint[pointCount]; BGradient* gradient; if (link.Read(pointList, pointCount * sizeof(BPoint)) == B_OK && link.ReadGradient(&gradient) == B_OK) { for (int32 i = 0; i < pointCount; i++) - fCurrentView->ConvertToScreenForDrawing(&pointList[i]); - fCurrentView->ConvertToScreenForDrawing(&polyFrame); - fCurrentView->ConvertToScreenForDrawing(gradient); + transform.Apply(&pointList[i]); + transform.Apply(&polyFrame); + transform.Apply(gradient); drawingEngine->FillPolygon(pointList, pointCount, polyFrame, *gradient, isClosed && pointCount > 2); @@ -2631,8 +2653,10 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, = fCurrentView->CurrentState()->PenLocation(); shapeFrame.OffsetBy(screenOffset); - fCurrentView->ConvertToScreenForDrawing(&screenOffset); - fCurrentView->ConvertToScreenForDrawing(&shapeFrame); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); + transform.Apply(&screenOffset); + transform.Apply(&shapeFrame); drawingEngine->DrawShape(shapeFrame, opCount, opList, ptCount, ptList, code == AS_FILL_SHAPE, screenOffset, @@ -2669,9 +2693,11 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, = fCurrentView->CurrentState()->PenLocation(); shapeFrame.OffsetBy(screenOffset); - fCurrentView->ConvertToScreenForDrawing(&screenOffset); - fCurrentView->ConvertToScreenForDrawing(&shapeFrame); - fCurrentView->ConvertToScreenForDrawing(gradient); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); + transform.Apply(&screenOffset); + transform.Apply(&shapeFrame); + transform.Apply(gradient); drawingEngine->FillShape(shapeFrame, opCount, opList, ptCount, ptList, *gradient, screenOffset, fCurrentView->Scale()); @@ -2690,7 +2716,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, if (link.ReadRegion(®ion) < B_OK) break; - fCurrentView->ConvertToScreenForDrawing(®ion); + fCurrentView->PenToScreenTransform().Apply(®ion); drawingEngine->FillRegion(region); break; @@ -2707,8 +2733,10 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, if (link.ReadGradient(&gradient) != B_OK) break; - fCurrentView->ConvertToScreenForDrawing(®ion); - fCurrentView->ConvertToScreenForDrawing(gradient); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); + transform.Apply(®ion); + transform.Apply(gradient); drawingEngine->FillRegion(region, *gradient); delete gradient; break; @@ -2747,11 +2775,11 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, } // Convert to screen coords and draw + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); for (int32 i = 0; i < lineCount; i++) { - fCurrentView->ConvertToScreenForDrawing( - &lineData[i].startPoint); - fCurrentView->ConvertToScreenForDrawing( - &lineData[i].endPoint); + transform.Apply(&lineData[i].startPoint); + transform.Apply(&lineData[i].endPoint); } drawingEngine->StrokeLineArray(lineCount, lineData); @@ -2796,11 +2824,11 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, DTRACE(("ServerWindow %s: Message AS_DRAW_STRING, View: %s " "-> %s\n", Title(), fCurrentView->Name(), string)); - fCurrentView->ConvertToScreenForDrawing(&info.location); + fCurrentView->PenToScreenTransform().Apply(&info.location); BPoint penLocation = drawingEngine->DrawString(string, info.stringLength, info.location, delta); - fCurrentView->ConvertFromScreenForDrawing(&penLocation); + fCurrentView->ScreenToPenTransform().Apply(&penLocation); fCurrentView->CurrentState()->SetPenLocation(penLocation); if (string != stackString) @@ -2853,13 +2881,15 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, DTRACE(("ServerWindow %s: Message AS_DRAW_STRING_WITH_OFFSETS, View: %s " "-> %s\n", Title(), fCurrentView->Name(), string)); + const SimpleTransform transform = + fCurrentView->PenToScreenTransform(); for (int32 i = 0; i < glyphCount; i++) - fCurrentView->ConvertToScreenForDrawing(&locations[i]); + transform.Apply(&locations[i]); BPoint penLocation = drawingEngine->DrawString(string, stringLength, locations); - fCurrentView->ConvertFromScreenForDrawing(&penLocation); + fCurrentView->ScreenToPenTransform().Apply(&penLocation); fCurrentView->CurrentState()->SetPenLocation(penLocation); break; @@ -3703,11 +3733,11 @@ ServerWindow::_UpdateDrawState(View* view) if (view != NULL && drawingEngine != NULL) { BPoint leftTop(0, 0); if (view->GetAlphaMask() != NULL) { - view->ConvertToScreen(&leftTop); + view->LocalToScreenTransform().Apply(&leftTop); view->GetAlphaMask()->Update(view->Bounds(), leftTop); leftTop = BPoint(0, 0); } - view->ConvertToScreenForDrawing(&leftTop); + view->PenToScreenTransform().Apply(&leftTop); drawingEngine->SetDrawState(view->CurrentState(), leftTop.x, leftTop.y); } } diff --git a/src/servers/app/SimpleTransform.h b/src/servers/app/SimpleTransform.h new file mode 100644 index 0000000000..00c8f458a5 --- /dev/null +++ b/src/servers/app/SimpleTransform.h @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2001-2015, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + * Stephan Aßmus + * Adrien Destugues + * Julian Harnath + */ + +#ifndef SIMPLE_TRANSFORM_H +#define SIMPLE_TRANSFORM_H + +#include +#include +#include +#include +#include +#include +#include + +#include "IntPoint.h" +#include "IntRect.h" + + +class SimpleTransform { +public: + SimpleTransform() + : + fScale(1.0) + { + } + + void AddOffset(float x, float y) + { + fOffset.x += x; + fOffset.y += y; + } + + void SetScale(float scale) + { + fScale = scale; + } + + void Apply(BPoint* point) const + { + _Apply(point->x, point->y); + } + + void Apply(IntPoint* point) const + { + _Apply(point->x, point->y); + } + + void Apply(BRect* rect) const + { + if (fScale == 1.0) { + rect->OffsetBy(fOffset.x, fOffset.y); + } else { + _Apply(rect->left, rect->top); + _Apply(rect->right, rect->bottom); + } + } + + void Apply(IntRect* rect) const + { + if (fScale == 1.0) { + rect->OffsetBy(fOffset.x, fOffset.y); + } else { + _Apply(rect->left, rect->top); + _Apply(rect->right, rect->bottom); + } + } + + void Apply(BRegion* region) const + { + if (fScale == 1.0) { + region->OffsetBy(fOffset.x, fOffset.y); + } else { + // TODO: optimize some more + BRegion converted; + int32 count = region->CountRects(); + for (int32 i = 0; i < count; i++) { + BRect r = region->RectAt(i); + BPoint lt(r.LeftTop()); + BPoint rb(r.RightBottom()); + // offset to bottom right corner of pixel before transformation + rb.x++; + rb.y++; + // apply transformation + _Apply(lt.x, lt.y); + _Apply(rb.x, rb.y); + // reset bottom right to pixel "index" + rb.x--; + rb.y--; + // add rect to converted region + // NOTE/TODO: the rect would not have to go + // through the whole intersection test process, + // it is guaranteed not to overlap with any rect + // already contained in the region + converted.Include(BRect(lt, rb)); + } + *region = converted; + } + } + + void Apply(BGradient* gradient) const + { + switch (gradient->GetType()) { + case BGradient::TYPE_LINEAR: + { + BGradientLinear* linear = (BGradientLinear*) gradient; + BPoint start = linear->Start(); + BPoint end = linear->End(); + Apply(&start); + Apply(&end); + linear->SetStart(start); + linear->SetEnd(end); + break; + } + + case BGradient::TYPE_RADIAL: + { + BGradientRadial* radial = (BGradientRadial*) gradient; + BPoint center = radial->Center(); + Apply(¢er); + radial->SetCenter(center); + break; + } + + case BGradient::TYPE_RADIAL_FOCUS: + { + BGradientRadialFocus* radialFocus = + (BGradientRadialFocus*)gradient; + BPoint center = radialFocus->Center(); + BPoint focal = radialFocus->Focal(); + Apply(¢er); + Apply(&focal); + radialFocus->SetCenter(center); + radialFocus->SetFocal(focal); + break; + } + + case BGradient::TYPE_DIAMOND: + { + BGradientDiamond* diamond = (BGradientDiamond*) gradient; + BPoint center = diamond->Center(); + Apply(¢er); + diamond->SetCenter(center); + break; + } + + case BGradient::TYPE_CONIC: + { + BGradientConic* conic = (BGradientConic*) gradient; + BPoint center = conic->Center(); + Apply(¢er); + conic->SetCenter(center); + break; + } + + case BGradient::TYPE_NONE: + { + break; + } + } + + // Make sure the gradient is fully padded so that out of bounds access + // get the correct colors + gradient->SortColorStopsByOffset(); + + BGradient::ColorStop* end = gradient->ColorStopAtFast( + gradient->CountColorStops() - 1); + + if (end->offset != 255) + gradient->AddColor(end->color, 255); + + BGradient::ColorStop* start = gradient->ColorStopAtFast(0); + + if (start->offset != 0) + gradient->AddColor(start->color, 0); + + gradient->SortColorStopsByOffset(); + } + + void Apply(BPoint* destination, const BPoint* source, int32 count) const + { + // TODO: optimize this, it should be smarter + while (count--) { + *destination = *source; + Apply(destination); + source++; + destination++; + } + } + + void Apply(BRect* destination, const BRect* source, int32 count) const + { + // TODO: optimize this, it should be smarter + while (count--) { + *destination = *source; + Apply(destination); + source++; + destination++; + } + } + + void Apply(BRegion* destination, const BRegion* source, int32 count) const + { + // TODO: optimize this, it should be smarter + while (count--) { + *destination = *source; + Apply(destination); + source++; + destination++; + } + } + +private: + void _Apply(int32& x, int32& y) const + { + x *= (int32)fScale; + y *= (int32)fScale; + x += (int32)fOffset.x; + y += (int32)fOffset.y; + } + + void _Apply(float& x, float& y) const + { + x *= fScale; + y *= fScale; + x += fOffset.x; + y += fOffset.y; + } + +private: + BPoint fOffset; + float fScale; +}; + + +#endif // SIMPLE_TRANSFORM_H diff --git a/src/servers/app/View.cpp b/src/servers/app/View.cpp index 7831b45cfb..b1375327a3 100644 --- a/src/servers/app/View.cpp +++ b/src/servers/app/View.cpp @@ -165,7 +165,8 @@ View::ConvertToVisibleInTopView(IntRect* bounds) const { *bounds = *bounds & Bounds(); // NOTE: this step is necessary even if we don't have a parent! - ConvertToParent(bounds); + bounds->OffsetBy(fFrame.left - fScrollingOffset.x, + fFrame.top - fScrollingOffset.y); if (fParent) fParent->ConvertToVisibleInTopView(bounds); @@ -440,7 +441,7 @@ View::ViewAt(const BPoint& where) IntRect frame = Frame(); if (Parent() != NULL) - Parent()->ConvertToScreen(&frame); + Parent()->LocalToScreenTransform().Apply(&frame); if (!frame.Contains(where)) return NULL; @@ -524,7 +525,7 @@ View::_UpdateOverlayView() const return; IntRect destination = fBitmapDestination; - ConvertToScreen(&destination); + LocalToScreenTransform().Apply(&destination); overlay->Configure(fBitmapSource, destination); } @@ -556,201 +557,34 @@ View::UpdateOverlay() void -View::ConvertToParent(BPoint* point) const +View::_LocalToScreenTransform(SimpleTransform& transform) const { - // remove scrolling offset and convert to parent coordinate space - point->x += fFrame.left - fScrollingOffset.x; - point->y += fFrame.top - fScrollingOffset.y; + const View* view = this; + int32 offsetX = 0; + int32 offsetY = 0; + do { + offsetX += view->fFrame.left - view->fScrollingOffset.x; + offsetY += view->fFrame.top - view->fScrollingOffset.y; + view = view->fParent; + } while (view != NULL); + + transform.AddOffset(offsetX, offsetY); } void -View::ConvertToParent(IntPoint* point) const +View::_ScreenToLocalTransform(SimpleTransform& transform) const { - // remove scrolling offset and convert to parent coordinate space - point->x += fFrame.left - fScrollingOffset.x; - point->y += fFrame.top - fScrollingOffset.y; -} + const View* view = this; + int32 offsetX = 0; + int32 offsetY = 0; + do { + offsetX += view->fScrollingOffset.x - view->fFrame.left; + offsetY += view->fScrollingOffset.y - view->fFrame.top; + view = view->fParent; + } while (view != NULL); - -void -View::ConvertToParent(BRect* rect) const -{ - // remove scrolling offset and convert to parent coordinate space - rect->OffsetBy(fFrame.left - fScrollingOffset.x, - fFrame.top - fScrollingOffset.y); -} - - -void -View::ConvertToParent(IntRect* rect) const -{ - // remove scrolling offset and convert to parent coordinate space - rect->OffsetBy(fFrame.left - fScrollingOffset.x, - fFrame.top - fScrollingOffset.y); -} - - -void -View::ConvertToParent(BRegion* region) const -{ - // remove scrolling offset and convert to parent coordinate space - region->OffsetBy(fFrame.left - fScrollingOffset.x, - fFrame.top - fScrollingOffset.y); -} - - -void -View::ConvertFromParent(BPoint* point) const -{ - // convert from parent coordinate space amd add scrolling offset - point->x += fScrollingOffset.x - fFrame.left; - point->y += fScrollingOffset.y - fFrame.top; -} - - -void -View::ConvertFromParent(IntPoint* point) const -{ - // convert from parent coordinate space amd add scrolling offset - point->x += fScrollingOffset.x - fFrame.left; - point->y += fScrollingOffset.y - fFrame.top; -} - - -void -View::ConvertFromParent(BRect* rect) const -{ - // convert from parent coordinate space amd add scrolling offset - rect->OffsetBy(fScrollingOffset.x - fFrame.left, - fScrollingOffset.y - fFrame.top); -} - - -void -View::ConvertFromParent(IntRect* rect) const -{ - // convert from parent coordinate space amd add scrolling offset - rect->OffsetBy(fScrollingOffset.x - fFrame.left, - fScrollingOffset.y - fFrame.top); -} - - -void -View::ConvertFromParent(BRegion* region) const -{ - // convert from parent coordinate space amd add scrolling offset - region->OffsetBy(fScrollingOffset.x - fFrame.left, - fScrollingOffset.y - fFrame.top); -} - -//! converts a point from local to screen coordinate system -void -View::ConvertToScreen(BPoint* pt) const -{ - ConvertToParent(pt); - - if (fParent) - fParent->ConvertToScreen(pt); -} - - -//! converts a point from local to screen coordinate system -void -View::ConvertToScreen(IntPoint* pt) const -{ - ConvertToParent(pt); - - if (fParent) - fParent->ConvertToScreen(pt); -} - - -//! converts a rect from local to screen coordinate system -void -View::ConvertToScreen(BRect* rect) const -{ - BPoint offset(0.0, 0.0); - ConvertToScreen(&offset); - - rect->OffsetBy(offset); -} - - -//! converts a rect from local to screen coordinate system -void -View::ConvertToScreen(IntRect* rect) const -{ - BPoint offset(0.0, 0.0); - ConvertToScreen(&offset); - - rect->OffsetBy(offset); -} - - -//! converts a region from local to screen coordinate system -void -View::ConvertToScreen(BRegion* region) const -{ - BPoint offset(0.0, 0.0); - ConvertToScreen(&offset); - - region->OffsetBy((int)offset.x, (int)offset.y); -} - - -//! converts a point from screen to local coordinate system -void -View::ConvertFromScreen(BPoint* pt) const -{ - ConvertFromParent(pt); - - if (fParent) - fParent->ConvertFromScreen(pt); -} - - -//! converts a point from screen to local coordinate system -void -View::ConvertFromScreen(IntPoint* pt) const -{ - ConvertFromParent(pt); - - if (fParent) - fParent->ConvertFromScreen(pt); -} - - -//! converts a rect from screen to local coordinate system -void -View::ConvertFromScreen(BRect* rect) const -{ - BPoint offset(0.0, 0.0); - ConvertFromScreen(&offset); - - rect->OffsetBy(offset.x, offset.y); -} - - -//! converts a rect from screen to local coordinate system -void -View::ConvertFromScreen(IntRect* rect) const -{ - BPoint offset(0.0, 0.0); - ConvertFromScreen(&offset); - - rect->OffsetBy((int)offset.x, (int)offset.y); -} - - -//! converts a region from screen to local coordinate system -void -View::ConvertFromScreen(BRegion* region) const -{ - BPoint offset(0.0, 0.0); - ConvertFromScreen(&offset); - - region->OffsetBy((int)offset.x, (int)offset.y); + transform.AddOffset(offsetX, offsetY); } @@ -775,7 +609,7 @@ View::MoveBy(int32 x, int32 y, BRegion* dirtyRegion) // local clipping to see which parts need invalidation IntRect oldVisibleBounds(newVisibleBounds); oldVisibleBounds.OffsetBy(-x, -y); - ConvertToScreen(&oldVisibleBounds); + LocalToScreenTransform().Apply(&oldVisibleBounds); ConvertToVisibleInTopView(&newVisibleBounds); @@ -788,7 +622,7 @@ View::MoveBy(int32 x, int32 y, BRegion* dirtyRegion) IntRect oldVisibleBounds(Bounds()); IntRect newVisibleBounds(oldVisibleBounds); oldVisibleBounds.OffsetBy(-x, -y); - ConvertToScreen(&oldVisibleBounds); + LocalToScreenTransform().Apply(&oldVisibleBounds); // NOTE: using ConvertToVisibleInTopView() // instead of ConvertToScreen()! see below @@ -875,7 +709,7 @@ View::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion) } } - ConvertToScreen(dirty); + LocalToScreenTransform().Apply(dirty); dirtyRegion->Include(dirty); } fWindow->RecycleRegion(dirty); @@ -1171,7 +1005,7 @@ View::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping, // draw view bitmap // TODO: support other options! BRect rect = fBitmapDestination; - ConvertToScreenForDrawing(&rect); + PenToScreenTransform().Apply(&rect); align_rect_to_pixels(&rect); @@ -1406,7 +1240,7 @@ View::AddTokensForViewsInRegion(BPrivate::PortLink& link, BRegion& region, // This check will prevent descending the view hierarchy // any further than necessary IntRect screenBounds(Bounds()); - ConvertToScreen(&screenBounds); + LocalToScreenTransform().Apply(&screenBounds); if (!region.Intersects((clipping_rect)screenBounds)) return; @@ -1537,7 +1371,7 @@ View::ScreenAndUserClipping(BRegion* windowContentClipping, bool force) const if (fScreenAndUserClipping == NULL) return fScreenClipping; - ConvertToScreen(fScreenAndUserClipping); + LocalToScreenTransform().Apply(fScreenAndUserClipping); fScreenAndUserClipping->IntersectWith( &_ScreenClipping(windowContentClipping, force)); return *fScreenAndUserClipping; @@ -1578,7 +1412,7 @@ View::_ScreenClipping(BRegion* windowContentClipping, bool force) const { if (!fScreenClippingValid || force) { fScreenClipping = fLocalClipping; - ConvertToScreen(&fScreenClipping); + LocalToScreenTransform().Apply(&fScreenClipping); // see if parts of our bounds are hidden underneath // the parent, the local clipping does not account for this diff --git a/src/servers/app/View.h b/src/servers/app/View.h index 7bdc31a78d..5550fcb961 100644 --- a/src/servers/app/View.h +++ b/src/servers/app/View.h @@ -111,31 +111,7 @@ public: View* ViewAt(const BPoint& where); - // coordinate conversion - void ConvertToParent(BPoint* point) const; - void ConvertToParent(IntPoint* point) const; - void ConvertToParent(BRect* rect) const; - void ConvertToParent(IntRect* rect) const; - void ConvertToParent(BRegion* region) const; - - void ConvertFromParent(BPoint* point) const; - void ConvertFromParent(IntPoint* point) const; - void ConvertFromParent(BRect* rect) const; - void ConvertFromParent(IntRect* rect) const; - void ConvertFromParent(BRegion* region) const; - - void ConvertToScreen(BPoint* point) const; - void ConvertToScreen(IntPoint* point) const; - void ConvertToScreen(BRect* rect) const; - void ConvertToScreen(IntRect* rect) const; - void ConvertToScreen(BRegion* region) const; - - void ConvertFromScreen(BPoint* point) const; - void ConvertFromScreen(IntPoint* point) const; - void ConvertFromScreen(BRect* rect) const; - void ConvertFromScreen(IntRect* rect) const; - void ConvertFromScreen(BRegion* region) const; - +public: void MoveBy(int32 dx, int32 dy, BRegion* dirtyRegion); @@ -235,6 +211,11 @@ public: #endif protected: + virtual void _LocalToScreenTransform( + SimpleTransform& transform) const; + virtual void _ScreenToLocalTransform( + SimpleTransform& transform) const; + BRegion& _ScreenClipping(BRegion* windowContentClipping, bool force = false) const; void _MoveScreenClipping(int32 x, int32 y, diff --git a/src/servers/app/Window.cpp b/src/servers/app/Window.cpp index 117e67a564..8af42bd2bd 100644 --- a/src/servers/app/Window.cpp +++ b/src/servers/app/Window.cpp @@ -817,7 +817,7 @@ Window::InvalidateView(View* view, BRegion& viewRegion) if (!fContentRegionValid) _UpdateContentRegion(); - view->ConvertToScreen(&viewRegion); + view->LocalToScreenTransform().Apply(&viewRegion); viewRegion.IntersectWith(&VisibleContentRegion()); if (viewRegion.CountRects() > 0) { viewRegion.IntersectWith( diff --git a/src/servers/app/WorkspacesView.cpp b/src/servers/app/WorkspacesView.cpp index be53497cec..2e4aabac75 100644 --- a/src/servers/app/WorkspacesView.cpp +++ b/src/servers/app/WorkspacesView.cpp @@ -90,7 +90,7 @@ WorkspacesView::_WorkspaceAt(int32 i) _GetGrid(columns, rows); BRect frame = Bounds(); - ConvertToScreen(&frame); + LocalToScreenTransform().Apply(&frame); int32 width = frame.IntegerWidth() / columns; int32 height = frame.IntegerHeight() / rows; @@ -356,7 +356,7 @@ void WorkspacesView::_Invalidate() const { BRect frame = Bounds(); - ConvertToScreen(&frame); + LocalToScreenTransform().Apply(&frame); BRegion region(frame); Window()->MarkContentDirty(region); @@ -385,7 +385,7 @@ WorkspacesView::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping, drawingEngine->ConstrainClippingRegion(&gridRegion); BRect frame = Bounds(); - ConvertToScreen(&frame); + LocalToScreenTransform().Apply(&frame); // horizontal lines From ad53a0d999135776e664131cba0321bd1ce9e729 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Mon, 6 Apr 2015 14:44:11 +0200 Subject: [PATCH 003/370] app_server: add unit test add-on, test for SimpleTransform * app_server currently does not have any real unit tests, making changes more difficult and riskier. A new directory unit_tests with a test add-on is added in app_server's tetsts directory to hold future unit tests. * Add test for SimpleTransform class --- src/tests/servers/app/Jamfile | 1 + .../app/unit_tests/AppServerUnitTestAddOn.cpp | 20 ++ src/tests/servers/app/unit_tests/Jamfile | 15 + .../app/unit_tests/SimpleTransformTest.cpp | 269 ++++++++++++++++++ .../app/unit_tests/SimpleTransformTest.h | 36 +++ 5 files changed, 341 insertions(+) create mode 100644 src/tests/servers/app/unit_tests/AppServerUnitTestAddOn.cpp create mode 100644 src/tests/servers/app/unit_tests/Jamfile create mode 100644 src/tests/servers/app/unit_tests/SimpleTransformTest.cpp create mode 100644 src/tests/servers/app/unit_tests/SimpleTransformTest.h diff --git a/src/tests/servers/app/Jamfile b/src/tests/servers/app/Jamfile index 0a5daf047e..f3e3ac340d 100644 --- a/src/tests/servers/app/Jamfile +++ b/src/tests/servers/app/Jamfile @@ -249,6 +249,7 @@ SubInclude HAIKU_TOP src tests servers app statusbar ; SubInclude HAIKU_TOP src tests servers app stress_test ; SubInclude HAIKU_TOP src tests servers app textview ; SubInclude HAIKU_TOP src tests servers app transformation ; +SubInclude HAIKU_TOP src tests servers app unit_tests ; SubInclude HAIKU_TOP src tests servers app view_state ; SubInclude HAIKU_TOP src tests servers app view_transit ; SubInclude HAIKU_TOP src tests servers app window_creation ; diff --git a/src/tests/servers/app/unit_tests/AppServerUnitTestAddOn.cpp b/src/tests/servers/app/unit_tests/AppServerUnitTestAddOn.cpp new file mode 100644 index 0000000000..2044db51de --- /dev/null +++ b/src/tests/servers/app/unit_tests/AppServerUnitTestAddOn.cpp @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Julian Harnath + * All rights reserved. Distributed under the terms of the MIT license. + */ + +#include +#include + +#include "SimpleTransformTest.h" + + +BTestSuite* +getTestSuite() +{ + BTestSuite* suite = new BTestSuite("AppServerUnitTests"); + + SimpleTransformTest::AddTests(*suite); + + return suite; +} diff --git a/src/tests/servers/app/unit_tests/Jamfile b/src/tests/servers/app/unit_tests/Jamfile new file mode 100644 index 0000000000..89fbc1b0fd --- /dev/null +++ b/src/tests/servers/app/unit_tests/Jamfile @@ -0,0 +1,15 @@ +SubDir HAIKU_TOP src tests servers app unit_tests ; + +UseHeaders [ FDirName $(HAIKU_TOP) src servers app ] : true ; + +SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src servers app ] ; + +UnitTestLib app_server_unit_tests.so : + AppServerUnitTestAddOn.cpp + + IntPoint.cpp + IntRect.cpp + SimpleTransformTest.cpp + + : be [ TargetLibstdc++ ] + ; diff --git a/src/tests/servers/app/unit_tests/SimpleTransformTest.cpp b/src/tests/servers/app/unit_tests/SimpleTransformTest.cpp new file mode 100644 index 0000000000..db4872b9f3 --- /dev/null +++ b/src/tests/servers/app/unit_tests/SimpleTransformTest.cpp @@ -0,0 +1,269 @@ +/* + * Copyright 2015 Julian Harnath + * All rights reserved. Distributed under the terms of the MIT license. + */ + +#include "SimpleTransformTest.h" + +#include "IntPoint.h" +#include "IntRect.h" + +#include +#include + + +void +SimpleTransformTest::TransformPoint() +{ + BPoint point(1.0, 1.0); + SimpleTransform specimen; + specimen.AddOffset(10.0, 10.0); + specimen.Apply(&point); + CPPUNIT_ASSERT(point == BPoint(11.0, 11.0)); + + specimen.AddOffset(10.0, 10.0); + point.Set(0.0, 0.0); + specimen.Apply(&point); + CPPUNIT_ASSERT(point == BPoint(20.0, 20.0)); +} + + +void +SimpleTransformTest::TransformIntPoint() +{ + IntPoint point(1, 1); + SimpleTransform specimen; + specimen.AddOffset(10.0, 10.0); + specimen.Apply(&point); + CPPUNIT_ASSERT(point == BPoint(11.0, 11.0)); +} + + +void +SimpleTransformTest::TransformRect() +{ + BRect rect(5.0, 10.0, 15.0, 20.0); + SimpleTransform specimen; + specimen.AddOffset(10.0, 10.0); + specimen.Apply(&rect); + CPPUNIT_ASSERT(rect == BRect(15.0, 20.0, 25.0, 30.0)); + + specimen.SetScale(2.5); + specimen.Apply(&rect); + CPPUNIT_ASSERT(rect == BRect(47.5, 60.0, 72.5, 85.0)); +} + + +void +SimpleTransformTest::TransformIntRect() +{ + IntRect rect(5, 10, 15, 20); + SimpleTransform specimen; + specimen.AddOffset(10.0, 10.0); + specimen.Apply(&rect); + CPPUNIT_ASSERT(rect == IntRect(15, 20, 25, 30)); + + specimen.SetScale(2); + specimen.Apply(&rect); + CPPUNIT_ASSERT(rect == BRect(40, 50, 60, 70)); +} + + +void +SimpleTransformTest::TransformRegion() +{ + BRegion region; + region.Include(BRect( 5.0, 5.0, 20.0, 20.0)); + region.Include(BRect(10.0, 10.0, 30.0, 30.0)); + region.Exclude(BRect(10.0, 20.0, 20.0, 25.0)); + + BRegion reference1 = region; + reference1.OffsetBy(10, 20); + + SimpleTransform specimen; + specimen.AddOffset(10.0, 20.0); + specimen.Apply(®ion); + CPPUNIT_ASSERT(region == reference1); + + specimen.SetScale(2.5); + + BRegion reference2; + reference2.Include(BRect(47.0, 82.0, 87.0, 122.0)); + reference2.Include(BRect(60.0, 95.0, 112.0, 147.0)); + reference2.Exclude(BRect(60.0, 120.0, 86.0, 134.0)); + + specimen.Apply(®ion); + CPPUNIT_ASSERT(region == reference2); +} + + +void +SimpleTransformTest::TransformGradientLinear() +{ + BGradientLinear gradient(10.0, 20.0, 30.0, 40.0); + SimpleTransform specimen; + specimen.AddOffset(10.0, 20.0); + specimen.SetScale(2.5); + specimen.Apply(&gradient); + CPPUNIT_ASSERT(gradient.Start() == BPoint(35.0, 70.0)); + CPPUNIT_ASSERT(gradient.End() == BPoint(85.0, 120.0)); +} + + +void +SimpleTransformTest::TransformGradientRadial() +{ + BGradientRadial gradient(10.0, 20.0, 10.0); + SimpleTransform specimen; + specimen.AddOffset(10.0, 20.0); + specimen.SetScale(2.5); + specimen.Apply(&gradient); + CPPUNIT_ASSERT(gradient.Center() == BPoint(35.0, 70.0)); +} + + +void +SimpleTransformTest::TransformGradientRadialFocus() +{ + BGradientRadialFocus gradient(10.0, 20.0, 10.0, 30.0, 40.0); + SimpleTransform specimen; + specimen.AddOffset(10.0, 20.0); + specimen.SetScale(2.5); + specimen.Apply(&gradient); + CPPUNIT_ASSERT(gradient.Center() == BPoint(35.0, 70.0)); + CPPUNIT_ASSERT(gradient.Focal() == BPoint(85.0, 120.0)); +} + + +void +SimpleTransformTest::TransformGradientDiamond() +{ + BGradientDiamond gradient(10.0, 20.0); + SimpleTransform specimen; + specimen.AddOffset(10.0, 20.0); + specimen.SetScale(2.5); + specimen.Apply(&gradient); + CPPUNIT_ASSERT(gradient.Center() == BPoint(35.0, 70.0)); +} + + +void +SimpleTransformTest::TransformGradientConic() +{ + BGradientConic gradient(10.0, 20.0, 10.0); + SimpleTransform specimen; + specimen.AddOffset(10.0, 20.0); + specimen.SetScale(2.5); + specimen.Apply(&gradient); + CPPUNIT_ASSERT(gradient.Center() == BPoint(35.0, 70.0)); +} + + +void +SimpleTransformTest::TransformPointArray() +{ + BPoint points[3]; + points[0].Set(10.0, 20.0); + points[1].Set(30.0, 40.0); + points[2].Set(50.0, 60.0); + BPoint transformedPoints[3]; + SimpleTransform specimen; + specimen.AddOffset(10.0, 20.0); + specimen.Apply(&transformedPoints[0], &points[0], 3); + CPPUNIT_ASSERT(transformedPoints[0] == BPoint(20.0, 40.0)); + CPPUNIT_ASSERT(transformedPoints[1] == BPoint(40.0, 60.0)); + CPPUNIT_ASSERT(transformedPoints[2] == BPoint(60.0, 80.0)); +} + + +void +SimpleTransformTest::TransformRectArray() +{ + BRect rects[3]; + rects[0].Set( 5.0, 10.0, 15.0, 20.0); + rects[1].Set(15.0, 20.0, 25.0, 30.0); + rects[2].Set(25.0, 30.0, 35.0, 40.0); + BRect transformedRects[3]; + SimpleTransform specimen; + specimen.AddOffset(10.0, 20.0); + specimen.SetScale(2.5); + specimen.Apply(&transformedRects[0], &rects[0], 3); + CPPUNIT_ASSERT(transformedRects[0] == BRect(22.5, 45.0, 47.5, 70.0)); + CPPUNIT_ASSERT(transformedRects[1] == BRect(47.5, 70.0, 72.5, 95.0)); + CPPUNIT_ASSERT(transformedRects[2] == BRect(72.5, 95.0, 97.5, 120.0)); +} + + +void +SimpleTransformTest::TransformRegionArray() +{ + BRegion regions[2]; + regions[0].Include(BRect( 5.0, 5.0, 20.0, 20.0)); + regions[0].Include(BRect(10.0, 10.0, 30.0, 30.0)); + regions[0].Exclude(BRect(10.0, 20.0, 20.0, 25.0)); + regions[1].Include(BRect( 5.0, 5.0, 20.0, 20.0)); + regions[1].Include(BRect(10.0, 10.0, 30.0, 30.0)); + regions[1].Exclude(BRect(10.0, 20.0, 20.0, 25.0)); + BRegion transformedRegions[3]; + SimpleTransform specimen; + specimen.AddOffset(10.0, 20.0); + specimen.SetScale(2.5); + specimen.Apply(&transformedRegions[0], ®ions[0], 2); + BRegion reference; + reference.Include(BRect(22.0, 32.0, 62.0, 72.0)); + reference.Include(BRect(35.0, 45.0, 87.0, 97.0)); + reference.Exclude(BRect(35.0, 70.0, 61.0, 84.0)); + + CPPUNIT_ASSERT(transformedRegions[0] == reference); + CPPUNIT_ASSERT(transformedRegions[1] == reference); +} + + +/* static */ void +SimpleTransformTest::AddTests(BTestSuite& parent) +{ + CppUnit::TestSuite* const suite = new CppUnit::TestSuite( + "SimpleTransformTest"); + + suite->addTest(new CppUnit::TestCaller( + "SimpleTransformTest::TransformPoint", + &SimpleTransformTest::TransformPoint)); + suite->addTest(new CppUnit::TestCaller( + "SimpleTransformTest::TransformIntPoint", + &SimpleTransformTest::TransformIntPoint)); + suite->addTest(new CppUnit::TestCaller( + "SimpleTransformTest::TransformRect", + &SimpleTransformTest::TransformRect)); + suite->addTest(new CppUnit::TestCaller( + "SimpleTransformTest::TransformIntRect", + &SimpleTransformTest::TransformIntRect)); + suite->addTest(new CppUnit::TestCaller( + "SimpleTransformTest::TransformRegion", + &SimpleTransformTest::TransformRegion)); + suite->addTest(new CppUnit::TestCaller( + "SimpleTransformTest::TransformGradientLinear", + &SimpleTransformTest::TransformGradientLinear)); + suite->addTest(new CppUnit::TestCaller( + "SimpleTransformTest::TransformGradientRadial", + &SimpleTransformTest::TransformGradientRadial)); + suite->addTest(new CppUnit::TestCaller( + "SimpleTransformTest::TransformGradientRadialFocus", + &SimpleTransformTest::TransformGradientRadialFocus)); + suite->addTest(new CppUnit::TestCaller( + "SimpleTransformTest::TransformGradientDiamond", + &SimpleTransformTest::TransformGradientDiamond)); + suite->addTest(new CppUnit::TestCaller( + "SimpleTransformTest::TransformGradientConic", + &SimpleTransformTest::TransformGradientConic)); + suite->addTest(new CppUnit::TestCaller( + "SimpleTransformTest::TransformPointArray", + &SimpleTransformTest::TransformPointArray)); + suite->addTest(new CppUnit::TestCaller( + "SimpleTransformTest::TransformRectArray", + &SimpleTransformTest::TransformRectArray)); + suite->addTest(new CppUnit::TestCaller( + "SimpleTransformTest::TransformRegionArray", + &SimpleTransformTest::TransformRegionArray)); + + parent.addTest("SimpleTransformTest", suite); +} diff --git a/src/tests/servers/app/unit_tests/SimpleTransformTest.h b/src/tests/servers/app/unit_tests/SimpleTransformTest.h new file mode 100644 index 0000000000..89a889fd46 --- /dev/null +++ b/src/tests/servers/app/unit_tests/SimpleTransformTest.h @@ -0,0 +1,36 @@ +/* + * Copyright 2015 Julian Harnath + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef SIMPLE_TRANSFORM_TEST_H +#define SIMPLE_TRANSFORM_TEST_H + +#include +#include + +#include "SimpleTransform.h" + + +class SimpleTransformTest : public BTestCase { +public: + static void AddTests(BTestSuite& parent); + + void TransformPoint(); + void TransformIntPoint(); + void TransformRect(); + void TransformIntRect(); + void TransformRegion(); + + void TransformGradientLinear(); + void TransformGradientRadial(); + void TransformGradientRadialFocus(); + void TransformGradientDiamond(); + void TransformGradientConic(); + + void TransformPointArray(); + void TransformRectArray(); + void TransformRegionArray(); +}; + + +#endif // SIMPLE_TRANSFORM_TEST_H From ccaee9e818cc4ef94f313aa47a0b6c18ff580f57 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Wed, 8 Jul 2015 20:07:51 +0200 Subject: [PATCH 004/370] app_server: add Squash method in DrawState * New method DrawState::Squash() uses the combined scale, origin and transform as the state's own scale, origin, transform. This can be used when making copies of DrawStates which have previous states below them in the state stack. The top of stack DrawState can be copied, squashed and then used just like the original one with the whole stack below it (except of course when trying to pop off any earlier state). --- src/servers/app/DrawState.cpp | 13 +++++++++++++ src/servers/app/DrawState.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/src/servers/app/DrawState.cpp b/src/servers/app/DrawState.cpp index d7f88bc922..9621cfa68e 100644 --- a/src/servers/app/DrawState.cpp +++ b/src/servers/app/DrawState.cpp @@ -370,6 +370,19 @@ DrawState::SetTransform(BAffineTransform transform) } +DrawState* +DrawState::Squash() +{ + DrawState* const squashedState = new DrawState(*this); + + squashedState->fOrigin = fCombinedOrigin; + squashedState->fScale = fCombinedScale; + squashedState->fTransform = fCombinedTransform; + + return squashedState; +} + + void DrawState::SetClippingRegion(const BRegion* region) { diff --git a/src/servers/app/DrawState.h b/src/servers/app/DrawState.h index 392549789f..48a6f371c6 100644 --- a/src/servers/app/DrawState.h +++ b/src/servers/app/DrawState.h @@ -69,6 +69,8 @@ public: BAffineTransform CombinedTransform() const { return fCombinedTransform; } + DrawState* Squash(); + // additional clipping as requested by client void SetClippingRegion(const BRegion* region); From 1b4dba929dd35c7aeaa92673efd63dbfc665c8e0 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Wed, 8 Jul 2015 20:17:04 +0200 Subject: [PATCH 005/370] app_server: add picture player for determining bounding box * Add PictureBoundingBoxPlayer, a new player for BPictures. Instead of drawing the picture, it determines an approximate bounding box of its contained drawing operations. * To increase performance, the resulting bounding box is an approximation: it guarantees to always enclose all pixels of the picture, however not necessarily tightly. * PictureBoundingBoxPlayer::Play() gets a DrawState which is the initial state used when playing the picture. The player does not modify this state (it uses a copy internally), so the method is idempotent. --- src/servers/app/Jamfile | 1 + src/servers/app/PictureBoundingBoxPlayer.cpp | 778 +++++++++++++++++++ src/servers/app/PictureBoundingBoxPlayer.h | 28 + 3 files changed, 807 insertions(+) create mode 100644 src/servers/app/PictureBoundingBoxPlayer.cpp create mode 100644 src/servers/app/PictureBoundingBoxPlayer.h diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index aebc6c8580..fdaea83c7e 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -71,6 +71,7 @@ Server app_server : MultiLocker.cpp OffscreenServerWindow.cpp OffscreenWindow.cpp + PictureBoundingBoxPlayer.cpp ProfileMessageSupport.cpp RGBColor.cpp RegionPool.cpp diff --git a/src/servers/app/PictureBoundingBoxPlayer.cpp b/src/servers/app/PictureBoundingBoxPlayer.cpp new file mode 100644 index 0000000000..08ff0f7f0d --- /dev/null +++ b/src/servers/app/PictureBoundingBoxPlayer.cpp @@ -0,0 +1,778 @@ +/* + * Copyright 2001-2015, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Marc Flerackers (mflerackers@androme.be) + * Stefano Ceccherini (stefano.ceccherini@gmail.com) + * Marcus Overhagen + * Julian Harnath + */ + +#include "PictureBoundingBoxPlayer.h" + +#include +#include + +#include "DrawState.h" +#include "FontManager.h" +#include "ServerApp.h" +#include "ServerBitmap.h" +#include "ServerFont.h" +#include "ServerPicture.h" +#include "ServerTokenSpace.h" +#include "View.h" +#include "Window.h" + +#include +#include +#include +#include +#include +#include +#include + + +//#define DEBUG_TRACE_BB +#ifdef DEBUG_TRACE_BB +# define TRACE_BB(text, ...) debug_printf("PBBP: " text, ##__VA_ARGS__) +#else +# define TRACE_BB(text, ...) +#endif + + +typedef PictureBoundingBoxPlayer::State BoundingBoxState; + + +// #pragma mark - PictureBoundingBoxPlayer::State + + +class PictureBoundingBoxPlayer::State { +public: + State(DrawState* drawState, BRect* boundingBox) + : + fDrawState(drawState->Squash()), + fBoundingBox(boundingBox) + { + fBoundingBox->Set(INT_MAX, INT_MAX, 0, 0); + } + + ~State() + { + delete fDrawState; + } + + DrawState* GetDrawState() + { + return fDrawState; + } + + void PushDrawState() + { + DrawState* nextState = fDrawState->PushState(); + if (nextState != NULL) + fDrawState = nextState; + } + + void PopDrawState() + { + if (fDrawState->PreviousState() != NULL) + fDrawState = fDrawState->PopState(); + } + + SimpleTransform PenToLocalTransform() const + { + SimpleTransform transform; + fDrawState->Transform(transform); + return transform; + } + + void IncludeRect(BRect& rect) + { + _AffineTransformRect(rect); + *fBoundingBox = (*fBoundingBox) | rect; + } + +private: + void _AffineTransformRect(BRect& rect) + { + BAffineTransform transform = fDrawState->Transform(); + if (transform.IsIdentity()) + return; + + BPoint transformedShape[4]; + transformedShape[0] = rect.LeftTop(); + transformedShape[1] = rect.LeftBottom(); + transformedShape[2] = rect.RightTop(); + transformedShape[3] = rect.RightBottom(); + + transform.Apply(&transformedShape[0], 4); + + float minX = INT_MAX; + float minY = INT_MAX; + float maxX = 0; + float maxY = 0; + + for (uint32 i = 0; i < 4; i++) { + if (transformedShape[i].x < minX) + minX = transformedShape[i].x; + else if (transformedShape[i].x > maxX) + maxX = transformedShape[i].x; + if (transformedShape[i].y < minY) + minY = transformedShape[i].y; + else if (transformedShape[i].y > maxY) + maxY = transformedShape[i].y; + } + + rect.Set(minX, minY, maxX, maxY); + } + + +private: + DrawState* fDrawState; + BRect* fBoundingBox; +}; + + +// #pragma mark - Picture playback hooks + + +static void +get_polygon_frame(const BPoint* points, int32 numPoints, BRect* frame) +{ + ASSERT(numPoints > 0); + + float left = points->x; + float top = points->y; + float right = left; + float bottom = top; + + points++; + numPoints--; + + while (numPoints--) { + if (points->x < left) + left = points->x; + if (points->x > right) + right = points->x; + if (points->y < top) + top = points->y; + if (points->y > bottom) + bottom = points->y; + points++; + } + + frame->Set(left, top, right, bottom); +} + + +template +static void +expand_rect_for_pen_size(BoundingBoxState* state, RectType& rect) +{ + float penInset = -((state->GetDrawState()->PenSize() / 2.0f) + 1.0f); + rect.InsetBy(penInset, penInset); +} + + +static void +nop() +{ +} + + +static void +move_pen_by(BoundingBoxState* state, BPoint delta) +{ + TRACE_BB("%p move pen by %.2f %.2f\n", state, delta.x, delta.y); + + state->GetDrawState()->SetPenLocation( + state->GetDrawState()->PenLocation() + delta); +} + + +static void +determine_bounds_stroke_line(BoundingBoxState* state, BPoint start, BPoint end) +{ + TRACE_BB("%p stroke line %.2f %.2f -> %.2f %.2f\n", state, + start.x, start.y, end.x, end.y); + + BPoint penPos = end; + + const SimpleTransform transform = state->PenToLocalTransform(); + transform.Apply(&start); + transform.Apply(&end); + + BRect rect; + if (start.x <= end.x) { + rect.left = start.x; + rect.right = end.x; + } else { + rect.left = end.x; + rect.right = start.x; + } + if (start.y <= end.y) { + rect.top = start.y; + rect.bottom = end.y; + } else { + rect.top = end.y; + rect.bottom = start.y; + } + + expand_rect_for_pen_size(state, rect); + state->IncludeRect(rect); + + state->GetDrawState()->SetPenLocation(penPos); +} + + +static void +determine_bounds_stroke_rect(BoundingBoxState* state, BRect rect) +{ + TRACE_BB("%p stroke rect %.2f %.2f %.2f %.2f\n", state, + rect.left, rect.top, rect.right, rect.bottom); + + state->PenToLocalTransform().Apply(&rect); + expand_rect_for_pen_size(state, rect); + state->IncludeRect(rect); +} + + +static void +determine_bounds_fill_rect(BoundingBoxState* state, BRect rect) +{ + TRACE_BB("%p fill rect %.2f %.2f %.2f %.2f\n", state, + rect.left, rect.top, rect.right, rect.bottom); + + state->PenToLocalTransform().Apply(&rect); + state->IncludeRect(rect); +} + + +static void +determine_bounds_bezier(BoundingBoxState* state, const BPoint* viewPoints, + BRect& outRect) +{ + // Note: this is an approximation which results in a rectangle which + // encloses all four control points. That will always enclose the curve, + // although not necessarily tightly, but it's good enough for the purpose. + // The exact bounding box of a bezier curve is not trivial to determine, + // (need to calculate derivative of the curve) and we're going for + // performance here. + BPoint points[4]; + state->PenToLocalTransform().Apply(points, viewPoints, 4); + BPoint topLeft = points[0]; + BPoint bottomRight = points[0]; + for (uint32 index = 1; index < 4; index++) { + if (points[index].x < topLeft.x || points[index].y < topLeft.y) + topLeft = points[index]; + if (points[index].x > topLeft.x || points[index].y > topLeft.y) + bottomRight = points[index]; + } + outRect.SetLeftTop(topLeft); + outRect.SetRightBottom(bottomRight); +} + + +static void +determine_bounds_stroke_bezier(BoundingBoxState* state, const BPoint* viewPoints) +{ + TRACE_BB("%p stroke bezier (%.2f %.2f) (%.2f %.2f) (%.2f %.2f) (%.2f %.2f)\n", + state, + viewPoints[0].x, viewPoints[0].y, + viewPoints[1].x, viewPoints[1].y, + viewPoints[2].x, viewPoints[2].y, + viewPoints[3].x, viewPoints[3].y); + + BRect rect; + determine_bounds_bezier(state, viewPoints, rect); + expand_rect_for_pen_size(state, rect); + state->IncludeRect(rect); +} + + +static void +determine_bounds_fill_bezier(BoundingBoxState* state, const BPoint* viewPoints) +{ + TRACE_BB("%p fill bezier (%.2f %.2f) (%.2f %.2f) (%.2f %.2f) (%.2f %.2f)\n", + state, + viewPoints[0].x, viewPoints[0].y, + viewPoints[1].x, viewPoints[1].y, + viewPoints[2].x, viewPoints[2].y, + viewPoints[3].x, viewPoints[3].y); + + BRect rect; + determine_bounds_bezier(state, viewPoints, rect); + state->IncludeRect(rect); +} + + + +static void +determine_bounds_stroke_ellipse(BoundingBoxState* state, BPoint center, BPoint radii) +{ + TRACE_BB("%p stroke ellipse (%.2f %.2f) (%.2f %.2f)\n", state, + center.x, center.y, radii.x, radii.y); + + BRect rect(center.x - radii.x, center.y - radii.y, + center.x + radii.x - 1, center.y + radii.y - 1); + state->PenToLocalTransform().Apply(&rect); + expand_rect_for_pen_size(state, rect); + state->IncludeRect(rect); +} + + +static void +determine_bounds_fill_ellipse(BoundingBoxState* state, BPoint center, BPoint radii) +{ + TRACE_BB("%p fill ellipse (%.2f %.2f) (%.2f %.2f)\n", state, + center.x, center.y, radii.x, radii.y); + + BRect rect(center.x - radii.x, center.y - radii.y, + center.x + radii.x - 1, center.y + radii.y - 1); + + TRACE_BB(" --> (%.2f %.2f %.2f %.2f)\n", + rect.left, rect.top, rect.right, rect.bottom); + + state->PenToLocalTransform().Apply(&rect); + state->IncludeRect(rect); +} + + +static void +determine_bounds_polygon(BoundingBoxState* state, int32 numPoints, + const BPoint* viewPoints, BRect& outRect) +{ + if (numPoints <= 0) + return; + + if (numPoints <= 200) { + // fast path: no malloc/free, also avoid + // constructor/destructor calls + char data[200 * sizeof(BPoint)]; + BPoint* points = (BPoint*)data; + + state->PenToLocalTransform().Apply(points, viewPoints, numPoints); + get_polygon_frame(points, numPoints, &outRect); + + } else { + // avoid constructor/destructor calls by + // using malloc instead of new [] + BPoint* points = (BPoint*)malloc(numPoints * sizeof(BPoint)); + if (points == NULL) + return; + + state->PenToLocalTransform().Apply(points, viewPoints, numPoints); + get_polygon_frame(points, numPoints, &outRect); + + free(points); + } +} + + +void +determine_bounds_stroke_polygon(BoundingBoxState* state, int32 numPoints, + const BPoint* viewPoints, bool) +{ + TRACE_BB("%p stroke polygon (%ld points)\n", state, numPoints); + + BRect rect; + determine_bounds_polygon(state, numPoints, viewPoints, rect); + expand_rect_for_pen_size(state, rect); + state->IncludeRect(rect); +} + + +void +determine_bounds_fill_polygon(BoundingBoxState* state, int32 numPoints, + const BPoint* viewPoints, bool) +{ + TRACE_BB("%p fill polygon (%ld points)\n", state, numPoints); + + BRect rect; + determine_bounds_polygon(state, numPoints, viewPoints, rect); + state->IncludeRect(rect); +} + + +static void +determine_bounds_stroke_shape(BoundingBoxState* state, const BShape* shape) +{ + BRect rect = shape->Bounds(); + + TRACE_BB("%p stroke shape (bounds %.2f %.2f %.2f %.2f)\n", state, + rect.left, rect.top, rect.right, rect.bottom); + + state->PenToLocalTransform().Apply(&rect); + expand_rect_for_pen_size(state, rect); + state->IncludeRect(rect); +} + + +static void +determine_bounds_fill_shape(BoundingBoxState* state, const BShape* shape) +{ + BRect rect = shape->Bounds(); + + TRACE_BB("%p fill shape (bounds %.2f %.2f %.2f %.2f)\n", state, + rect.left, rect.top, rect.right, rect.bottom); + + state->PenToLocalTransform().Apply(&rect); + state->IncludeRect(rect); +} + + +static void +determine_bounds_string(BoundingBoxState* state, const char* string, float deltaSpace, + float deltaNonSpace) +{ + TRACE_BB("%p string '%s'\n", state, string); + + ServerFont font = state->GetDrawState()->Font(); + + escapement_delta delta = { deltaSpace, deltaNonSpace }; + BRect rect; + int32 length = strlen(string); + font.GetBoundingBoxesForStrings((char**)&string, &length, 1, &rect, + B_SCREEN_METRIC, &delta); + + BPoint location = state->GetDrawState()->PenLocation(); + + state->PenToLocalTransform().Apply(&location); + rect.OffsetBy(location); + state->IncludeRect(rect); + + state->PenToLocalTransform().Apply(&location); + state->GetDrawState()->SetPenLocation(location); +} + + +static void +determine_bounds_pixels(BoundingBoxState* state, BRect, BRect dest, int32 w, int32 h, + int32 bpr, int32 pf, int32, const void*) +{ + TRACE_BB("%p pixels (dest %.2f %.2f %.2f %.2f) w=%ld h=%ld bpr=%ld pf=%ld\n", state, + dest.left, dest.top, dest.right, dest.bottom, + w, h, bpr, pf); + // TODO remove params + + state->PenToLocalTransform().Apply(&dest); + state->IncludeRect(dest); +} + + +static void +draw_picture(BoundingBoxState* state, BPoint where, int32 token) +{ + TRACE_BB("%p picture (unimplemented)\n", state); + + // TODO + (void)state; + (void)where; + (void)token; +} + + +static void +set_clipping_rects(BoundingBoxState* state, const BRect* rects, + uint32 numRects) +{ + TRACE_BB("%p cliping rects (%ld rects)\n", state, numRects); + + // TODO + (void)state; + (void)rects; + (void)numRects; +} + + +static void +clip_to_picture(BoundingBoxState* state, BPicture* picture, BPoint pt, + bool clipToInverse) +{ + TRACE_BB("%p clip to picture (unimplemented)\n", state); + + // TODO + printf("ClipToPicture(picture, BPoint(%.2f, %.2f), %s)\n", + pt.x, pt.y, clipToInverse ? "inverse" : ""); +} + + +static void +push_state(BoundingBoxState* state) +{ + TRACE_BB("%p push state\n", state); + state->PushDrawState(); +} + + +static void +pop_state(BoundingBoxState* state) +{ + TRACE_BB("%p pop state\n", state); + state->PopDrawState(); +} + + +static void +enter_state_change(BoundingBoxState*) +{ +} + + +static void +exit_state_change(BoundingBoxState*) +{ +} + + +static void +enter_font_state(BoundingBoxState*) +{ +} + + +static void +exit_font_state(BoundingBoxState*) +{ +} + + +static void +set_origin(BoundingBoxState* state, BPoint pt) +{ + TRACE_BB("%p set origin %.2f %.2f\n", state, pt.x, pt.y); + state->GetDrawState()->SetOrigin(pt); +} + + +static void +set_pen_location(BoundingBoxState* state, BPoint pt) +{ + TRACE_BB("%p set pen location %.2f %.2f\n", state, pt.x, pt.y); + state->GetDrawState()->SetPenLocation(pt); +} + + +static void +set_drawing_mode(BoundingBoxState*, drawing_mode) +{ +} + + +static void +set_line_mode(BoundingBoxState* state, cap_mode capMode, join_mode joinMode, + float miterLimit) +{ + DrawState* drawState = state->GetDrawState(); + drawState->SetLineCapMode(capMode); + drawState->SetLineJoinMode(joinMode); + drawState->SetMiterLimit(miterLimit); +} + + +static void +set_pen_size(BoundingBoxState* state, float size) +{ + TRACE_BB("%p set pen size %.2f\n", state, size); + state->GetDrawState()->SetPenSize(size); +} + + +static void +set_fore_color(BoundingBoxState* state, rgb_color color) +{ + state->GetDrawState()->SetHighColor(color); +} + + +static void +set_back_color(BoundingBoxState* state, rgb_color color) +{ + state->GetDrawState()->SetLowColor(color); +} + + +static void +set_stipple_pattern(BoundingBoxState* state, pattern p) +{ + state->GetDrawState()->SetPattern(Pattern(p)); +} + + +static void +set_scale(BoundingBoxState* state, float scale) +{ + state->GetDrawState()->SetScale(scale); +} + + +static void +set_font_family(BoundingBoxState* state, const char* family) +{ + FontStyle* fontStyle = gFontManager->GetStyleByIndex(family, 0); + ServerFont font; + font.SetStyle(fontStyle); + state->GetDrawState()->SetFont(font, B_FONT_FAMILY_AND_STYLE); +} + + +static void +set_font_style(BoundingBoxState* state, const char* style) +{ + ServerFont font(state->GetDrawState()->Font()); + FontStyle* fontStyle = gFontManager->GetStyle(font.Family(), style); + font.SetStyle(fontStyle); + state->GetDrawState()->SetFont(font, B_FONT_FAMILY_AND_STYLE); +} + + +static void +set_font_spacing(BoundingBoxState* state, int32 spacing) +{ + ServerFont font; + font.SetSpacing(spacing); + state->GetDrawState()->SetFont(font, B_FONT_SPACING); +} + + +static void +set_font_size(BoundingBoxState* state, float size) +{ + ServerFont font; + font.SetSize(size); + state->GetDrawState()->SetFont(font, B_FONT_SIZE); +} + + +static void +set_font_rotate(BoundingBoxState* state, float rotation) +{ + ServerFont font; + font.SetRotation(rotation); + state->GetDrawState()->SetFont(font, B_FONT_ROTATION); +} + + +static void +set_font_encoding(BoundingBoxState* state, int32 encoding) +{ + ServerFont font; + font.SetEncoding(encoding); + state->GetDrawState()->SetFont(font, B_FONT_ENCODING); +} + + +static void +set_font_flags(BoundingBoxState* state, int32 flags) +{ + ServerFont font; + font.SetFlags(flags); + state->GetDrawState()->SetFont(font, B_FONT_FLAGS); +} + + +static void +set_font_shear(BoundingBoxState* state, float shear) +{ + ServerFont font; + font.SetShear(shear); + state->GetDrawState()->SetFont(font, B_FONT_SHEAR); +} + + +static void +set_font_face(BoundingBoxState* state, int32 face) +{ + ServerFont font; + font.SetFace(face); + state->GetDrawState()->SetFont(font, B_FONT_FACE); +} + + +static void +set_blending_mode(BoundingBoxState*, int16, int16) +{ +} + + +static void +set_transform(BoundingBoxState* state, BAffineTransform transform) +{ + TRACE_BB("%p transform\n", state); + state->GetDrawState()->SetTransform(transform); +} + + +const static void* kTableEntries[] = { + (const void*)nop, // 0 + (const void*)move_pen_by, + (const void*)determine_bounds_stroke_line, + (const void*)determine_bounds_stroke_rect, + (const void*)determine_bounds_fill_rect, + (const void*)determine_bounds_stroke_rect, // 5 + (const void*)determine_bounds_fill_rect, + (const void*)determine_bounds_stroke_bezier, + (const void*)determine_bounds_fill_bezier, + (const void*)determine_bounds_stroke_ellipse, + (const void*)determine_bounds_fill_ellipse, // 10 + (const void*)determine_bounds_stroke_ellipse, + (const void*)determine_bounds_fill_ellipse, + (const void*)determine_bounds_stroke_polygon, + (const void*)determine_bounds_fill_polygon, + (const void*)determine_bounds_stroke_shape, // 15 + (const void*)determine_bounds_fill_shape, + (const void*)determine_bounds_string, + (const void*)determine_bounds_pixels, + (const void*)draw_picture, + (const void*)set_clipping_rects, // 20 + (const void*)clip_to_picture, + (const void*)push_state, + (const void*)pop_state, + (const void*)enter_state_change, + (const void*)exit_state_change, // 25 + (const void*)enter_font_state, + (const void*)exit_font_state, + (const void*)set_origin, + (const void*)set_pen_location, + (const void*)set_drawing_mode, // 30 + (const void*)set_line_mode, + (const void*)set_pen_size, + (const void*)set_fore_color, + (const void*)set_back_color, + (const void*)set_stipple_pattern, // 35 + (const void*)set_scale, + (const void*)set_font_family, + (const void*)set_font_style, + (const void*)set_font_spacing, + (const void*)set_font_size, // 40 + (const void*)set_font_rotate, + (const void*)set_font_encoding, + (const void*)set_font_flags, + (const void*)set_font_shear, + (const void*)nop, // 45 + (const void*)set_font_face, + (const void*)set_blending_mode, + (const void*)set_transform // 48 +}; + + +// #pragma mark - PictureBoundingBoxPlayer + + +/* static */ void +PictureBoundingBoxPlayer::Play(ServerPicture* picture, + DrawState* drawState, BRect* outBoundingBox) +{ + State state(drawState, outBoundingBox); + + BMallocIO* mallocIO = dynamic_cast(picture->fData); + if (mallocIO == NULL) + return; + + BPrivate::PicturePlayer player(mallocIO->Buffer(), + mallocIO->BufferLength(), ServerPicture::PictureList::Private( + picture->fPictures).AsBList()); + player.Play(const_cast(kTableEntries), + sizeof(kTableEntries) / sizeof(void*), &state); +} diff --git a/src/servers/app/PictureBoundingBoxPlayer.h b/src/servers/app/PictureBoundingBoxPlayer.h new file mode 100644 index 0000000000..37ae88e2c3 --- /dev/null +++ b/src/servers/app/PictureBoundingBoxPlayer.h @@ -0,0 +1,28 @@ +/* + * Copyright 2015, Haiku. + * Distributed under the terms of the MIT license. + * + * Authors: + * Julian Harnath + */ +#ifndef PICTURE_BOUNDING_BOX_H +#define PICTURE_BOUNDING_BOX_H + + +class BRect; +class DrawState; +class ServerPicture; + + +class PictureBoundingBoxPlayer { +public: + class State; + +public: + static void Play(ServerPicture* picture, + DrawState* drawState, + BRect* outBoundingBox); +}; + + +#endif // PICTURE_BOUNDING_BOX_H From 8511f6ac9b4db63e490538fa7d0248ff0e0d5924 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Wed, 8 Jul 2015 20:54:56 +0200 Subject: [PATCH 006/370] app_server: fix ServerPicture::SyncState pen size * Should use the unscaled pen size here because we also write down the current scale, and we don't want to scale the pen twice. --- src/servers/app/ServerPicture.cpp | 2 +- src/servers/app/ServerPicture.h | 2 ++ src/tests/servers/app/Jamfile | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index d03ddb29e3..b59a61701a 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -978,7 +978,7 @@ ServerPicture::SyncState(View* view) WriteSetOrigin(view->CurrentState()->Origin()); WriteSetPenLocation(view->CurrentState()->PenLocation()); - WriteSetPenSize(view->CurrentState()->PenSize()); + WriteSetPenSize(view->CurrentState()->UnscaledPenSize()); WriteSetScale(view->CurrentState()->Scale()); WriteSetLineMode(view->CurrentState()->LineCapMode(), view->CurrentState()->LineJoinMode(), diff --git a/src/servers/app/ServerPicture.h b/src/servers/app/ServerPicture.h index f559b45b59..5b008e22d9 100644 --- a/src/servers/app/ServerPicture.h +++ b/src/servers/app/ServerPicture.h @@ -63,6 +63,8 @@ public: status_t ExportData(BPrivate::PortLink& link); private: + friend class PictureBoundingBoxPlayer; + typedef BObjectList PictureList; int32 fToken; diff --git a/src/tests/servers/app/Jamfile b/src/tests/servers/app/Jamfile index f3e3ac340d..73d8b98009 100644 --- a/src/tests/servers/app/Jamfile +++ b/src/tests/servers/app/Jamfile @@ -156,6 +156,7 @@ SharedLibrary libtestappserver.so : DesktopSettings.cpp OffscreenServerWindow.cpp OffscreenWindow.cpp + PictureBoundingBoxPlayer.cpp RegionPool.cpp Screen.cpp ScreenConfigurations.cpp From ae0468762f2ff1f11bb575f40184fdb90d398dd9 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Wed, 8 Jul 2015 21:16:30 +0200 Subject: [PATCH 007/370] app_server: add Canvas::PenToLocalTransform --- src/servers/app/Canvas.cpp | 12 +++++++++++- src/servers/app/Canvas.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/servers/app/Canvas.cpp b/src/servers/app/Canvas.cpp index 4fd87a0322..729a160ff4 100644 --- a/src/servers/app/Canvas.cpp +++ b/src/servers/app/Canvas.cpp @@ -188,6 +188,17 @@ Canvas::PenToScreenTransform() const GCC_2_NRV(transform) } +SimpleTransform +Canvas::PenToLocalTransform() const GCC_2_NRV(transform) +{ +#if __GNUC__ >= 3 + SimpleTransform transform; +#endif + fDrawState->Transform(transform); + return transform; +} + + SimpleTransform Canvas::ScreenToPenTransform() const GCC_2_NRV(transform) { @@ -218,4 +229,3 @@ OffscreenCanvas::ResyncDrawState() { fDrawingEngine->SetDrawState(fDrawState); } - diff --git a/src/servers/app/Canvas.h b/src/servers/app/Canvas.h index acb52d09e5..8bc799aae3 100644 --- a/src/servers/app/Canvas.h +++ b/src/servers/app/Canvas.h @@ -57,6 +57,7 @@ public: SimpleTransform LocalToScreenTransform() const; SimpleTransform ScreenToLocalTransform() const; SimpleTransform PenToScreenTransform() const; + SimpleTransform PenToLocalTransform() const; SimpleTransform ScreenToPenTransform() const; virtual DrawingEngine* GetDrawingEngine() const = 0; From c34cbf2878cb39d46bad3de00d17e60bf502d750 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Wed, 8 Jul 2015 21:22:25 +0200 Subject: [PATCH 008/370] app_server: fix PicturePlayer dummy function table * With the support for BAffineTransform, it needs to have 49 entries --- src/kits/interface/PicturePlayer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/kits/interface/PicturePlayer.cpp b/src/kits/interface/PicturePlayer.cpp index f337bc1896..ed2f13c546 100644 --- a/src/kits/interface/PicturePlayer.cpp +++ b/src/kits/interface/PicturePlayer.cpp @@ -159,7 +159,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, - (void *)nop, (void *)nop, (void *)nop, (void *)nop + (void *)nop, (void *)nop, (void *)nop, (void *)nop, + (void *)nop }; if ((uint32)tableEntries < kOpsTableSize) { From b5c7f936de1af0ce11e8257c4bba56c4a4e12f11 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Wed, 8 Jul 2015 21:27:24 +0200 Subject: [PATCH 009/370] app_server: allow replacing the DrawState in a Canvas * Needed for layers support. The previously set DrawState and its stack predecessors are not freed, so take care to not leak memory when using this. --- src/servers/app/Canvas.cpp | 7 +++++++ src/servers/app/Canvas.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/servers/app/Canvas.cpp b/src/servers/app/Canvas.cpp index 729a160ff4..89b100f9d6 100644 --- a/src/servers/app/Canvas.cpp +++ b/src/servers/app/Canvas.cpp @@ -88,6 +88,13 @@ Canvas::PopState() } +void +Canvas::SetDrawState(DrawState* newState) +{ + fDrawState = newState; +} + + void Canvas::SetDrawingOrigin(BPoint origin) { diff --git a/src/servers/app/Canvas.h b/src/servers/app/Canvas.h index 8bc799aae3..3744435187 100644 --- a/src/servers/app/Canvas.h +++ b/src/servers/app/Canvas.h @@ -41,6 +41,7 @@ public: virtual void PushState(); virtual void PopState(); DrawState* CurrentState() const { return fDrawState; } + void SetDrawState(DrawState* newState); void SetDrawingOrigin(BPoint origin); BPoint DrawingOrigin() const; From 65a54d2892d46ff6fb72d76390555de0d5d6dd96 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Tue, 21 Jul 2015 22:46:43 +0200 Subject: [PATCH 010/370] app_server: implement setting BAffineTransforms in BPicture * Add a simple callback for the picture command --- src/servers/app/ServerPicture.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index b59a61701a..f7f2babaad 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -1,11 +1,12 @@ /* - * Copyright 2001-2010, Haiku. + * Copyright 2001-2015, Haiku. * Distributed under the terms of the MIT License. * * Authors: * Marc Flerackers (mflerackers@androme.be) * Stefano Ceccherini (stefano.ceccherini@gmail.com) * Marcus Overhagen + * Julian Harnath */ #include "ServerPicture.h" @@ -372,6 +373,7 @@ fill_ellipse(Canvas* canvas, BPoint center, BPoint radii) { BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x - 1, center.y + radii.y - 1); + canvas->PenToScreenTransform().Apply(&rect); canvas->GetDrawingEngine()->DrawEllipse(rect, true); } @@ -775,6 +777,13 @@ set_blending_mode(Canvas* canvas, int16 alphaSrcMode, int16 alphaFncMode) } +static void +set_transform(Canvas* canvas, BAffineTransform transform) +{ + canvas->CurrentState()->SetTransform(transform); +} + + static void reserved() { @@ -787,7 +796,7 @@ const static void* kTableEntries[] = { (const void*)stroke_line, (const void*)stroke_rect, (const void*)fill_rect, - (const void*)stroke_round_rect, // 5 + (const void*)stroke_round_rect, // 5 (const void*)fill_round_rect, (const void*)stroke_bezier, (const void*)fill_bezier, @@ -807,7 +816,7 @@ const static void* kTableEntries[] = { (const void*)push_state, (const void*)pop_state, (const void*)enter_state_change, - (const void*)exit_state_change, // 25 + (const void*)exit_state_change, // 25 (const void*)enter_font_state, (const void*)exit_font_state, (const void*)set_origin, @@ -822,14 +831,15 @@ const static void* kTableEntries[] = { (const void*)set_font_family, (const void*)set_font_style, (const void*)set_font_spacing, - (const void*)set_font_size, // 40 + (const void*)set_font_size, // 40 (const void*)set_font_rotate, (const void*)set_font_encoding, (const void*)set_font_flags, (const void*)set_font_shear, (const void*)reserved, // 45 (const void*)set_font_face, - (const void*)set_blending_mode // 47 + (const void*)set_blending_mode, + (const void*)set_transform // 48 }; From edc0b5e9db34f77086d510fa7159d2daf22488aa Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Wed, 22 Jul 2015 21:01:19 +0200 Subject: [PATCH 011/370] app_server: allow disabling affine transforms in DrawState * New method DrawState::SetTransformEnabled allows to temporarily disable all BAffineTransforms in the state stack (up to 'this'). Later, the same method can be used to reenable the transforms. Needed for layers support: when drawing the finished layer bitmap onto the view, the affine transforms must not be applied again -- they have already been applied while drawing the bitmap's contents. --- src/servers/app/DrawState.cpp | 16 ++++++++++++++++ src/servers/app/DrawState.h | 1 + 2 files changed, 17 insertions(+) diff --git a/src/servers/app/DrawState.cpp b/src/servers/app/DrawState.cpp index 9621cfa68e..2eaa39f5de 100644 --- a/src/servers/app/DrawState.cpp +++ b/src/servers/app/DrawState.cpp @@ -370,6 +370,22 @@ DrawState::SetTransform(BAffineTransform transform) } +/* Can be used to temporarily disable all BAffineTransforms in the state + stack, and later reenable them. +*/ +void +DrawState::SetTransformEnabled(bool enabled) +{ + if (enabled) { + BAffineTransform temp = fTransform; + SetTransform(BAffineTransform()); + SetTransform(temp); + } + else + fCombinedTransform = BAffineTransform(); +} + + DrawState* DrawState::Squash() { diff --git a/src/servers/app/DrawState.h b/src/servers/app/DrawState.h index 48a6f371c6..e67e1ed2af 100644 --- a/src/servers/app/DrawState.h +++ b/src/servers/app/DrawState.h @@ -68,6 +68,7 @@ public: { return fTransform; } BAffineTransform CombinedTransform() const { return fCombinedTransform; } + void SetTransformEnabled(bool enabled); DrawState* Squash(); From 6ac468ef24f664699f674e5dd9b27d41be906d95 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Wed, 22 Jul 2015 21:26:49 +0200 Subject: [PATCH 012/370] app_server: add support for uniform opacity alpha masks * Another constructor for AlphaMask allows creating a mask with no picture, it will simply be a single uniform alpha value over the whole mask. * No need to even allocate a buffer in this case, we can just use the feature of clipped_alpha_mask to define an opacity for outside the mask, and set the buffer size to zero. --- src/servers/app/drawing/AlphaMask.cpp | 55 +++++++++++++++++++++++---- src/servers/app/drawing/AlphaMask.h | 12 +++++- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/servers/app/drawing/AlphaMask.cpp b/src/servers/app/drawing/AlphaMask.cpp index 2b744cd548..391c929466 100644 --- a/src/servers/app/drawing/AlphaMask.cpp +++ b/src/servers/app/drawing/AlphaMask.cpp @@ -1,10 +1,11 @@ /* - * Copyright 2014, Haiku, Inc. + * Copyright 2014-2015, Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: * Adrien Destugues * Stephan Aßmus + * Julian Harnath */ @@ -26,6 +27,7 @@ AlphaMask::AlphaMask(ServerPicture* picture, bool inverse, BPoint origin, fPicture(picture), fInverse(inverse), fOrigin(origin), + fBackgroundOpacity(0), fDrawState(drawState), fViewBounds(), @@ -43,9 +45,34 @@ AlphaMask::AlphaMask(ServerPicture* picture, bool inverse, BPoint origin, } +AlphaMask::AlphaMask(uint8 backgroundOpacity) + : + fPreviousMask(NULL), + + fPicture(NULL), + fInverse(false), + fOrigin(0, 0), + fBackgroundOpacity(backgroundOpacity), + fDrawState(), + + fViewBounds(), + fViewOffset(), + + fCachedBitmap(NULL), + fCachedBounds(), + fCachedOffset(), + + fBuffer(), + fCachedMask(), + fScanline(fCachedMask) +{ +} + + AlphaMask::~AlphaMask() { - fPicture->ReleaseReference(); + if (fPicture != NULL) + fPicture->ReleaseReference(); delete[] fCachedBitmap; SetPrevious(NULL); } @@ -81,7 +108,13 @@ AlphaMask::SetPrevious(AlphaMask* mask) scanline_unpacked_masked_type* AlphaMask::Generate() { - if (fPicture == NULL || !fViewBounds.IsValid()) + if (fPicture == NULL) { + fBuffer.attach(NULL, 0, 0, 0); + _AttachMaskToBuffer(); + return &fScanline; + } + + if (!fViewBounds.IsValid()) return NULL; // See if a cached bitmap can be used. Don't use it when the view offset @@ -162,9 +195,7 @@ AlphaMask::Generate() fCachedOffset = fViewOffset; fBuffer.attach(fCachedBitmap, width, height, width); - - fCachedMask.attach(fBuffer, fViewOffset.x + fOrigin.x, - fViewOffset.y + fOrigin.y, fInverse ? 255 : 0); + _AttachMaskToBuffer(); return &fScanline; } @@ -184,7 +215,7 @@ AlphaMask::_RenderPicture() const } // Clear the bitmap with the transparent color - memset(bitmap->Bits(), 0, bitmap->BitsLength()); + memset(bitmap->Bits(), fBackgroundOpacity, bitmap->BitsLength()); // Render the picture to the bitmap BitmapHWInterface interface(bitmap); @@ -213,3 +244,13 @@ AlphaMask::_RenderPicture() const return bitmap; } + +void +AlphaMask::_AttachMaskToBuffer() +{ + uint8 outsideOpacity = fInverse ? 255 - fBackgroundOpacity + : fBackgroundOpacity; + + fCachedMask.attach(fBuffer, fViewOffset.x + fOrigin.x, + fViewOffset.y + fOrigin.y, outsideOpacity); +} diff --git a/src/servers/app/drawing/AlphaMask.h b/src/servers/app/drawing/AlphaMask.h index 661ec7768e..83ceb7fd2f 100644 --- a/src/servers/app/drawing/AlphaMask.h +++ b/src/servers/app/drawing/AlphaMask.h @@ -1,5 +1,5 @@ /* - * Copyright 2014, Haiku, Inc. + * Copyright 2014-2015, Haiku, Inc. * Distributed under the terms of the MIT License. */ @@ -23,6 +23,7 @@ class AlphaMask : public BReferenceable { public: AlphaMask(ServerPicture* mask, bool inverse, BPoint origin, const DrawState& drawState); + AlphaMask(uint8 backgroundOpacity); ~AlphaMask(); void Update(BRect bounds, BPoint offset); @@ -33,6 +34,7 @@ public: private: ServerBitmap* _RenderPicture() const; + void _AttachMaskToBuffer(); private: @@ -41,10 +43,18 @@ private: ServerPicture* fPicture; const bool fInverse; BPoint fOrigin; + // position of this mask, relative to + // either its parent mask, or (if there + // is none) the canvas + uint8 fBackgroundOpacity; DrawState fDrawState; + // draw state used for drawing fPicture BRect fViewBounds; + // determines alpha mask size BPoint fViewOffset; + // position of alpha mask in screen + // coordinates uint8* fCachedBitmap; BRect fCachedBounds; From cd621b9585b4dd2dd629283976130c13afeb087e Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Wed, 22 Jul 2015 21:31:42 +0200 Subject: [PATCH 013/370] app_server: add method to shift alpha masks * Allow shifting the offset of alpha masks without changing the size. Ideally, we only need to reattach the buffer in the shifted position, saving the work of reallocating and redrawing the mask picture. Needed for layers support. --- src/servers/app/drawing/AlphaMask.cpp | 19 +++++++++++++++++++ src/servers/app/drawing/AlphaMask.h | 1 + 2 files changed, 20 insertions(+) diff --git a/src/servers/app/drawing/AlphaMask.cpp b/src/servers/app/drawing/AlphaMask.cpp index 391c929466..49636c6296 100644 --- a/src/servers/app/drawing/AlphaMask.cpp +++ b/src/servers/app/drawing/AlphaMask.cpp @@ -89,6 +89,25 @@ AlphaMask::Update(BRect bounds, BPoint offset) } +BPoint +AlphaMask::Update(BPoint offset) +{ + BPoint oldOffset = fViewOffset; + fViewOffset = offset; + + if (oldOffset == fCachedOffset && fCachedBitmap != NULL) { + // No need to redraw the picture when only the offset is shifted + fCachedOffset = offset; + _AttachMaskToBuffer(); + } + + if (fPreviousMask != NULL) + fPreviousMask->Update(offset); + + return oldOffset; +} + + void AlphaMask::SetPrevious(AlphaMask* mask) { diff --git a/src/servers/app/drawing/AlphaMask.h b/src/servers/app/drawing/AlphaMask.h index 83ceb7fd2f..cb1969af7a 100644 --- a/src/servers/app/drawing/AlphaMask.h +++ b/src/servers/app/drawing/AlphaMask.h @@ -27,6 +27,7 @@ public: ~AlphaMask(); void Update(BRect bounds, BPoint offset); + BPoint Update(BPoint offset); void SetPrevious(AlphaMask* mask); From d56beda4d8fa72f264b64c8e649ae4d8a0430a43 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Wed, 22 Jul 2015 21:36:10 +0200 Subject: [PATCH 014/370] app_server: optional coordinate shifting in renderer_region * agg::renderer_region gets an extra feature which allows to optionally shift the coordinates by a specified offset. * This allows to shift coordinates at the lowest level, even below the transformations done by BAffineTransform (which happen in the painter, right before rasterization). Needed for layers support: shifts the origin of the layer bitmaps to their position in the view while keeping all transformations (BView origin/scale transforms as well as BAffineTransforms) intact. The offset for the layer bitmaps within their parent view is determined by the bounding box and is then fixed, it must not be altered while the layer's BPicture is played into the bitmap. If this offset were added to the BView origin or as translation in the BAffineTransform, it would be further transformed by the BView scale or the other affine transform parameters. Thus, we need another low-level offset mechanism which is even below BAffineTransform's transformations. --- src/servers/app/drawing/DrawingEngine.cpp | 12 +- src/servers/app/drawing/DrawingEngine.h | 5 +- src/servers/app/drawing/Painter/Painter.cpp | 12 +- src/servers/app/drawing/Painter/Painter.h | 3 + .../app/drawing/Painter/agg_renderer_region.h | 138 ++++++++++++++++-- 5 files changed, 156 insertions(+), 14 deletions(-) diff --git a/src/servers/app/drawing/DrawingEngine.cpp b/src/servers/app/drawing/DrawingEngine.cpp index b5c425a97a..147a359b18 100644 --- a/src/servers/app/drawing/DrawingEngine.cpp +++ b/src/servers/app/drawing/DrawingEngine.cpp @@ -1,9 +1,10 @@ /* - * Copyright 2001-2009, Haiku, Inc. + * Copyright 2001-2015, Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: * Stephan Aßmus + * Julian Harnath */ @@ -1070,7 +1071,7 @@ DrawingEngine::FillRegion(BRegion& r) doInSoftware = false; } } - + if (doInSoftware && (fAvailableHWAccleration & HW_ACC_INVERT_REGION) != 0 && fPainter->Pattern() == B_SOLID_HIGH @@ -1555,6 +1556,13 @@ DrawingEngine::CopyRect(BRect src, int32 xOffset, int32 yOffset) const } +void +DrawingEngine::SetRendererOffset(int32 offsetX, int32 offsetY) +{ + fPainter->SetRendererOffset(offsetX, offsetY); +} + + void DrawingEngine::_CopyRect(uint8* src, uint32 width, uint32 height, uint32 bytesPerRow, int32 xOffset, int32 yOffset) const diff --git a/src/servers/app/drawing/DrawingEngine.h b/src/servers/app/drawing/DrawingEngine.h index dd15db25c3..d9a0896614 100644 --- a/src/servers/app/drawing/DrawingEngine.h +++ b/src/servers/app/drawing/DrawingEngine.h @@ -1,11 +1,12 @@ /* - * Copyright 2001-2009, Haiku, Inc. + * Copyright 2001-2015, Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: * DarkWyrm * Gabe Yoder * Stephan Aßmus + * Julian Harnath */ #ifndef DRAWING_ENGINE_H_ #define DRAWING_ENGINE_H_ @@ -187,6 +188,8 @@ public: virtual BRect CopyRect(BRect rect, int32 xOffset, int32 yOffset) const; + void SetRendererOffset(int32 offsetX, int32 offsetY); + private: void _CopyRect(uint8* bits, uint32 width, uint32 height, uint32 bytesPerRow, diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 9ac646eb6c..1ff042ceba 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -2,6 +2,7 @@ * Copyright 2009, Christian Packmann. * Copyright 2008, Andrej Spielmann . * Copyright 2005-2014, Stephan Aßmus . + * Copyright 2015, Julian Harnath * All rights reserved. Distributed under the terms of the MIT License. */ @@ -667,7 +668,7 @@ Painter::DrawPolygon(BPoint* p, int32 numPts, bool filled, bool closed) const bool centerOffset = !filled && fIdentityTransform && fmodf(fPenSize, 2.0) != 0.0; - + fPath.remove_all(); _Align(p, centerOffset); @@ -1508,6 +1509,13 @@ Painter::InvertRect(const BRect& r) const } +void +Painter::SetRendererOffset(int32 offsetX, int32 offsetY) +{ + fBaseRenderer.set_offset(offsetX, offsetY); +} + + // #pragma mark - private @@ -2939,7 +2947,7 @@ Painter::_RasterizePath(VertexSource& path, const BGradient& gradient) const _RasterizePath(path, gradient, gradientFunction, gradientTransform); break; } - + default: case BGradient::TYPE_NONE: GTRACE(("Painter::_FillPathGradient> type == TYPE_NONE/unkown\n")); diff --git a/src/servers/app/drawing/Painter/Painter.h b/src/servers/app/drawing/Painter/Painter.h index 166de5b8b1..4402113438 100644 --- a/src/servers/app/drawing/Painter/Painter.h +++ b/src/servers/app/drawing/Painter/Painter.h @@ -1,6 +1,7 @@ /* * Copyright 2005-2007, Stephan Aßmus . * Copyright 2008, Andrej Spielmann . + * Copyright 2015, Julian Harnath * All rights reserved. Distributed under the terms of the MIT License. * * API to the Anti-Grain Geometry based "Painter" drawing backend. Manages @@ -243,6 +244,8 @@ public: inline BRect AlignAndClipRect(BRect rect) const; inline BRect AlignRect(BRect rect) const; + void SetRendererOffset(int32 offsetX, + int32 offsetY); private: float _Align(float coord, bool round, diff --git a/src/servers/app/drawing/Painter/agg_renderer_region.h b/src/servers/app/drawing/Painter/agg_renderer_region.h index e761129744..faf0664fc2 100644 --- a/src/servers/app/drawing/Painter/agg_renderer_region.h +++ b/src/servers/app/drawing/Painter/agg_renderer_region.h @@ -1,6 +1,7 @@ /* * Copyright 2005-2006, Stephan Aßmus . * Copyright 2008, Andrej Spielmann . + * Copyright 2015, Julian Harnath * All rights reserved. Distributed under the terms of the MIT License. * * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com) @@ -36,7 +37,9 @@ namespace agg m_ren(ren), m_region(NULL), m_curr_cb(0), - m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax()) + m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax()), + m_offset_x(0), + m_offset_y(0) { } @@ -49,11 +52,15 @@ namespace agg unsigned height() const { return m_ren.height(); } //-------------------------------------------------------------------- - const rect_i& clip_box() const { return m_ren.clip_box(); } - int xmin() const { return m_ren.xmin(); } - int ymin() const { return m_ren.ymin(); } - int xmax() const { return m_ren.xmax(); } - int ymax() const { return m_ren.ymax(); } + const rect_i& clip_box() const { return m_bounds; } + int xmin() const { return translate_from_base_ren_x( + m_ren.xmin()); } + int ymin() const { return translate_from_base_ren_y( + m_ren.ymin()); } + int xmax() const { return translate_from_base_ren_x( + m_ren.xmax()); } + int ymax() const { return translate_from_base_ren_y( + m_ren.ymax()); } //-------------------------------------------------------------------- const rect_i& bounding_clip_box() const { return m_bounds; } @@ -69,7 +76,12 @@ namespace agg if(m_region && m_region->CountRects() > 0) { clipping_rect cb = m_region->RectAtInt(0); - m_ren.clip_box_naked(cb.left, cb.top, cb.right, cb.bottom); + translate_to_base_ren(cb); + m_ren.clip_box_naked( + cb.left, + cb.top, + cb.right, + cb.bottom); } else m_ren.clip_box_naked(0, 0, -1, -1); @@ -81,7 +93,12 @@ namespace agg if(m_region && (int)(++m_curr_cb) < m_region->CountRects()) { clipping_rect cb = m_region->RectAtInt(m_curr_cb); - m_ren.clip_box_naked(cb.left, cb.top, cb.right, cb.bottom); + translate_to_base_ren(cb); + m_ren.clip_box_naked( + cb.left, + cb.top, + cb.right, + cb.bottom); return true; } return false; @@ -94,6 +111,7 @@ namespace agg m_region = NULL; m_curr_cb = 0; m_bounds = m_ren.clip_box(); + translate_from_base_ren(m_bounds); } //-------------------------------------------------------------------- @@ -117,6 +135,68 @@ namespace agg } } + //-------------------------------------------------------------------- + void set_offset(int offset_x, int offset_y) + { + m_offset_x = offset_x; + m_offset_y = offset_y; + + if (m_region == NULL) { + m_bounds = m_ren.clip_box(); + translate_from_base_ren(m_bounds); + } + } + + //-------------------------------------------------------------------- + void translate_to_base_ren_x(int& x) + { + x -= m_offset_x; + } + + void translate_to_base_ren_y(int& y) + { + y -= m_offset_y; + } + + void translate_to_base_ren(int& x, int&y) + { + x -= m_offset_x; + y -= m_offset_y; + } + + void translate_to_base_ren(clipping_rect& clip) + { + clip.left -= m_offset_x; + clip.right -= m_offset_x; + clip.top -= m_offset_y; + clip.bottom -= m_offset_y; + } + + //-------------------------------------------------------------------- + int translate_from_base_ren_x(int x) const + { + return x + m_offset_x; + } + + int translate_from_base_ren_y(int y) const + { + return y + m_offset_y; + } + + void translate_from_base_ren(int& x, int& y) + { + x += m_offset_x; + y += m_offset_y; + } + + void translate_from_base_ren(rect_i& rect) + { + rect.x1 += m_offset_x; + rect.x2 += m_offset_x; + rect.y1 += m_offset_y; + rect.y2 += m_offset_y; + } + //-------------------------------------------------------------------- void clear(const color_type& c) { @@ -126,6 +206,8 @@ namespace agg //-------------------------------------------------------------------- void copy_pixel(int x, int y, const color_type& c) { + translate_to_base_ren(x, y); + first_clip_box(); do { @@ -141,6 +223,8 @@ namespace agg //-------------------------------------------------------------------- void blend_pixel(int x, int y, const color_type& c, cover_type cover) { + translate_to_base_ren(x, y); + first_clip_box(); do { @@ -156,6 +240,8 @@ namespace agg //-------------------------------------------------------------------- color_type pixel(int x, int y) const { + translate_to_base_ren(x, y); + first_clip_box(); do { @@ -171,6 +257,9 @@ namespace agg //-------------------------------------------------------------------- void copy_hline(int x1, int y, int x2, const color_type& c) { + translate_to_base_ren(x1, y); + translate_to_base_ren_x(x2); + first_clip_box(); do { @@ -182,6 +271,9 @@ namespace agg //-------------------------------------------------------------------- void copy_vline(int x, int y1, int y2, const color_type& c) { + translate_to_base_ren(x, y1); + translate_to_base_ren_y(y2); + first_clip_box(); do { @@ -194,6 +286,9 @@ namespace agg void blend_hline(int x1, int y, int x2, const color_type& c, cover_type cover) { + translate_to_base_ren(x1, y); + translate_to_base_ren_x(x2); + first_clip_box(); do { @@ -201,11 +296,14 @@ namespace agg } while(next_clip_box()); } - + //-------------------------------------------------------------------- void blend_vline(int x, int y1, int y2, const color_type& c, cover_type cover) { + translate_to_base_ren(x, y1); + translate_to_base_ren_y(y2); + first_clip_box(); do { @@ -217,6 +315,9 @@ namespace agg //-------------------------------------------------------------------- void copy_bar(int x1, int y1, int x2, int y2, const color_type& c) { + translate_to_base_ren(x1, y1); + translate_to_base_ren(x2, y2); + first_clip_box(); do { @@ -229,6 +330,9 @@ namespace agg void blend_bar(int x1, int y1, int x2, int y2, const color_type& c, cover_type cover) { + translate_to_base_ren(x1, y1); + translate_to_base_ren(x2, y2); + first_clip_box(); do { @@ -242,6 +346,8 @@ namespace agg void blend_solid_hspan(int x, int y, int len, const color_type& c, const cover_type* covers) { + translate_to_base_ren(x, y); + first_clip_box(); do { @@ -254,6 +360,8 @@ namespace agg void blend_solid_hspan_subpix(int x, int y, int len, const color_type& c, const cover_type* covers) { + translate_to_base_ren(x, y); + first_clip_box(); do { @@ -266,6 +374,8 @@ namespace agg void blend_solid_vspan(int x, int y, int len, const color_type& c, const cover_type* covers) { + translate_to_base_ren(x, y); + first_clip_box(); do { @@ -280,6 +390,8 @@ namespace agg const cover_type* covers, cover_type cover = cover_full) { + translate_to_base_ren(x, y); + first_clip_box(); do { @@ -294,6 +406,8 @@ namespace agg const cover_type* covers, cover_type cover = cover_full) { + translate_to_base_ren(x, y); + first_clip_box(); do { @@ -308,6 +422,7 @@ namespace agg const cover_type* covers, cover_type cover = cover_full) { + translate_to_base_ren(x, y); m_ren.blend_color_hspan_no_clip(x, y, len, colors, covers, cover); } @@ -317,6 +432,7 @@ namespace agg const cover_type* covers, cover_type cover = cover_full) { + translate_to_base_ren(x, y); m_ren.blend_color_vspan_no_clip(x, y, len, colors, covers, cover); } @@ -326,6 +442,7 @@ namespace agg int x_to=0, int y_to=0) { + translate_to_base_ren(x_to, y_to); first_clip_box(); do { @@ -343,6 +460,9 @@ namespace agg BRegion* m_region; unsigned m_curr_cb; rect_i m_bounds; + + int m_offset_x; + int m_offset_y; }; From 551438b9be6bb3c4c52b8276718d56eccf969dff Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Sat, 25 Jul 2015 15:44:23 +0200 Subject: [PATCH 015/370] app_server: add new BView layers API * Add new methods BView::BeginLayer(uint8 opacity) BView::EndLayer() * All drawing between begin and end of a layer is redirected onto an intermediate bitmap. When ending the layer, this bitmap is composited onto the view with the opacity given when the layer was started. * Layers can be nested arbitrarily and will be blended onto each other in order. There can also be any arbitrary interleaving of layer begin/end and drawing operations. * Internally, drawing commands are redirected into a BPicture between BeginLayer and EndLayer (but client code need not know or care about this). Client code can also start/end other BPictures while inside a layer. * Uses the PictureBoundingBoxPlayer to determine the size of the layer bitmap before allocating and drawing into it, so it does not allocate more memory than necessary and -- more importantly -- it will not alpha-composite more pixels than necessary. * Drawing mode is always set to B_OP_ALPHA, blend mode to (B_PIXEL_ALPHA, B_ALPHA_COMPOSITE) while inside layers. This is necessary for (a) correct compositing output and (b) for redirection of drawing into the intermediate bitmap, which uses the renderer_region offset (in B_OP_COPY, the Painter does not use the AGG renderer methods, it directly accesses the pixel data. This would access out-of-bounds without the offset, so B_OP_COPY cannot be allowed.) To ensure these modes aren't changed, BView::SetDrawingMode() and BView::SetBlendingMode() are ignored while inside a layer. * The main motivation behind this new API is WebKit, which internally expects such a layers functionality to be present. A performant and reusable implementation of this functionality can only be done server-side in app_server. --- headers/os/interface/View.h | 3 + headers/private/app/ServerProtocol.h | 3 + headers/private/interface/PictureDataWriter.h | 6 +- headers/private/interface/PictureProtocol.h | 3 +- src/kits/interface/PictureDataWriter.cpp | 18 +- src/kits/interface/PicturePlayer.cpp | 16 +- src/kits/interface/View.cpp | 26 ++- src/servers/app/Canvas.cpp | 42 ++++ src/servers/app/Canvas.h | 3 + src/servers/app/Jamfile | 1 + src/servers/app/Layer.cpp | 216 ++++++++++++++++++ src/servers/app/Layer.h | 42 ++++ src/servers/app/PictureBoundingBoxPlayer.cpp | 16 +- src/servers/app/ServerPicture.cpp | 11 +- src/servers/app/ServerPicture.h | 5 +- src/servers/app/ServerWindow.cpp | 69 +++++- src/servers/app/View.cpp | 17 +- src/servers/app/View.h | 5 +- src/tests/servers/app/Jamfile | 1 + 19 files changed, 489 insertions(+), 14 deletions(-) create mode 100644 src/servers/app/Layer.cpp create mode 100644 src/servers/app/Layer.h diff --git a/headers/os/interface/View.h b/headers/os/interface/View.h index e744375fee..29a3fefc12 100644 --- a/headers/os/interface/View.h +++ b/headers/os/interface/View.h @@ -505,6 +505,9 @@ public: void DrawPictureAsync(const char* filename, long offset, BPoint where); + void BeginLayer(uint8 opacity); + void EndLayer(); + status_t SetEventMask(uint32 mask, uint32 options = 0); uint32 EventMask(); status_t SetMouseEventMask(uint32 mask, diff --git a/headers/private/app/ServerProtocol.h b/headers/private/app/ServerProtocol.h index 952a6111dd..897baa18e2 100644 --- a/headers/private/app/ServerProtocol.h +++ b/headers/private/app/ServerProtocol.h @@ -7,6 +7,7 @@ * Jérôme Duval, jerome.duval@free.fr * Axel Dörfler, axeld@pinc-software.de * Andrej Spielmann, + * Julian Harnath, */ #ifndef APP_SERVER_PROTOCOL_H #define APP_SERVER_PROTOCOL_H @@ -319,6 +320,8 @@ enum { AS_VIEW_SET_VIEW_BITMAP, AS_VIEW_SET_PATTERN, AS_SET_CURRENT_VIEW, + AS_VIEW_BEGIN_LAYER, + AS_VIEW_END_LAYER, // BDirectWindow/BWindowScreen codes AS_DIRECT_WINDOW_GET_SYNC_DATA, diff --git a/headers/private/interface/PictureDataWriter.h b/headers/private/interface/PictureDataWriter.h index 4af9187f24..a0f7904ee8 100644 --- a/headers/private/interface/PictureDataWriter.h +++ b/headers/private/interface/PictureDataWriter.h @@ -1,9 +1,10 @@ /* - * Copyright 2006-2007 Haiku, Inc. All rights reserved. + * Copyright 2006-2015 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Stefano Ceccherini, burton666@libero.it + * Julian Harnath, */ #ifndef _PICTURE_DATA_WRITER_H #define _PICTURE_DATA_WRITER_H @@ -17,6 +18,7 @@ #include +class Layer; class BPositionIO; class BRegion; @@ -91,6 +93,8 @@ public: status_t WriteDrawPicture(const BPoint& where, const int32& token); + status_t WriteBlendLayer(Layer* layer); + protected: // throw a status_t on error void BeginOp(const int16& op); diff --git a/headers/private/interface/PictureProtocol.h b/headers/private/interface/PictureProtocol.h index f83b53d86c..f33abddaa6 100644 --- a/headers/private/interface/PictureProtocol.h +++ b/headers/private/interface/PictureProtocol.h @@ -52,10 +52,11 @@ enum { B_PIC_SET_FONT_BPP = 0x0388, B_PIC_SET_FONT_FACE = 0x0389, B_PIC_SET_TRANSFORM = 0x0390, + B_PIC_BLEND_LAYER = 0x0391 }; -const static uint32 kOpsTableSize = 49; +const static uint32 kOpsTableSize = 50; #endif diff --git a/src/kits/interface/PictureDataWriter.cpp b/src/kits/interface/PictureDataWriter.cpp index 3f9f5c911c..e2ae828fe3 100644 --- a/src/kits/interface/PictureDataWriter.cpp +++ b/src/kits/interface/PictureDataWriter.cpp @@ -1,9 +1,10 @@ /* - * Copyright 2006-2009 Haiku, Inc. All rights reserved. + * Copyright 2006-2015 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Stefano Ceccherini, stefano.ceccherini@gmail.com + * Julian Harnath, */ #include @@ -641,6 +642,21 @@ PictureDataWriter::WritePopState() } +status_t +PictureDataWriter::WriteBlendLayer(Layer* layer) +{ + try { + BeginOp(B_PIC_BLEND_LAYER); + Write(layer); + EndOp(); + } catch (status_t& status) { + return status; + } + + return B_OK; +} + + // private void PictureDataWriter::BeginOp(const int16& op) diff --git a/src/kits/interface/PicturePlayer.cpp b/src/kits/interface/PicturePlayer.cpp index ed2f13c546..c56cfd66c0 100644 --- a/src/kits/interface/PicturePlayer.cpp +++ b/src/kits/interface/PicturePlayer.cpp @@ -1,11 +1,12 @@ /* - * Copyright 2001-2007, Haiku Inc. + * Copyright 2001-2015, Haiku Inc. * Distributed under the terms of the MIT License. * * Authors: * Marc Flerackers (mflerackers@androme.be) * Stefano Ceccherini (stefano.ceccherini@gmail.com) * Marcus Overhagen (marcus@overhagen.de) + * Julian Harnath (julian.harnath@rwth-aachen.de) */ /** PicturePlayer is used to play picture data. */ @@ -23,6 +24,9 @@ using BPrivate::PicturePlayer; +class Layer; + + typedef void (*fnc)(void*); typedef void (*fnc_BPoint)(void*, BPoint); typedef void (*fnc_BPointBPoint)(void*, BPoint, BPoint); @@ -47,6 +51,7 @@ typedef void (*fnc_DrawPixels)(void *, BRect, BRect, int32, int32, int32, typedef void (*fnc_DrawPicture)(void *, BPoint, int32); typedef void (*fnc_BShape)(void*, BShape*); typedef void (*fnc_BAffineTransform)(void*, BAffineTransform); +typedef void (*fnc_Layer)(void*, const Layer*); static void @@ -160,7 +165,7 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, (void *)nop, - (void *)nop + (void *)nop, (void *)nop }; if ((uint32)tableEntries < kOpsTableSize) { @@ -546,6 +551,13 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) break; } + case B_PIC_BLEND_LAYER: + { + ((fnc_Layer)functionTable[49])(userData, + *reinterpret_cast(data)); + break; + } + default: break; } diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index eb07f0f64b..703320cdb8 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -7,6 +7,7 @@ * Axel Dörfler, axeld@pinc-software.de * Adrian Oanca, adioanca@cotty.iren.ro * Ingo Weinhold. ingo_weinhold@gmx.de + * Julian Harnath, julian.harnath@rwth-aachen.de */ @@ -3933,6 +3934,27 @@ BView::DrawPictureAsync(const char* filename, long offset, BPoint where) } +void +BView::BeginLayer(uint8 opacity) +{ + if (_CheckOwnerLockAndSwitchCurrent()) { + fOwner->fLink->StartMessage(AS_VIEW_BEGIN_LAYER); + fOwner->fLink->Attach(opacity); + _FlushIfNotInTransaction(); + } +} + + +void +BView::EndLayer() +{ + if (_CheckOwnerLockAndSwitchCurrent()) { + fOwner->fLink->StartMessage(AS_VIEW_END_LAYER); + _FlushIfNotInTransaction(); + } +} + + void BView::Invalidate(BRect invalRect) { @@ -5225,7 +5247,7 @@ BView::_ClipToPicture(BPicture* picture, BPoint where, bool invert, bool sync) if (picture == NULL) { fOwner->fLink->StartMessage(AS_VIEW_CLIP_TO_PICTURE); fOwner->fLink->Attach(-1); - + // NOTE: No need to sync here, since the -1 token cannot // become invalid on the server. } else { @@ -5240,7 +5262,7 @@ BView::_ClipToPicture(BPicture* picture, BPoint where, bool invert, bool sync) // the client creates BPictures on the stack, these BPictures may // have issued a AS_DELETE_PICTURE command to the ServerApp when Draw() // goes out of scope, and the command is processed earlier in the - // ServerApp thread than the AS_VIEW_CLIP_TO_PICTURE command in the + // ServerApp thread than the AS_VIEW_CLIP_TO_PICTURE command in the // ServerWindow thread, which will then have the result that no // ServerPicture is found of the token. if (sync) diff --git a/src/servers/app/Canvas.cpp b/src/servers/app/Canvas.cpp index 89b100f9d6..e79b1527a2 100644 --- a/src/servers/app/Canvas.cpp +++ b/src/servers/app/Canvas.cpp @@ -19,8 +19,10 @@ #include +#include "AlphaMask.h" #include "DrawingEngine.h" #include "DrawState.h" +#include "Layer.h" #if __GNUC__ >= 3 @@ -218,6 +220,46 @@ Canvas::ScreenToPenTransform() const GCC_2_NRV(transform) } +void +Canvas::BlendLayer(Layer* layer) +{ + UtilityBitmap* layerBitmap = layer->RenderToBitmap(this); + if (layerBitmap == NULL) + return; + + BRect destination = layerBitmap->Bounds(); + destination.OffsetBy(layer->LeftTopOffset()); + LocalToScreenTransform().Apply(&destination); + + PushState(); + + fDrawState->SetDrawingMode(B_OP_ALPHA); + fDrawState->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE); + fDrawState->SetTransformEnabled(false); + + AlphaMask* mask = new AlphaMask(layer->Opacity()); + if (mask == NULL) { + layerBitmap->ReleaseReference(); + return; + } + + SetAlphaMask(mask); + mask->ReleaseReference(); + ResyncDrawState(); + + GetDrawingEngine()->DrawBitmap(layerBitmap, layerBitmap->Bounds(), + destination, 0); + + fDrawState->SetTransformEnabled(true); + + PopState(); + ResyncDrawState(); + + layerBitmap->ReleaseReference(); + layer->ReleaseReference(); +} + + // #pragma mark - OffscreenCanvas diff --git a/src/servers/app/Canvas.h b/src/servers/app/Canvas.h index 3744435187..aaad41b9c6 100644 --- a/src/servers/app/Canvas.h +++ b/src/servers/app/Canvas.h @@ -27,6 +27,7 @@ class DrawingEngine; class DrawState; class IntPoint; class IntRect; +class Layer; class ServerPicture; @@ -61,6 +62,8 @@ public: SimpleTransform PenToLocalTransform() const; SimpleTransform ScreenToPenTransform() const; + void BlendLayer(Layer* layer); + virtual DrawingEngine* GetDrawingEngine() const = 0; virtual ServerPicture* GetPicture(int32 token) const = 0; virtual void RebuildClipping(bool deep) = 0; diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index fdaea83c7e..7c96133439 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -67,6 +67,7 @@ Server app_server : InputManager.cpp IntPoint.cpp IntRect.cpp + Layer.cpp MessageLooper.cpp MultiLocker.cpp OffscreenServerWindow.cpp diff --git a/src/servers/app/Layer.cpp b/src/servers/app/Layer.cpp new file mode 100644 index 0000000000..1c80ad736b --- /dev/null +++ b/src/servers/app/Layer.cpp @@ -0,0 +1,216 @@ +/* + * Copyright 2015 Julian Harnath + * All rights reserved. Distributed under the terms of the MIT license. + */ +#include "Layer.h" + +#include "AlphaMask.h" +#include "BitmapHWInterface.h" +#include "DrawingEngine.h" +#include "DrawState.h" +#include "IntRect.h" +#include "PictureBoundingBoxPlayer.h" +#include "ServerBitmap.h" +#include "View.h" + + +class LayerCanvas : public Canvas { +public: + LayerCanvas(DrawingEngine* drawingEngine, DrawState* drawState) + : + Canvas(), + fDrawingEngine(drawingEngine) + { + delete fDrawState; + fDrawState = drawState; + } + + virtual DrawingEngine* GetDrawingEngine() const + { + return fDrawingEngine; + } + + virtual ServerPicture* GetPicture(int32 token) const + { + return NULL; + } + + virtual void RebuildClipping(bool) + { + } + + virtual void ResyncDrawState() + { + fDrawingEngine->SetDrawState(fDrawState); + } + +protected: + virtual void _LocalToScreenTransform(SimpleTransform&) const + { + } + + virtual void _ScreenToLocalTransform(SimpleTransform&) const + { + } + +private: + DrawingEngine* fDrawingEngine; +}; + + +Layer::Layer(uint8 opacity) + : + fOpacity(opacity), + fLeftTopOffset(0, 0) +{ +} + + +Layer::~Layer() +{ +} + + +void +Layer::PushLayer(Layer* layer) +{ + PushPicture(layer); +} + + +Layer* +Layer::PopLayer() +{ + Layer* const previousLayer = static_cast(PopPicture()); + if (previousLayer != NULL) + previousLayer->ReleaseReference(); + return previousLayer; +} + + +UtilityBitmap* +Layer::RenderToBitmap(Canvas* canvas) +{ + BRect boundingBox = _DetermineBoundingBox(canvas); + if (!boundingBox.IsValid()) + return NULL; + + fLeftTopOffset = boundingBox.LeftTop(); + + UtilityBitmap* const layerBitmap = _AllocateBitmap(boundingBox); + if (layerBitmap == NULL) + return NULL; + + BitmapHWInterface layerInterface(layerBitmap); + DrawingEngine* const layerEngine = layerInterface.CreateDrawingEngine(); + if (layerEngine == NULL) { + layerBitmap->ReleaseReference(); + return NULL; + } + layerEngine->SetRendererOffset(boundingBox.left, boundingBox.top); + // Drawing commands of the layer's picture use coordinates in the + // coordinate space of the underlying canvas. The coordinate origin + // of the layer bitmap is at boundingBox.LeftTop(). So all the drawing + // from the picture needs to be offset to be moved into the bitmap. + // We use a low-level offsetting via the AGG renderer here because the + // offset needs to be processed independently, after all other + // transforms, even after the BAffineTransforms (which are processed in + // Painter), to prevent this origin from being further transformed by + // e.g. scaling. + + LayerCanvas layerCanvas(layerEngine, canvas->CurrentState()); + + AlphaMask* const mask = layerCanvas.GetAlphaMask(); + BPoint oldOffset; + if (mask != NULL) { + // Move alpha mask to bitmap origin + oldOffset = mask->Update(BPoint(0, 0)); + } + + canvas->CurrentState()->SetDrawingMode(B_OP_ALPHA); + canvas->CurrentState()->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE); + + layerCanvas.ResyncDrawState(); + // Apply state to the new drawing engine of the layer canvas + + if (layerEngine->LockParallelAccess()) { + const BRegion region(boundingBox); + layerEngine->ConstrainClippingRegion(®ion); + + // Draw recorded picture into bitmap + Play(&layerCanvas); + layerEngine->UnlockParallelAccess(); + } + + if (mask != NULL) { + // Move alpha mask back to its old position + // Note: this needs to be adapted if setting alpha masks is + // implemented as BPicture command (the mask now might be a different + // one than before). + mask->Update(oldOffset); + layerCanvas.ResyncDrawState(); + } + + canvas->SetDrawState(layerCanvas.CurrentState()); + // Update state in canvas (the top-of-stack state could be a different + // state instance now, if the picture commands contained push/pop + // commands) + + delete layerEngine; + + return layerBitmap; +} + + +IntPoint +Layer::LeftTopOffset() const +{ + return fLeftTopOffset; +} + + +uint8 +Layer::Opacity() const +{ + return fOpacity; +} + + +BRect +Layer::_DetermineBoundingBox(Canvas* canvas) +{ + BRect boundingBox; + PictureBoundingBoxPlayer::Play(this, canvas->CurrentState(), &boundingBox); + + if (!boundingBox.IsValid()) + return boundingBox; + + // Round up and add an additional 2 pixels on the bottom/right to + // compensate for the various types of rounding used in Painter. + boundingBox.left = floorf(boundingBox.left); + boundingBox.right = ceilf(boundingBox.right) + 2; + boundingBox.top = floorf(boundingBox.top); + boundingBox.bottom = ceilf(boundingBox.bottom) + 2; + + // TODO: for optimization, crop the bounding box to the underlying + // view bounds here + + return boundingBox; +} + + +UtilityBitmap* +Layer::_AllocateBitmap(const BRect& bounds) +{ + UtilityBitmap* const layerBitmap = new(std::nothrow) UtilityBitmap(bounds, + B_RGBA32, 0); + if (layerBitmap == NULL) + return NULL; + if (!layerBitmap->IsValid()) { + delete layerBitmap; + return NULL; + } + memset(layerBitmap->Bits(), 0, layerBitmap->BitsLength()); + + return layerBitmap; +} diff --git a/src/servers/app/Layer.h b/src/servers/app/Layer.h new file mode 100644 index 0000000000..7a9f969cd4 --- /dev/null +++ b/src/servers/app/Layer.h @@ -0,0 +1,42 @@ +/* + * Copyright 2015 Julian Harnath + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef LAYER_H +#define LAYER_H + + +#include "ServerPicture.h" + +#include "IntPoint.h" + + +class AlphaMask; +class Canvas; +class UtilityBitmap; + + +class Layer : public ServerPicture { +public: + Layer(uint8 opacity); + virtual ~Layer(); + + void PushLayer(Layer* layer); + Layer* PopLayer(); + + UtilityBitmap* RenderToBitmap(Canvas* canvas); + + IntPoint LeftTopOffset() const; + uint8 Opacity() const; + +private: + BRect _DetermineBoundingBox(Canvas* canvas); + UtilityBitmap* _AllocateBitmap(const BRect& bounds); + +private: + uint8 fOpacity; + IntPoint fLeftTopOffset; +}; + + +#endif // LAYER_H diff --git a/src/servers/app/PictureBoundingBoxPlayer.cpp b/src/servers/app/PictureBoundingBoxPlayer.cpp index 08ff0f7f0d..b330a78265 100644 --- a/src/servers/app/PictureBoundingBoxPlayer.cpp +++ b/src/servers/app/PictureBoundingBoxPlayer.cpp @@ -16,6 +16,7 @@ #include "DrawState.h" #include "FontManager.h" +#include "Layer.h" #include "ServerApp.h" #include "ServerBitmap.h" #include "ServerFont.h" @@ -704,6 +705,18 @@ set_transform(BoundingBoxState* state, BAffineTransform transform) } +static void +determine_bounds_nested_layer(BoundingBoxState* state, Layer* layer) +{ + TRACE_BB("%p nested layer\n", state); + + BRect boundingBox; + PictureBoundingBoxPlayer::Play(layer, state->GetDrawState(), &boundingBox); + if (boundingBox.IsValid()) + state->IncludeRect(boundingBox); +} + + const static void* kTableEntries[] = { (const void*)nop, // 0 (const void*)move_pen_by, @@ -753,7 +766,8 @@ const static void* kTableEntries[] = { (const void*)nop, // 45 (const void*)set_font_face, (const void*)set_blending_mode, - (const void*)set_transform // 48 + (const void*)set_transform, + (const void*)determine_bounds_nested_layer // 49 }; diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index f7f2babaad..9e060d2ac6 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -18,6 +18,7 @@ #include "DrawingEngine.h" #include "DrawState.h" #include "FontManager.h" +#include "Layer.h" #include "ServerApp.h" #include "ServerBitmap.h" #include "ServerFont.h" @@ -784,6 +785,13 @@ set_transform(Canvas* canvas, BAffineTransform transform) } +static void +blend_layer(Canvas* canvas, Layer* layer) +{ + canvas->BlendLayer(layer); +} + + static void reserved() { @@ -839,7 +847,8 @@ const static void* kTableEntries[] = { (const void*)reserved, // 45 (const void*)set_font_face, (const void*)set_blending_mode, - (const void*)set_transform // 48 + (const void*)set_transform, + (const void*)blend_layer // 49 }; diff --git a/src/servers/app/ServerPicture.h b/src/servers/app/ServerPicture.h index 5b008e22d9..d44d2a5282 100644 --- a/src/servers/app/ServerPicture.h +++ b/src/servers/app/ServerPicture.h @@ -1,10 +1,11 @@ /* - * Copyright 2001-2010, Haiku. + * Copyright 2001-2015, Haiku. * Distributed under the terms of the MIT License. * * Authors: * DarkWyrm * Stefano Ceccherini + * Julian Harnath */ #ifndef SERVER_PICTURE_H #define SERVER_PICTURE_H @@ -35,7 +36,7 @@ public: ServerPicture(const ServerPicture& other); ServerPicture(const char* fileName, int32 offset); - ~ServerPicture(); + virtual ~ServerPicture(); int32 Token() { return fToken; } bool SetOwner(ServerApp* owner); diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 81892f939c..d0b1d01476 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2010, Haiku. + * Copyright 2001-2015, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -11,6 +11,7 @@ * Artur Wyszynski * Philippe Saint-Pierre * Brecht Machiels + * Julian Harnath */ @@ -61,6 +62,7 @@ #include "DrawingEngine.h" #include "DrawState.h" #include "HWInterface.h" +#include "Layer.h" #include "Overlay.h" #include "ProfileMessageSupport.h" #include "RenderingBuffer.h" @@ -2184,6 +2186,21 @@ fDesktop->LockSingleWindow(); break; } + case AS_VIEW_BEGIN_LAYER: + { + DTRACE(("ServerWindow %s: Message AS_VIEW_BEGIN_LAYER\n", + Title())); + + uint8 opacity; + link.Read(&opacity); + + Layer* layer = new(std::nothrow) Layer(opacity); + if (layer == NULL) + break; + fCurrentView->SetPicture(layer); + break; + } + default: _DispatchViewDrawingMessage(code, link); break; @@ -2922,6 +2939,15 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, break; } + case AS_VIEW_END_LAYER: + { + DTRACE(("ServerWindow %s: Message AS_VIEW_END_LAYER\n", + Title())); + fCurrentView->BlendAllLayers(); + fCurrentView->SetPicture(NULL); + break; + } + default: BString codeString; string_for_message_code(code, codeString); @@ -2983,6 +3009,11 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) int8 drawingMode; link.Read(&drawingMode); + if (dynamic_cast(picture) != NULL) { + // drawing mode changes not allowed in layers + break; + } + picture->WriteSetDrawingMode((drawing_mode)drawingMode); fCurrentView->CurrentState()->SetDrawingMode( @@ -3416,6 +3447,42 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) fLink.Flush(); return true; } + + case AS_VIEW_BEGIN_LAYER: + { + uint8 opacity; + link.Read(&opacity); + + Layer* layer = dynamic_cast(picture); + if (layer == NULL) + break; + + Layer* nextLayer = new(std::nothrow) Layer(opacity); + if (nextLayer == NULL) + break; + + nextLayer->PushLayer(layer); + fCurrentView->SetPicture(nextLayer); + break; + } + + case AS_VIEW_END_LAYER: + { + Layer* layer = dynamic_cast(picture); + if (layer == NULL) + break; + + Layer* previousLayer = layer->PopLayer(); + if (previousLayer == NULL) { + // End last layer + return false; + } + fCurrentView->SetPicture(previousLayer); + + previousLayer->WriteBlendLayer(layer); + break; + } + /* case AS_VIEW_SET_BLENDING_MODE: { diff --git a/src/servers/app/View.cpp b/src/servers/app/View.cpp index b1375327a3..eaf80412fc 100644 --- a/src/servers/app/View.cpp +++ b/src/servers/app/View.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2014, Haiku, Inc. + * Copyright (c) 2001-2015, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: @@ -9,6 +9,7 @@ * Stephan Aßmus * Marcus Overhagen * Adrien Destugues */ #include "View.h" @@ -19,6 +20,7 @@ #include "Desktop.h" #include "DrawingEngine.h" #include "DrawState.h" +#include "Layer.h" #include "Overlay.h" #include "ServerApp.h" #include "ServerBitmap.h" @@ -27,6 +29,7 @@ #include "ServerWindow.h" #include "Window.h" +#include "BitmapHWInterface.h" #include "drawing_support.h" #include @@ -972,6 +975,18 @@ View::SetPicture(ServerPicture* picture) } +void +View::BlendAllLayers() +{ + if (fPicture == NULL) + return; + Layer* layer = dynamic_cast(fPicture); + if (layer == NULL) + return; + BlendLayer(layer); +} + + void View::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping, BRegion* windowContentClipping, bool deep) diff --git a/src/servers/app/View.h b/src/servers/app/View.h index 5550fcb961..fbf66409b9 100644 --- a/src/servers/app/View.h +++ b/src/servers/app/View.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2014, Haiku, Inc. + * Copyright (c) 2001-2015, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: @@ -9,6 +9,7 @@ * Stephan Aßmus * Marcus Overhagen * Adrien Destugues + * Julian Harnath */ #ifndef VIEW_H #define VIEW_H @@ -156,6 +157,8 @@ public: ServerPicture* Picture() const { return fPicture; } + void BlendAllLayers(); + // for background clearing virtual void Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping, diff --git a/src/tests/servers/app/Jamfile b/src/tests/servers/app/Jamfile index 73d8b98009..de8d379f46 100644 --- a/src/tests/servers/app/Jamfile +++ b/src/tests/servers/app/Jamfile @@ -154,6 +154,7 @@ SharedLibrary libtestappserver.so : BitmapHWInterface.cpp Canvas.cpp DesktopSettings.cpp + Layer.cpp OffscreenServerWindow.cpp OffscreenWindow.cpp PictureBoundingBoxPlayer.cpp From d727d0743b2f8bebaf895dc2a661a97fbf3f226a Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Fri, 31 Jul 2015 21:01:12 +0200 Subject: [PATCH 016/370] app_server: fix clearing user clipping from BPicture * Clipping was set to an empty region instead of being cleared when inside a BPicture --- src/servers/app/ServerPicture.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index 9e060d2ac6..bec689149f 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -538,10 +538,14 @@ set_clipping_rects(Canvas* canvas, const BRect* rects, { // TODO: This might be too slow, we should copy the rects // directly to BRegion's internal data - BRegion region; - for (uint32 c = 0; c < numRects; c++) - region.Include(rects[c]); - canvas->SetUserClipping(®ion); + if (numRects == 0) + canvas->SetUserClipping(NULL); + else { + BRegion region; + for (uint32 c = 0; c < numRects; c++) + region.Include(rects[c]); + canvas->SetUserClipping(®ion); + } canvas->UpdateCurrentDrawingRegion(); } From 3d12d3a832462309cca084b87a89d008ae50d5e9 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Mon, 3 Aug 2015 18:50:58 +0200 Subject: [PATCH 017/370] app_server: special handling for opaque/invisible layers * Opaque layers (opacity = 255) don't need to use an intermediate bitmap (and everything that comes with it) for drawing at all, they can just directly draw onto the underlying canvas or layer. (WebKit likes to use plenty of opaque layers) * Invisible layers (opacity = 0) can simply be ignored. --- src/servers/app/Canvas.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/servers/app/Canvas.cpp b/src/servers/app/Canvas.cpp index e79b1527a2..3c53676e62 100644 --- a/src/servers/app/Canvas.cpp +++ b/src/servers/app/Canvas.cpp @@ -223,6 +223,15 @@ Canvas::ScreenToPenTransform() const GCC_2_NRV(transform) void Canvas::BlendLayer(Layer* layer) { + if (layer->Opacity() == 255) { + layer->Play(this); + layer->ReleaseReference(); + return; + } else if (layer->Opacity() == 0) { + layer->ReleaseReference(); + return; + } + UtilityBitmap* layerBitmap = layer->RenderToBitmap(this); if (layerBitmap == NULL) return; From c77b945acdc5bdad234c2d5cd35ffb158e1ae9d8 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Mon, 3 Aug 2015 18:53:20 +0200 Subject: [PATCH 018/370] app_server: allow drawing mode changes in opaque layers * For better performance, we allow doing drawing mode changes (and thus, B_OP_COPY) again when inside an opaque layer which has only other opaque layers below it in the layer stack. As soon as the first non-opaque layer turns up in the stack, the drawing mode will be locked to alpha composite mode, until this layer stack is ended entirely. This allows using B_OP_COPY in many cases as used by WebKit. * In the long term it would be nice to get rid of the drawing-mode lock altogether, however that would need some larger refactoring work in Painter (i.e. remove the offsetting from renderer_region again and instead implement an "exit-level transform" (support for offsets is enough) in Painter which is applied after all other transforms). --- src/servers/app/DrawState.cpp | 19 ++++++++++++++++--- src/servers/app/DrawState.h | 3 +++ src/servers/app/ServerWindow.cpp | 19 ++++++++++++++----- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/servers/app/DrawState.cpp b/src/servers/app/DrawState.cpp index 2eaa39f5de..de5c81173e 100644 --- a/src/servers/app/DrawState.cpp +++ b/src/servers/app/DrawState.cpp @@ -47,6 +47,7 @@ DrawState::DrawState() fDrawingMode(B_OP_COPY), fAlphaSrcMode(B_PIXEL_ALPHA), fAlphaFncMode(B_ALPHA_OVERLAY), + fDrawingModeLocked(false), fPenLocation(0.0f, 0.0f), fPenSize(1.0f), @@ -81,6 +82,7 @@ DrawState::DrawState(const DrawState& other) fDrawingMode(other.fDrawingMode), fAlphaSrcMode(other.fAlphaSrcMode), fAlphaFncMode(other.fAlphaFncMode), + fDrawingModeLocked(other.fDrawingModeLocked), fPenLocation(other.fPenLocation), fPenSize(other.fPenSize), @@ -527,18 +529,29 @@ DrawState::SetPattern(const Pattern& pattern) void DrawState::SetDrawingMode(drawing_mode mode) { - fDrawingMode = mode; + if (!fDrawingModeLocked) + fDrawingMode = mode; } void DrawState::SetBlendingMode(source_alpha srcMode, alpha_function fncMode) { - fAlphaSrcMode = srcMode; - fAlphaFncMode = fncMode; + if (!fDrawingModeLocked) { + fAlphaSrcMode = srcMode; + fAlphaFncMode = fncMode; + } } +void +DrawState::SetDrawingModeLocked(bool locked) +{ + fDrawingModeLocked = locked; +} + + + void DrawState::SetPenLocation(BPoint location) { diff --git a/src/servers/app/DrawState.h b/src/servers/app/DrawState.h index e67e1ed2af..7e7274cdf3 100644 --- a/src/servers/app/DrawState.h +++ b/src/servers/app/DrawState.h @@ -111,6 +111,8 @@ public: alpha_function AlphaFncMode() const { return fAlphaFncMode; } + void SetDrawingModeLocked(bool locked); + // pen void SetPenLocation(BPoint location); BPoint PenLocation() const; @@ -173,6 +175,7 @@ protected: drawing_mode fDrawingMode; source_alpha fAlphaSrcMode; alpha_function fAlphaFncMode; + bool fDrawingModeLocked; BPoint fPenLocation; float fPenSize; diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index d0b1d01476..369e13454a 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -2197,6 +2197,13 @@ fDesktop->LockSingleWindow(); Layer* layer = new(std::nothrow) Layer(opacity); if (layer == NULL) break; + + if (opacity != 255) { + fCurrentView->CurrentState()->SetDrawingMode(B_OP_ALPHA); + fCurrentView->CurrentState()->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE); + fCurrentView->CurrentState()->SetDrawingModeLocked(true); + } + fCurrentView->SetPicture(layer); break; } @@ -2945,6 +2952,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, Title())); fCurrentView->BlendAllLayers(); fCurrentView->SetPicture(NULL); + fCurrentView->CurrentState()->SetDrawingModeLocked(false); break; } @@ -3009,11 +3017,6 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) int8 drawingMode; link.Read(&drawingMode); - if (dynamic_cast(picture) != NULL) { - // drawing mode changes not allowed in layers - break; - } - picture->WriteSetDrawingMode((drawing_mode)drawingMode); fCurrentView->CurrentState()->SetDrawingMode( @@ -3461,6 +3464,12 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) if (nextLayer == NULL) break; + if (opacity != 255) { + fCurrentView->CurrentState()->SetDrawingMode(B_OP_ALPHA); + fCurrentView->CurrentState()->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE); + fCurrentView->CurrentState()->SetDrawingModeLocked(true); + } + nextLayer->PushLayer(layer); fCurrentView->SetPicture(nextLayer); break; From e353fe396a362ab9c10a7c058e76007939370f66 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Mon, 3 Aug 2015 23:32:07 +0200 Subject: [PATCH 019/370] app_server Painter: refactoring, extract bitmap drawing * Extract bitmap drawing from Painter into separate class Painter::BitmapPainter. This will allow to add new optimized drawing modes without making Painter larger. * BitmapPainter itself is further decomposed into separate (method object) structs per drawing mode (currently, those are: generic, no scale, nearest neighbor, bilinear). New optimized implementations can be added by writing additional method objects and calling them from BitmapPainter. * DrawBitmapNoScale and DrawBitmapBilinear are implemented using CRTP. This removes the function pointer in the 'no scale' version, which was previously used to select the row copy type. In the bilinear version it untangles the three variants (default, low filter ratio, SIMD) into separate methods. * While BitmapPainter is a nested class in Painter, the specialized method objects are not. Instead, the AGG-specific data fields from Painter are moved into a new struct PainterAggInterface. This struct is passed to the method objects and allows them to access the Painter's AGG renderer/rasterizer/scanline containers/etc. Alternatives would be to make all the involved structs friends of Painter, or nesting them all, or exposing all of Painter's internals via getter methods -- all of these would be quite messy. The details of the bitmap painting implementations are intentionally hidden from Painter: there is no need for it to know about their internals -- it does not even know their type names. (Nesting or making them friend would expose their type names to Painter.) Furthermore, there is another level of information hiding between BitmapPainter and the DrawBitmap[...] method objects. BitmapPainter itself only needs to decide that it uses e.g. the bilinear version. It has no knowledge that DrawBitmapBilinear is internally made out of several structs implementing specially optimized versions. * Refactoring only, no functional change intended. Performance should be unaffected. --- src/servers/app/drawing/Painter/Jamfile | 4 + src/servers/app/drawing/Painter/Painter.cpp | 1055 +---------------- src/servers/app/drawing/Painter/Painter.h | 73 +- .../app/drawing/Painter/PainterAggInterface.h | 67 ++ .../Painter/bitmap_painter/BitmapPainter.cpp | 314 +++++ .../Painter/bitmap_painter/BitmapPainter.h | 60 + .../bitmap_painter/DrawBitmapBilinear.h | 520 ++++++++ .../bitmap_painter/DrawBitmapGeneric.h | 112 ++ .../DrawBitmapNearestNeighbor.h | 143 +++ .../bitmap_painter/DrawBitmapNoScale.h | 169 +++ .../painter_bilinear_scale.nasm | 0 11 files changed, 1425 insertions(+), 1092 deletions(-) create mode 100644 src/servers/app/drawing/Painter/PainterAggInterface.h create mode 100644 src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp create mode 100644 src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.h create mode 100644 src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapBilinear.h create mode 100644 src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapGeneric.h create mode 100644 src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNearestNeighbor.h create mode 100644 src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNoScale.h rename src/servers/app/drawing/Painter/{ => bitmap_painter}/painter_bilinear_scale.nasm (100%) diff --git a/src/servers/app/drawing/Painter/Jamfile b/src/servers/app/drawing/Painter/Jamfile index 47703c8b28..61bf424b85 100644 --- a/src/servers/app/drawing/Painter/Jamfile +++ b/src/servers/app/drawing/Painter/Jamfile @@ -12,6 +12,7 @@ UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter drawing_modes UseBuildFeatureHeaders freetype ; SEARCH_SOURCE += [ FDirName $(SUBDIR) drawing_modes ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) bitmap_painter ] ; local PAINTER_ARCH_SOURCES ; if $(TARGET_ARCH) = x86 { @@ -29,6 +30,9 @@ StaticLibrary libpainter.a : # drawing_modes PixelFormat.cpp + # bitmap_painter + BitmapPainter.cpp + AGGTextRenderer.cpp $(PAINTER_ARCH_SOURCES) diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 1ff042ceba..45cd532cc8 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -54,6 +54,7 @@ #include #include "AlphaMask.h" +#include "BitmapPainter.h" #include "DrawingMode.h" #include "GlobalSubpixelSettings.h" #include "PatternHandler.h" @@ -86,19 +87,28 @@ using std::nothrow; #define CHECK_CLIPPING if (!fValidClipping) return BRect(0, 0, -1, -1); #define CHECK_CLIPPING_NO_RETURN if (!fValidClipping) return; -// Defines for SIMD support. -#define APPSERVER_SIMD_MMX (1 << 0) -#define APPSERVER_SIMD_SSE (1 << 1) -// Prototypes for assembler routines -extern "C" { - void bilinear_scale_xloop_mmxsse(const uint8* src, void* dst, - void* xWeights, uint32 xmin, uint32 xmax, uint32 wTop, uint32 srcBPR); -} +// Shortcuts for accessing internal data +#define fBuffer fInternal.fBuffer +#define fPixelFormat fInternal.fPixelFormat +#define fBaseRenderer fInternal.fBaseRenderer +#define fUnpackedScanline fInternal.fUnpackedScanline +#define fPackedScanline fInternal.fPackedScanline +#define fRasterizer fInternal.fRasterizer +#define fRenderer fInternal.fRenderer +#define fRendererBin fInternal.fRendererBin +#define fSubpixPackedScanline fInternal.fSubpixPackedScanline +#define fSubpixUnpackedScanline fInternal.fSubpixUnpackedScanline +#define fSubpixRasterizer fInternal.fSubpixRasterizer +#define fSubpixRenderer fInternal.fSubpixRenderer +#define fMaskedUnpackedScanline fInternal.fMaskedUnpackedScanline +#define fPath fInternal.fPath +#define fCurve fInternal.fCurve + static uint32 detect_simd(); -static uint32 sSIMDFlags = detect_simd(); +uint32 gSIMDFlags = detect_simd(); /*! Detect SIMD flags for use in AppServer. Checks all CPUs in the system @@ -170,23 +180,7 @@ detect_simd() Painter::Painter() : - fBuffer(), - fPixelFormat(fBuffer, &fPatternHandler), - fBaseRenderer(fPixelFormat), - fUnpackedScanline(), - fPackedScanline(), - fRasterizer(), - fRenderer(fBaseRenderer), - fRendererBin(fBaseRenderer), - fSubpixPackedScanline(), - fSubpixUnpackedScanline(), - fSubpixRasterizer(), - fSubpixRenderer(fBaseRenderer), - fMaskedUnpackedScanline(NULL), - - fPath(), - fCurve(fPath), - + fInternal(fPatternHandler), fSubpixelPrecise(false), fValidClipping(false), fDrawingText(false), @@ -1431,27 +1425,11 @@ Painter::DrawBitmap(const ServerBitmap* bitmap, BRect bitmapRect, BRect touched = TransformAlignAndClipRect(viewRect); - if (bitmap && bitmap->IsValid() && touched.IsValid()) { - // the native bitmap coordinate system - BRect actualBitmapRect(bitmap->Bounds()); - - TRACE("Painter::DrawBitmap()\n"); - TRACE(" actualBitmapRect = (%.1f, %.1f) - (%.1f, %.1f)\n", - actualBitmapRect.left, actualBitmapRect.top, - actualBitmapRect.right, actualBitmapRect.bottom); - TRACE(" bitmapRect = (%.1f, %.1f) - (%.1f, %.1f)\n", - bitmapRect.left, bitmapRect.top, bitmapRect.right, - bitmapRect.bottom); - TRACE(" viewRect = (%.1f, %.1f) - (%.1f, %.1f)\n", - viewRect.left, viewRect.top, viewRect.right, viewRect.bottom); - - agg::rendering_buffer srcBuffer; - srcBuffer.attach(bitmap->Bits(), bitmap->Width(), bitmap->Height(), - bitmap->BytesPerRow()); - - _DrawBitmap(srcBuffer, bitmap->ColorSpace(), actualBitmapRect, - bitmapRect, viewRect, options); + if (touched.IsValid()) { + BitmapPainter bitmapPainter(this, bitmap, options); + bitmapPainter.Draw(bitmapRect, viewRect); } + return touched; } @@ -1642,61 +1620,6 @@ Painter::_DrawTriangle(BPoint pt1, BPoint pt2, BPoint pt3, bool fill) const } -// copy_bitmap_row_cmap8_copy -static inline void -copy_bitmap_row_cmap8_copy(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color* colorMap) -{ - uint32* d = (uint32*)dst; - const uint8* s = src; - while (numPixels--) { - const rgb_color c = colorMap[*s++]; - *d++ = (c.alpha << 24) | (c.red << 16) | (c.green << 8) | (c.blue); - } -} - - -// copy_bitmap_row_cmap8_over -static inline void -copy_bitmap_row_cmap8_over(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color* colorMap) -{ - uint32* d = (uint32*)dst; - const uint8* s = src; - while (numPixels--) { - const rgb_color c = colorMap[*s++]; - if (c.alpha) - *d = (c.alpha << 24) | (c.red << 16) | (c.green << 8) | (c.blue); - d++; - } -} - - -// copy_bitmap_row_bgr32_copy -static inline void -copy_bitmap_row_bgr32_copy(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color* colorMap) -{ - memcpy(dst, src, numPixels * 4); -} - - -// copy_bitmap_row_bgr32_over -static inline void -copy_bitmap_row_bgr32_over(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color* colorMap) -{ - uint32* d = (uint32*)dst; - uint32* s = (uint32*)src; - while (numPixels--) { - if (*s != B_TRANSPARENT_MAGIC_RGBA32) - *(uint32*)d = *(uint32*)s; - d++; - s++; - } -} - - void Painter::_IterateShapeData(const int32& opCount, const uint32* opList, const int32& ptCount, const BPoint* points, @@ -1764,935 +1687,6 @@ Painter::_IterateShapeData(const int32& opCount, const uint32* opList, } -// copy_bitmap_row_bgr32_alpha -static inline void -copy_bitmap_row_bgr32_alpha(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color* colorMap) -{ - uint32* d = (uint32*)dst; - int32 bytes = numPixels * 4; - uint8 buffer[bytes]; - uint8* b = buffer; - while (numPixels--) { - if (src[3] == 255) { - *(uint32*)b = *(uint32*)src; - } else { - *(uint32*)b = *d; - b[0] = ((src[0] - b[0]) * src[3] + (b[0] << 8)) >> 8; - b[1] = ((src[1] - b[1]) * src[3] + (b[1] << 8)) >> 8; - b[2] = ((src[2] - b[2]) * src[3] + (b[2] << 8)) >> 8; - } - d++; - b += 4; - src += 4; - } - memcpy(dst, buffer, bytes); -} - - -// _TransparentMagicToAlpha -template -void -Painter::_TransparentMagicToAlpha(sourcePixel* buffer, uint32 width, - uint32 height, uint32 sourceBytesPerRow, sourcePixel transparentMagic, - BBitmap* output) const -{ - uint8* sourceRow = (uint8*)buffer; - uint8* destRow = (uint8*)output->Bits(); - uint32 destBytesPerRow = output->BytesPerRow(); - - for (uint32 y = 0; y < height; y++) { - sourcePixel* pixel = (sourcePixel*)sourceRow; - uint32* destPixel = (uint32*)destRow; - for (uint32 x = 0; x < width; x++, pixel++, destPixel++) { - if (*pixel == transparentMagic) - *destPixel &= 0x00ffffff; - } - - sourceRow += sourceBytesPerRow; - destRow += destBytesPerRow; - } -} - - -// _DrawBitmap -void -Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format, - BRect actualBitmapRect, BRect bitmapRect, BRect viewRect, - uint32 options) const -{ - if (!fValidClipping - || !bitmapRect.IsValid() || !bitmapRect.Intersects(actualBitmapRect) - || !viewRect.IsValid()) { - return; - } - - if (!fSubpixelPrecise) { - align_rect_to_pixels(&bitmapRect); - align_rect_to_pixels(&viewRect); - } - - TRACE("Painter::_DrawBitmap()\n"); - TRACE(" bitmapRect = (%.1f, %.1f) - (%.1f, %.1f)\n", - bitmapRect.left, bitmapRect.top, bitmapRect.right, bitmapRect.bottom); - TRACE(" viewRect = (%.1f, %.1f) - (%.1f, %.1f)\n", - viewRect.left, viewRect.top, viewRect.right, viewRect.bottom); - - double xScale = (viewRect.Width() + 1) / (bitmapRect.Width() + 1); - double yScale = (viewRect.Height() + 1) / (bitmapRect.Height() + 1); - - if (xScale == 0.0 || yScale == 0.0) - return; - - // compensate for the lefttop offset the actualBitmapRect might have - // actualBitmapRect has the right size, but put it at B_ORIGIN - // bitmapRect is already in good coordinates - actualBitmapRect.OffsetBy(-actualBitmapRect.left, -actualBitmapRect.top); - - // constrain rect to passed bitmap bounds - // and transfer the changes to the viewRect with the right scale - if (bitmapRect.left < actualBitmapRect.left) { - float diff = actualBitmapRect.left - bitmapRect.left; - viewRect.left += diff * xScale; - bitmapRect.left = actualBitmapRect.left; - } - if (bitmapRect.top < actualBitmapRect.top) { - float diff = actualBitmapRect.top - bitmapRect.top; - viewRect.top += diff * yScale; - bitmapRect.top = actualBitmapRect.top; - } - if (bitmapRect.right > actualBitmapRect.right) { - float diff = bitmapRect.right - actualBitmapRect.right; - viewRect.right -= diff * xScale; - bitmapRect.right = actualBitmapRect.right; - } - if (bitmapRect.bottom > actualBitmapRect.bottom) { - float diff = bitmapRect.bottom - actualBitmapRect.bottom; - viewRect.bottom -= diff * yScale; - bitmapRect.bottom = actualBitmapRect.bottom; - } - - double xOffset = viewRect.left - bitmapRect.left; - double yOffset = viewRect.top - bitmapRect.top; - - // optimized code path for B_CMAP8 and no scale - if (xScale == 1.0 && yScale == 1.0 && fIdentityTransform - && fMaskedUnpackedScanline == NULL) { - if (format == B_CMAP8) { - if (fDrawingMode == B_OP_COPY) { - _DrawBitmapNoScale32(copy_bitmap_row_cmap8_copy, 1, - srcBuffer, (int32)xOffset, (int32)yOffset, viewRect); - return; - } - if (fDrawingMode == B_OP_OVER) { - _DrawBitmapNoScale32(copy_bitmap_row_cmap8_over, 1, - srcBuffer, (int32)xOffset, (int32)yOffset, viewRect); - return; - } - } else if (format == B_RGB32) { - if (fDrawingMode == B_OP_OVER) { - _DrawBitmapNoScale32(copy_bitmap_row_bgr32_over, 4, - srcBuffer, (int32)xOffset, (int32)yOffset, viewRect); - return; - } - } - } - - BBitmap* temp = NULL; - ObjectDeleter tempDeleter; - - if ((format != B_RGBA32 && format != B_RGB32) - || (format == B_RGB32 && fDrawingMode != B_OP_COPY -#if 1 -// Enabling this would make the behavior compatible to BeOS, which -// treats B_RGB32 bitmaps as B_RGB*A*32 bitmaps in B_OP_ALPHA - unlike in -// all other drawing modes, where B_TRANSPARENT_MAGIC_RGBA32 is handled. -// B_RGB32 bitmaps therefore don't draw correctly on BeOS if they actually -// use this color, unless the alpha channel contains 255 for all other -// pixels, which is inconsistent. - && fDrawingMode != B_OP_ALPHA -#endif - )) { - temp = new (nothrow) BBitmap(actualBitmapRect, B_BITMAP_NO_SERVER_LINK, - B_RGBA32); - if (temp == NULL) { - fprintf(stderr, "Painter::_DrawBitmap() - " - "out of memory for creating temporary conversion bitmap\n"); - return; - } - - tempDeleter.SetTo(temp); - - status_t err = temp->ImportBits(srcBuffer.buf(), - srcBuffer.height() * srcBuffer.stride(), - srcBuffer.stride(), 0, format); - if (err < B_OK) { - fprintf(stderr, "Painter::_DrawBitmap() - " - "colorspace conversion failed: %s\n", strerror(err)); - return; - } - - // the original bitmap might have had some of the - // transaparent magic colors set that we now need to - // make transparent in our RGBA32 bitmap again. - switch (format) { - case B_RGB32: - _TransparentMagicToAlpha((uint32 *)srcBuffer.buf(), - srcBuffer.width(), srcBuffer.height(), - srcBuffer.stride(), B_TRANSPARENT_MAGIC_RGBA32, - temp); - break; - - // TODO: not sure if this applies to B_RGBA15 too. It - // should not because B_RGBA15 actually has an alpha - // channel itself and it should have been preserved - // when importing the bitmap. Maybe it applies to - // B_RGB16 though? - case B_RGB15: - _TransparentMagicToAlpha((uint16 *)srcBuffer.buf(), - srcBuffer.width(), srcBuffer.height(), - srcBuffer.stride(), B_TRANSPARENT_MAGIC_RGBA15, - temp); - break; - - default: - break; - } - - srcBuffer.attach((uint8*)temp->Bits(), - (uint32)actualBitmapRect.IntegerWidth() + 1, - (uint32)actualBitmapRect.IntegerHeight() + 1, - temp->BytesPerRow()); - } - - // maybe we can use an optimized version if there is no scale - if (xScale == 1.0 && yScale == 1.0 && fIdentityTransform - && fMaskedUnpackedScanline == NULL) { - if (fDrawingMode == B_OP_COPY) { - _DrawBitmapNoScale32(copy_bitmap_row_bgr32_copy, 4, srcBuffer, - (int32)xOffset, (int32)yOffset, viewRect); - return; - } - if (fDrawingMode == B_OP_OVER || (fDrawingMode == B_OP_ALPHA - && fAlphaSrcMode == B_PIXEL_ALPHA - && fAlphaFncMode == B_ALPHA_OVERLAY)) { - _DrawBitmapNoScale32(copy_bitmap_row_bgr32_alpha, 4, srcBuffer, - (int32)xOffset, (int32)yOffset, viewRect); - return; - } - } - - if (fDrawingMode == B_OP_COPY && fIdentityTransform - && fMaskedUnpackedScanline == NULL) { - if ((options & B_FILTER_BITMAP_BILINEAR) != 0) { - _DrawBitmapBilinearCopy32(srcBuffer, xOffset, yOffset, xScale, - yScale, viewRect); - } else { - _DrawBitmapNearestNeighborCopy32(srcBuffer, xOffset, yOffset, - xScale, yScale, viewRect); - } - return; - } - - // for all other cases (non-optimized drawing mode or scaled drawing) - _DrawBitmapGeneric32(srcBuffer, xOffset, yOffset, xScale, yScale, viewRect, - options); -} - - -#define DEBUG_DRAW_BITMAP 0 - - -// _DrawBitmapNoScale32 -template -void -Painter::_DrawBitmapNoScale32(F copyRowFunction, uint32 bytesPerSourcePixel, - agg::rendering_buffer& srcBuffer, int32 xOffset, int32 yOffset, - BRect viewRect) const -{ - // NOTE: this would crash if viewRect was large enough to read outside the - // bitmap, so make sure this is not the case before calling this function! - uint8* dst = fBuffer.row_ptr(0); - uint32 dstBPR = fBuffer.stride(); - - const uint8* src = srcBuffer.row_ptr(0); - uint32 srcBPR = srcBuffer.stride(); - - int32 left = (int32)viewRect.left; - int32 top = (int32)viewRect.top; - int32 right = (int32)viewRect.right; - int32 bottom = (int32)viewRect.bottom; - -#if DEBUG_DRAW_BITMAP -if (left - xOffset < 0 || left - xOffset >= (int32)srcBuffer.width() || - right - xOffset >= (int32)srcBuffer.width() || - top - yOffset < 0 || top - yOffset >= (int32)srcBuffer.height() || - bottom - yOffset >= (int32)srcBuffer.height()) { - - char message[256]; - sprintf(message, "reading outside of bitmap (%ld, %ld, %ld, %ld) " - "(%d, %d) (%ld, %ld)", - left - xOffset, top - yOffset, right - xOffset, bottom - yOffset, - srcBuffer.width(), srcBuffer.height(), xOffset, yOffset); - debugger(message); -} -#endif - - const rgb_color* colorMap = SystemPalette(); - - // copy rects, iterate over clipping boxes - fBaseRenderer.first_clip_box(); - do { - int32 x1 = max_c(fBaseRenderer.xmin(), left); - int32 x2 = min_c(fBaseRenderer.xmax(), right); - if (x1 <= x2) { - int32 y1 = max_c(fBaseRenderer.ymin(), top); - int32 y2 = min_c(fBaseRenderer.ymax(), bottom); - if (y1 <= y2) { - uint8* dstHandle = dst + y1 * dstBPR + x1 * 4; - const uint8* srcHandle = src + (y1 - yOffset) * srcBPR - + (x1 - xOffset) * bytesPerSourcePixel; - - for (; y1 <= y2; y1++) { - copyRowFunction(dstHandle, srcHandle, x2 - x1 + 1, colorMap); - - dstHandle += dstBPR; - srcHandle += srcBPR; - } - } - } - } while (fBaseRenderer.next_clip_box()); -} - - -// _DrawBitmapNearestNeighborCopy32 -void -Painter::_DrawBitmapNearestNeighborCopy32(agg::rendering_buffer& srcBuffer, - double xOffset, double yOffset, double xScale, double yScale, - BRect viewRect) const -{ - //bigtime_t now = system_time(); - uint32 dstWidth = viewRect.IntegerWidth() + 1; - uint32 dstHeight = viewRect.IntegerHeight() + 1; - uint32 srcWidth = srcBuffer.width(); - uint32 srcHeight = srcBuffer.height(); - - // Do not calculate more filter weights than necessary and also - // keep the stack based allocations reasonably sized - if (fClippingRegion->Frame().IntegerWidth() + 1 < (int32)dstWidth) - dstWidth = fClippingRegion->Frame().IntegerWidth() + 1; - if (fClippingRegion->Frame().IntegerHeight() + 1 < (int32)dstHeight) - dstHeight = fClippingRegion->Frame().IntegerHeight() + 1; - - // When calculating less filter weights than specified by viewRect, - // we need to compensate the offset. - uint32 filterWeightXIndexOffset = 0; - uint32 filterWeightYIndexOffset = 0; - if (fClippingRegion->Frame().left > viewRect.left) { - filterWeightXIndexOffset = (int32)(fClippingRegion->Frame().left - - viewRect.left); - } - if (fClippingRegion->Frame().top > viewRect.top) { - filterWeightYIndexOffset = (int32)(fClippingRegion->Frame().top - - viewRect.top); - } - - // should not pose a problem with stack overflows - // (needs around 6Kb for 1920x1200) - uint16 xIndices[dstWidth]; - uint16 yIndices[dstHeight]; - - // Extract the cropping information for the source bitmap, - // If only a part of the source bitmap is to be drawn with scale, - // the offset will be different from the viewRect left top corner. - int32 xBitmapShift = (int32)(viewRect.left - xOffset); - int32 yBitmapShift = (int32)(viewRect.top - yOffset); - - for (uint32 i = 0; i < dstWidth; i++) { - // index into source - uint16 index = (uint16)((i + filterWeightXIndexOffset) * srcWidth - / (srcWidth * xScale)); - // round down to get the left pixel - xIndices[i] = index; - // handle cropped source bitmap - xIndices[i] += xBitmapShift; - // precompute index for 32 bit pixels - xIndices[i] *= 4; - } - - for (uint32 i = 0; i < dstHeight; i++) { - // index into source - uint16 index = (uint16)((i + filterWeightYIndexOffset) * srcHeight - / (srcHeight * yScale)); - // round down to get the top pixel - yIndices[i] = index; - // handle cropped source bitmap - yIndices[i] += yBitmapShift; - } -//printf("X: %d ... %d, %d (%ld or %f)\n", -// xIndices[0], xIndices[dstWidth - 2], xIndices[dstWidth - 1], dstWidth, -// srcWidth * xScale); -//printf("Y: %d ... %d, %d (%ld or %f)\n", -// yIndices[0], yIndices[dstHeight - 2], yIndices[dstHeight - 1], dstHeight, -// srcHeight * yScale); - - const int32 left = (int32)viewRect.left; - const int32 top = (int32)viewRect.top; - const int32 right = (int32)viewRect.right; - const int32 bottom = (int32)viewRect.bottom; - - const uint32 dstBPR = fBuffer.stride(); - - // iterate over clipping boxes - fBaseRenderer.first_clip_box(); - do { - const int32 x1 = max_c(fBaseRenderer.xmin(), left); - const int32 x2 = min_c(fBaseRenderer.xmax(), right); - if (x1 > x2) - continue; - - int32 y1 = max_c(fBaseRenderer.ymin(), top); - int32 y2 = min_c(fBaseRenderer.ymax(), bottom); - if (y1 > y2) - continue; - - // buffer offset into destination - uint8* dst = fBuffer.row_ptr(y1) + x1 * 4; - - // x and y are needed as indeces into the wheight arrays, so the - // offset into the target buffer needs to be compensated - const int32 xIndexL = x1 - left - filterWeightXIndexOffset; - const int32 xIndexR = x2 - left - filterWeightXIndexOffset; - y1 -= top + filterWeightYIndexOffset; - y2 -= top + filterWeightYIndexOffset; - -//printf("x: %ld - %ld\n", xIndexL, xIndexR); -//printf("y: %ld - %ld\n", y1, y2); - - for (; y1 <= y2; y1++) { - // buffer offset into source (top row) - register const uint8* src = srcBuffer.row_ptr(yIndices[y1]); - // buffer handle for destination to be incremented per pixel - register uint32* d = (uint32*)dst; - - for (int32 x = xIndexL; x <= xIndexR; x++) { - *d = *(uint32*)(src + xIndices[x]); - d++; - } - dst += dstBPR; - } - } while (fBaseRenderer.next_clip_box()); - -//printf("draw bitmap %.5fx%.5f: %lld\n", xScale, yScale, system_time() - now); -} - - -// _DrawBitmapBilinearCopy32 -void -Painter::_DrawBitmapBilinearCopy32(agg::rendering_buffer& srcBuffer, - double xOffset, double yOffset, double xScale, double yScale, - BRect viewRect) const -{ - //bigtime_t now = system_time(); - uint32 dstWidth = viewRect.IntegerWidth() + 1; - uint32 dstHeight = viewRect.IntegerHeight() + 1; - uint32 srcWidth = srcBuffer.width(); - uint32 srcHeight = srcBuffer.height(); - - // Do not calculate more filter weights than necessary and also - // keep the stack based allocations reasonably sized - if (fClippingRegion->Frame().IntegerWidth() + 1 < (int32)dstWidth) - dstWidth = fClippingRegion->Frame().IntegerWidth() + 1; - if (fClippingRegion->Frame().IntegerHeight() + 1 < (int32)dstHeight) - dstHeight = fClippingRegion->Frame().IntegerHeight() + 1; - - // When calculating less filter weights than specified by viewRect, - // we need to compensate the offset. - uint32 filterWeightXIndexOffset = 0; - uint32 filterWeightYIndexOffset = 0; - if (fClippingRegion->Frame().left > viewRect.left) { - filterWeightXIndexOffset = (int32)(fClippingRegion->Frame().left - - viewRect.left); - } - if (fClippingRegion->Frame().top > viewRect.top) { - filterWeightYIndexOffset = (int32)(fClippingRegion->Frame().top - - viewRect.top); - } - - struct FilterInfo { - uint16 index; // index into source bitmap row/column - uint16 weight; // weight of the pixel at index [0..255] - }; - -//#define FILTER_INFOS_ON_HEAP -#ifdef FILTER_INFOS_ON_HEAP - FilterInfo* xWeights = new (nothrow) FilterInfo[dstWidth]; - FilterInfo* yWeights = new (nothrow) FilterInfo[dstHeight]; - if (xWeights == NULL || yWeights == NULL) { - delete[] xWeights; - delete[] yWeights; - return; - } -#else - // stack based saves about 200µs on 1.85 GHz Core 2 Duo - // should not pose a problem with stack overflows - // (needs around 12Kb for 1920x1200) - FilterInfo xWeights[dstWidth]; - FilterInfo yWeights[dstHeight]; -#endif - - // Extract the cropping information for the source bitmap, - // If only a part of the source bitmap is to be drawn with scale, - // the offset will be different from the viewRect left top corner. - int32 xBitmapShift = (int32)(viewRect.left - xOffset); - int32 yBitmapShift = (int32)(viewRect.top - yOffset); - - for (uint32 i = 0; i < dstWidth; i++) { - // fractional index into source - // NOTE: It is very important to calculate the fractional index - // into the source pixel grid like this to prevent out of bounds - // access! It will result in the rightmost pixel of the destination - // to access the rightmost pixel of the source with a weighting - // of 255. This in turn will trigger an optimization in the loop - // that also prevents out of bounds access. - float index = (i + filterWeightXIndexOffset) * (srcWidth - 1) - / (srcWidth * xScale - 1); - // round down to get the left pixel - xWeights[i].index = (uint16)index; - xWeights[i].weight = 255 - (uint16)((index - xWeights[i].index) * 255); - // handle cropped source bitmap - xWeights[i].index += xBitmapShift; - // precompute index for 32 bit pixels - xWeights[i].index *= 4; - } - - for (uint32 i = 0; i < dstHeight; i++) { - // fractional index into source - // NOTE: It is very important to calculate the fractional index - // into the source pixel grid like this to prevent out of bounds - // access! It will result in the bottommost pixel of the destination - // to access the bottommost pixel of the source with a weighting - // of 255. This in turn will trigger an optimization in the loop - // that also prevents out of bounds access. - float index = (i + filterWeightYIndexOffset) * (srcHeight - 1) - / (srcHeight * yScale - 1); - // round down to get the top pixel - yWeights[i].index = (uint16)index; - yWeights[i].weight = 255 - (uint16)((index - yWeights[i].index) * 255); - // handle cropped source bitmap - yWeights[i].index += yBitmapShift; - } -//printf("X: %d/%d ... %d/%d, %d/%d (%ld)\n", -// xWeights[0].index, xWeights[0].weight, -// xWeights[dstWidth - 2].index, xWeights[dstWidth - 2].weight, -// xWeights[dstWidth - 1].index, xWeights[dstWidth - 1].weight, -// dstWidth); -//printf("Y: %d/%d ... %d/%d, %d/%d (%ld)\n", -// yWeights[0].index, yWeights[0].weight, -// yWeights[dstHeight - 2].index, yWeights[dstHeight - 2].weight, -// yWeights[dstHeight - 1].index, yWeights[dstHeight - 1].weight, -// dstHeight); - - const int32 left = (int32)viewRect.left; - const int32 top = (int32)viewRect.top; - const int32 right = (int32)viewRect.right; - const int32 bottom = (int32)viewRect.bottom; - - const uint32 dstBPR = fBuffer.stride(); - const uint32 srcBPR = srcBuffer.stride(); - - // Figure out which version of the code we want to use... - enum { - kOptimizeForLowFilterRatio = 0, - kUseDefaultVersion, - kUseSIMDVersion - }; - - int codeSelect = kUseDefaultVersion; - - uint32 neededSIMDFlags = APPSERVER_SIMD_MMX | APPSERVER_SIMD_SSE; - if ((sSIMDFlags & neededSIMDFlags) == neededSIMDFlags) - codeSelect = kUseSIMDVersion; - else { - if (xScale == yScale && (xScale == 1.5 || xScale == 2.0 - || xScale == 2.5 || xScale == 3.0)) { - codeSelect = kOptimizeForLowFilterRatio; - } - } - - // iterate over clipping boxes - fBaseRenderer.first_clip_box(); - do { - const int32 x1 = max_c(fBaseRenderer.xmin(), left); - const int32 x2 = min_c(fBaseRenderer.xmax(), right); - if (x1 > x2) - continue; - - int32 y1 = max_c(fBaseRenderer.ymin(), top); - int32 y2 = min_c(fBaseRenderer.ymax(), bottom); - if (y1 > y2) - continue; - - // buffer offset into destination - uint8* dst = fBuffer.row_ptr(y1) + x1 * 4; - - // x and y are needed as indeces into the wheight arrays, so the - // offset into the target buffer needs to be compensated - const int32 xIndexL = x1 - left - filterWeightXIndexOffset; - const int32 xIndexR = x2 - left - filterWeightXIndexOffset; - y1 -= top + filterWeightYIndexOffset; - y2 -= top + filterWeightYIndexOffset; - -//printf("x: %ld - %ld\n", xIndexL, xIndexR); -//printf("y: %ld - %ld\n", y1, y2); - - switch (codeSelect) { - case kOptimizeForLowFilterRatio: - { - // In this mode, we anticipate to hit many destination pixels - // that map directly to a source pixel, we have more branches - // in the inner loop but save time because of the special - // cases. If there are too few direct hit pixels, the branches - // only waste time. - for (; y1 <= y2; y1++) { - // cache the weight of the top and bottom row - const uint16 wTop = yWeights[y1].weight; - const uint16 wBottom = 255 - yWeights[y1].weight; - - // buffer offset into source (top row) - register const uint8* src - = srcBuffer.row_ptr(yWeights[y1].index); - // buffer handle for destination to be incremented per - // pixel - register uint8* d = dst; - - if (wTop == 255) { - for (int32 x = xIndexL; x <= xIndexR; x++) { - const uint8* s = src + xWeights[x].index; - // This case is important to prevent out - // of bounds access at bottom edge of the source - // bitmap. If the scale is low and integer, it will - // also help the speed. - if (xWeights[x].weight == 255) { - // As above, but to prevent out of bounds - // on the right edge. - *(uint32*)d = *(uint32*)s; - } else { - // Only the left and right pixels are - // interpolated, since the top row has 100% - // weight. - const uint16 wLeft = xWeights[x].weight; - const uint16 wRight = 255 - wLeft; - d[0] = (s[0] * wLeft + s[4] * wRight) >> 8; - d[1] = (s[1] * wLeft + s[5] * wRight) >> 8; - d[2] = (s[2] * wLeft + s[6] * wRight) >> 8; - } - d += 4; - } - } else { - for (int32 x = xIndexL; x <= xIndexR; x++) { - const uint8* s = src + xWeights[x].index; - if (xWeights[x].weight == 255) { - // Prevent out of bounds access on the right - // edge or simply speed up. - const uint8* sBottom = s + srcBPR; - d[0] = (s[0] * wTop + sBottom[0] * wBottom) - >> 8; - d[1] = (s[1] * wTop + sBottom[1] * wBottom) - >> 8; - d[2] = (s[2] * wTop + sBottom[2] * wBottom) - >> 8; - } else { - // calculate the weighted sum of all four - // interpolated pixels - const uint16 wLeft = xWeights[x].weight; - const uint16 wRight = 255 - wLeft; - // left and right of top row - uint32 t0 = (s[0] * wLeft + s[4] * wRight) - * wTop; - uint32 t1 = (s[1] * wLeft + s[5] * wRight) - * wTop; - uint32 t2 = (s[2] * wLeft + s[6] * wRight) - * wTop; - - // left and right of bottom row - s += srcBPR; - t0 += (s[0] * wLeft + s[4] * wRight) * wBottom; - t1 += (s[1] * wLeft + s[5] * wRight) * wBottom; - t2 += (s[2] * wLeft + s[6] * wRight) * wBottom; - - d[0] = t0 >> 16; - d[1] = t1 >> 16; - d[2] = t2 >> 16; - } - d += 4; - } - } - dst += dstBPR; - } - break; - } - - case kUseDefaultVersion: - { - // In this mode we anticipate many pixels wich need filtering, - // there are no special cases for direct hit pixels except for - // the last column/row and the right/bottom corner pixel. - - // The last column/row handling does not need to be performed - // for all clipping rects! - int32 yMax = y2; - if (yWeights[yMax].weight == 255) - yMax--; - int32 xIndexMax = xIndexR; - if (xWeights[xIndexMax].weight == 255) - xIndexMax--; - - for (; y1 <= yMax; y1++) { - // cache the weight of the top and bottom row - const uint16 wTop = yWeights[y1].weight; - const uint16 wBottom = 255 - yWeights[y1].weight; - - // buffer offset into source (top row) - register const uint8* src - = srcBuffer.row_ptr(yWeights[y1].index); - // buffer handle for destination to be incremented per - // pixel - register uint8* d = dst; - - for (int32 x = xIndexL; x <= xIndexMax; x++) { - const uint8* s = src + xWeights[x].index; - // calculate the weighted sum of all four - // interpolated pixels - const uint16 wLeft = xWeights[x].weight; - const uint16 wRight = 255 - wLeft; - // left and right of top row - uint32 t0 = (s[0] * wLeft + s[4] * wRight) * wTop; - uint32 t1 = (s[1] * wLeft + s[5] * wRight) * wTop; - uint32 t2 = (s[2] * wLeft + s[6] * wRight) * wTop; - - // left and right of bottom row - s += srcBPR; - t0 += (s[0] * wLeft + s[4] * wRight) * wBottom; - t1 += (s[1] * wLeft + s[5] * wRight) * wBottom; - t2 += (s[2] * wLeft + s[6] * wRight) * wBottom; - d[0] = t0 >> 16; - d[1] = t1 >> 16; - d[2] = t2 >> 16; - d += 4; - } - // last column of pixels if necessary - if (xIndexMax < xIndexR) { - const uint8* s = src + xWeights[xIndexR].index; - const uint8* sBottom = s + srcBPR; - d[0] = (s[0] * wTop + sBottom[0] * wBottom) >> 8; - d[1] = (s[1] * wTop + sBottom[1] * wBottom) >> 8; - d[2] = (s[2] * wTop + sBottom[2] * wBottom) >> 8; - } - - dst += dstBPR; - } - - // last row of pixels if necessary - // buffer offset into source (bottom row) - register const uint8* src - = srcBuffer.row_ptr(yWeights[y2].index); - // buffer handle for destination to be incremented per pixel - register uint8* d = dst; - - if (yMax < y2) { - for (int32 x = xIndexL; x <= xIndexMax; x++) { - const uint8* s = src + xWeights[x].index; - const uint16 wLeft = xWeights[x].weight; - const uint16 wRight = 255 - wLeft; - d[0] = (s[0] * wLeft + s[4] * wRight) >> 8; - d[1] = (s[1] * wLeft + s[5] * wRight) >> 8; - d[2] = (s[2] * wLeft + s[6] * wRight) >> 8; - d += 4; - } - } - - // pixel in bottom right corner if necessary - if (yMax < y2 && xIndexMax < xIndexR) { - const uint8* s = src + xWeights[xIndexR].index; - *(uint32*)d = *(uint32*)s; - } - break; - } - -#ifdef __INTEL__ - case kUseSIMDVersion: - { - // Basically the same as the "standard" mode, but we use SIMD - // routines for the processing of the single display lines. - - // The last column/row handling does not need to be performed - // for all clipping rects! - int32 yMax = y2; - if (yWeights[yMax].weight == 255) - yMax--; - int32 xIndexMax = xIndexR; - if (xWeights[xIndexMax].weight == 255) - xIndexMax--; - - for (; y1 <= yMax; y1++) { - // cache the weight of the top and bottom row - const uint16 wTop = yWeights[y1].weight; - const uint16 wBottom = 255 - yWeights[y1].weight; - - // buffer offset into source (top row) - const uint8* src = srcBuffer.row_ptr(yWeights[y1].index); - // buffer handle for destination to be incremented per - // pixel - uint8* d = dst; - bilinear_scale_xloop_mmxsse(src, dst, xWeights, xIndexL, - xIndexMax, wTop, srcBPR); - // increase pointer by processed pixels - d += (xIndexMax - xIndexL + 1) * 4; - - // last column of pixels if necessary - if (xIndexMax < xIndexR) { - const uint8* s = src + xWeights[xIndexR].index; - const uint8* sBottom = s + srcBPR; - d[0] = (s[0] * wTop + sBottom[0] * wBottom) >> 8; - d[1] = (s[1] * wTop + sBottom[1] * wBottom) >> 8; - d[2] = (s[2] * wTop + sBottom[2] * wBottom) >> 8; - } - - dst += dstBPR; - } - - // last row of pixels if necessary - // buffer offset into source (bottom row) - register const uint8* src - = srcBuffer.row_ptr(yWeights[y2].index); - // buffer handle for destination to be incremented per pixel - register uint8* d = dst; - - if (yMax < y2) { - for (int32 x = xIndexL; x <= xIndexMax; x++) { - const uint8* s = src + xWeights[x].index; - const uint16 wLeft = xWeights[x].weight; - const uint16 wRight = 255 - wLeft; - d[0] = (s[0] * wLeft + s[4] * wRight) >> 8; - d[1] = (s[1] * wLeft + s[5] * wRight) >> 8; - d[2] = (s[2] * wLeft + s[6] * wRight) >> 8; - d += 4; - } - } - - // pixel in bottom right corner if necessary - if (yMax < y2 && xIndexMax < xIndexR) { - const uint8* s = src + xWeights[xIndexR].index; - *(uint32*)d = *(uint32*)s; - } - break; - } -#endif // __INTEL__ - } - } while (fBaseRenderer.next_clip_box()); - -#ifdef FILTER_INFOS_ON_HEAP - delete[] xWeights; - delete[] yWeights; -#endif -//printf("draw bitmap %.5fx%.5f: %lld\n", xScale, yScale, system_time() - now); -} - - -// _DrawBitmapGeneric32 -void -Painter::_DrawBitmapGeneric32(agg::rendering_buffer& srcBuffer, - double xOffset, double yOffset, double xScale, double yScale, - BRect viewRect, uint32 options) const -{ - TRACE("Painter::_DrawBitmapGeneric32()\n"); - TRACE(" offset: %.1f, %.1f\n", xOffset, yOffset); - TRACE(" scale: %.3f, %.3f\n", xScale, yScale); - TRACE(" viewRect: (%.1f, %.1f) - (%.1f, %.1f)\n", - viewRect.left, viewRect.top, viewRect.right, viewRect.bottom); - // AGG pipeline - - // pixel format attached to bitmap - typedef agg::pixfmt_bgra32 pixfmt_image; - pixfmt_image pixf_img(srcBuffer); - - agg::trans_affine srcMatrix; - // NOTE: R5 seems to ignore this offset when drawing bitmaps - // srcMatrix *= agg::trans_affine_translation(-actualBitmapRect.left, - // -actualBitmapRect.top); - srcMatrix *= fTransform; - - agg::trans_affine imgMatrix; - imgMatrix *= agg::trans_affine_translation(xOffset - viewRect.left, - yOffset - viewRect.top); - imgMatrix *= agg::trans_affine_scaling(xScale, yScale); - imgMatrix *= agg::trans_affine_translation(viewRect.left, viewRect.top); - imgMatrix *= fTransform; - imgMatrix.invert(); - - // image interpolator - typedef agg::span_interpolator_linear<> interpolator_type; - interpolator_type interpolator(imgMatrix); - - // scanline allocator - agg::span_allocator spanAllocator; - - // image accessor attached to pixel format of bitmap - typedef agg::image_accessor_clone source_type; - source_type source(pixf_img); - - // clip to the current clipping region's frame - if (fIdentityTransform) - viewRect = viewRect & fClippingRegion->Frame(); - // convert to pixel coords (versus pixel indices) - viewRect.right++; - viewRect.bottom++; - - // path enclosing the bitmap - fPath.remove_all(); - fPath.move_to(viewRect.left, viewRect.top); - fPath.line_to(viewRect.right, viewRect.top); - fPath.line_to(viewRect.right, viewRect.bottom); - fPath.line_to(viewRect.left, viewRect.bottom); - fPath.close_polygon(); - - agg::conv_transform transformedPath(fPath, srcMatrix); - fRasterizer.reset(); - fRasterizer.add_path(transformedPath); - - if ((options & B_FILTER_BITMAP_BILINEAR) != 0) { - // image filter (bilinear) - typedef agg::span_image_filter_rgba_bilinear< - source_type, interpolator_type> span_gen_type; - span_gen_type spanGenerator(source, interpolator); - - // render the path with the bitmap as scanline fill - if (fMaskedUnpackedScanline != NULL) { - agg::render_scanlines_aa(fRasterizer, *fMaskedUnpackedScanline, - fBaseRenderer, spanAllocator, spanGenerator); - } else { - agg::render_scanlines_aa(fRasterizer, fUnpackedScanline, - fBaseRenderer, spanAllocator, spanGenerator); - } - } else { - // image filter (nearest neighbor) - typedef agg::span_image_filter_rgba_nn< - source_type, interpolator_type> span_gen_type; - span_gen_type spanGenerator(source, interpolator); - - // render the path with the bitmap as scanline fill - if (fMaskedUnpackedScanline != NULL) { - agg::render_scanlines_aa(fRasterizer, *fMaskedUnpackedScanline, - fBaseRenderer, spanAllocator, spanGenerator); - } else { - agg::render_scanlines_aa(fRasterizer, fUnpackedScanline, - fBaseRenderer, spanAllocator, spanGenerator); - } - } -} - - // _InvertRect32 void Painter::_InvertRect32(BRect r) const @@ -3132,4 +2126,3 @@ Painter::_RasterizePath(VertexSource& path, const BGradient& gradient, gradientRenderer); } } - diff --git a/src/servers/app/drawing/Painter/Painter.h b/src/servers/app/drawing/Painter/Painter.h index 4402113438..fc22b08193 100644 --- a/src/servers/app/drawing/Painter/Painter.h +++ b/src/servers/app/drawing/Painter/Painter.h @@ -14,6 +14,7 @@ #include "AGGTextRenderer.h" #include "FontManager.h" +#include "PainterAggInterface.h" #include "PatternHandler.h" #include "ServerFont.h" #include "Transformable.h" @@ -21,7 +22,6 @@ #include "defines.h" #include -#include #include #include @@ -43,6 +43,11 @@ class ServerBitmap; class ServerFont; +// Defines for SIMD support. +#define APPSERVER_SIMD_MMX (1 << 0) +#define APPSERVER_SIMD_SSE (1 << 1) + + class Painter { public: Painter(); @@ -68,6 +73,8 @@ public: inline bool IsIdentityTransform() const { return fIdentityTransform; } + const Transformable& Transform() const + { return fTransform; } void SetHighColor(const rgb_color& color); inline rgb_color HighColor() const @@ -273,41 +280,6 @@ private: const BPoint& viewToScreenOffset, float viewScale) const; - template - void _TransparentMagicToAlpha(sourcePixel *buffer, - uint32 width, uint32 height, - uint32 sourceBytesPerRow, - sourcePixel transparentMagic, - BBitmap *output) const; - - void _DrawBitmap(agg::rendering_buffer& srcBuffer, - color_space format, - BRect actualBitmapRect, - BRect bitmapRect, BRect viewRect, - uint32 bitmapFlags) const; - template - void _DrawBitmapNoScale32( F copyRowFunction, - uint32 bytesPerSourcePixel, - agg::rendering_buffer& srcBuffer, - int32 xOffset, int32 yOffset, - BRect viewRect) const; - void _DrawBitmapNearestNeighborCopy32( - agg::rendering_buffer& srcBuffer, - double xOffset, double yOffset, - double xScale, double yScale, - BRect viewRect) const; - void _DrawBitmapBilinearCopy32( - agg::rendering_buffer& srcBuffer, - double xOffset, double yOffset, - double xScale, double yScale, - BRect viewRect) const; - void _DrawBitmapGeneric32( - agg::rendering_buffer& srcBuffer, - double xOffset, double yOffset, - double xScale, double yScale, - BRect viewRect, - uint32 bitmapFlags) const; - void _InvertRect32(BRect r) const; void _BlendRect32(const BRect& r, const rgb_color& c) const; @@ -356,33 +328,12 @@ private: int gradientStop = 100) const; private: - mutable agg::rendering_buffer fBuffer; + class BitmapPainter; - // AGG rendering and rasterization classes - pixfmt fPixelFormat; - mutable renderer_base fBaseRenderer; + friend class BitmapPainter; // needed only for gcc2 - // Regular drawing mode: pixel-aligned, no alpha masking - mutable scanline_unpacked_type fUnpackedScanline; - mutable scanline_packed_type fPackedScanline; - mutable rasterizer_type fRasterizer; - mutable renderer_type fRenderer; - - // Fast mode: no antialiasing needed (horizontal/vertical lines, ...) - mutable renderer_bin_type fRendererBin; - - // Subpixel mode - mutable scanline_packed_subpix_type fSubpixPackedScanline; - mutable scanline_unpacked_subpix_type fSubpixUnpackedScanline; - mutable rasterizer_subpix_type fSubpixRasterizer; - mutable renderer_subpix_type fSubpixRenderer; - - // Alpha-Masked mode: for ClipToPicture - // (this uses the standard rasterizer and renderer) - mutable scanline_unpacked_masked_type* fMaskedUnpackedScanline; - - mutable agg::path_storage fPath; - mutable agg::conv_curve fCurve; +private: + mutable PainterAggInterface fInternal; // for internal coordinate rounding/transformation bool fSubpixelPrecise : 1; diff --git a/src/servers/app/drawing/Painter/PainterAggInterface.h b/src/servers/app/drawing/Painter/PainterAggInterface.h new file mode 100644 index 0000000000..57e9c6fa7e --- /dev/null +++ b/src/servers/app/drawing/Painter/PainterAggInterface.h @@ -0,0 +1,67 @@ +/* + * Copyright 2005-2007, Stephan Aßmus . + * Copyright 2008, Andrej Spielmann . + * Copyright 2015, Julian Harnath + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef PAINTER_DATA_H +#define PAINTER_DATA_H + + +#include "defines.h" + +#include + + +struct PainterAggInterface { + PainterAggInterface(PatternHandler& patternHandler) + : + fBuffer(), + fPixelFormat(fBuffer, &patternHandler), + fBaseRenderer(fPixelFormat), + fUnpackedScanline(), + fPackedScanline(), + fRasterizer(), + fRenderer(fBaseRenderer), + fRendererBin(fBaseRenderer), + fSubpixPackedScanline(), + fSubpixUnpackedScanline(), + fSubpixRasterizer(), + fSubpixRenderer(fBaseRenderer), + fMaskedUnpackedScanline(NULL), + fPath(), + fCurve(fPath) + { + } + + agg::rendering_buffer fBuffer; + + // AGG rendering and rasterization classes + pixfmt fPixelFormat; + renderer_base fBaseRenderer; + + // Regular drawing mode: pixel-aligned, no alpha masking + scanline_unpacked_type fUnpackedScanline; + scanline_packed_type fPackedScanline; + rasterizer_type fRasterizer; + renderer_type fRenderer; + + // Fast mode: no antialiasing needed (horizontal/vertical lines, ...) + renderer_bin_type fRendererBin; + + // Subpixel mode + scanline_packed_subpix_type fSubpixPackedScanline; + scanline_unpacked_subpix_type fSubpixUnpackedScanline; + rasterizer_subpix_type fSubpixRasterizer; + renderer_subpix_type fSubpixRenderer; + + // Alpha-Masked mode: for ClipToPicture + // (this uses the standard rasterizer and renderer) + scanline_unpacked_masked_type* fMaskedUnpackedScanline; + + agg::path_storage fPath; + agg::conv_curve fCurve; +}; + + +#endif // PAINTER_DATA_H diff --git a/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp b/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp new file mode 100644 index 0000000000..a56635630d --- /dev/null +++ b/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp @@ -0,0 +1,314 @@ +/* + * Copyright 2009, Christian Packmann. + * Copyright 2008, Andrej Spielmann . + * Copyright 2005-2014, Stephan Aßmus . + * Copyright 2015, Julian Harnath + * All rights reserved. Distributed under the terms of the MIT License. + */ +#include "BitmapPainter.h" + +#include + +#include +#include +#include + +#include "DrawBitmapBilinear.h" +#include "DrawBitmapGeneric.h" +#include "DrawBitmapNearestNeighbor.h" +#include "DrawBitmapNoScale.h" +#include "drawing_support.h" +#include "ServerBitmap.h" +#include "SystemPalette.h" + + +// #define TRACE_BITMAP_PAINTER +#ifdef TRACE_BITMAP_PAINTER +# define TRACE(x...) printf(x) +#else +# define TRACE(x...) +#endif + + +Painter::BitmapPainter::BitmapPainter(const Painter* painter, + const ServerBitmap* bitmap, uint32 options) + : + fPainter(painter), + fStatus(B_NO_INIT), + fOptions(options) +{ + if (bitmap == NULL || !bitmap->IsValid()) + return; + + fBitmapBounds = bitmap->Bounds(); + fBitmapBounds.OffsetBy(-fBitmapBounds.left, -fBitmapBounds.top); + // Compensate for the lefttop offset the bitmap bounds might have + // It has the right size, but put it at B_ORIGIN + + fColorSpace = bitmap->ColorSpace(); + + fBitmap.attach(bitmap->Bits(), bitmap->Width(), bitmap->Height(), + bitmap->BytesPerRow()); + + fStatus = B_OK; +} + + +void +Painter::BitmapPainter::Draw(const BRect& sourceRect, + const BRect& destinationRect) +{ + using namespace BitmapPainterPrivate; + + if (fStatus != B_OK) + return; + + TRACE("BitmapPainter::Draw()\n"); + TRACE(" bitmapBounds = (%.1f, %.1f) - (%.1f, %.1f)\n", + bitmapBounds.left, bitmapBounds.top, + bitmapBounds.right, bitmapBounds.bottom); + TRACE(" sourceRect = (%.1f, %.1f) - (%.1f, %.1f)\n", + sourceRect.left, sourceRect.top, + sourceRect.right, sourceRect.bottom); + TRACE(" destinationRect = (%.1f, %.1f) - (%.1f, %.1f)\n", + destinationRect.left, destinationRect.top, + destinationRect.right, destinationRect.bottom); + + bool success = _DetermineTransform(sourceRect, destinationRect); + if (!success) + return; + + // optimized version for no scale in CMAP8 or RGB32 OP_OVER + if (!_HasScale() && !_HasAffineTransform() && !_HasAlphaMask()) { + if (fColorSpace == B_CMAP8) { + if (fPainter->fDrawingMode == B_OP_COPY) { + DrawBitmapNoScale::Draw(fPainter->fInternal, + fBitmap, 1, fOffset, fDestinationRect); + return; + } + if (fPainter->fDrawingMode == B_OP_OVER) { + DrawBitmapNoScale::Draw(fPainter->fInternal, + fBitmap, 1, fOffset, fDestinationRect); + return; + } + } else if (fColorSpace == B_RGB32) { + if (fPainter->fDrawingMode == B_OP_OVER) { + DrawBitmapNoScale::Draw(fPainter->fInternal, + fBitmap, 4, fOffset, fDestinationRect); + return; + } + } + } + + ObjectDeleter convertedBitmapDeleter; + _ConvertColorSpace(convertedBitmapDeleter); + + // optimized version if there is no scale + if (!_HasScale() && !_HasAffineTransform() && !_HasAlphaMask()) { + if (fPainter->fDrawingMode == B_OP_COPY) { + DrawBitmapNoScale::Draw(fPainter->fInternal, + fBitmap, 4, fOffset, fDestinationRect); + return; + } + if (fPainter->fDrawingMode == B_OP_OVER + || (fPainter->fDrawingMode == B_OP_ALPHA + && fPainter->fAlphaSrcMode == B_PIXEL_ALPHA + && fPainter->fAlphaFncMode == B_ALPHA_OVERLAY)) { + DrawBitmapNoScale::Draw(fPainter->fInternal, + fBitmap, 4, fOffset, fDestinationRect); + return; + } + } + + // bilinear and nearest-neighbor scaled, OP_COPY only + if (fPainter->fDrawingMode == B_OP_COPY + && !_HasAffineTransform() && !_HasAlphaMask()) { + if ((fOptions & B_FILTER_BITMAP_BILINEAR) != 0) { + DrawBitmapBilinearCopy drawBilinear; + drawBilinear.Draw(fPainter, fPainter->fInternal, + fBitmap, fOffset, fScaleX, fScaleY, fDestinationRect); + } + else { + DrawBitmapNearestNeighborCopy::Draw(fPainter, fPainter->fInternal, + fBitmap, fOffset, fScaleX, fScaleY, fDestinationRect); + } + return; + } + + // for all other cases (non-optimized drawing mode or scaled drawing) + DrawBitmapGeneric::Draw(fPainter, fPainter->fInternal, fBitmap, fOffset, + fScaleX, fScaleY, fDestinationRect, fOptions); +} + + +bool +Painter::BitmapPainter::_DetermineTransform(BRect sourceRect, + const BRect& destinationRect) +{ + if (!fPainter->fValidClipping + || !sourceRect.IsValid() + || !sourceRect.Intersects(fBitmapBounds) + || !destinationRect.IsValid()) { + return false; + } + + fDestinationRect = destinationRect; + + if (!fPainter->fSubpixelPrecise) { + align_rect_to_pixels(&sourceRect); + align_rect_to_pixels(&fDestinationRect); + } + + fScaleX = (fDestinationRect.Width() + 1) / (sourceRect.Width() + 1); + fScaleY = (fDestinationRect.Height() + 1) / (sourceRect.Height() + 1); + + if (fScaleX == 0.0 || fScaleY == 0.0) + return false; + + // constrain source rect to bitmap bounds and transfer the changes to + // the destination rect with the right scale + if (sourceRect.left < fBitmapBounds.left) { + float diff = fBitmapBounds.left - sourceRect.left; + fDestinationRect.left += diff * fScaleX; + sourceRect.left = fBitmapBounds.left; + } + if (sourceRect.top < fBitmapBounds.top) { + float diff = fBitmapBounds.top - sourceRect.top; + fDestinationRect.top += diff * fScaleY; + sourceRect.top = fBitmapBounds.top; + } + if (sourceRect.right > fBitmapBounds.right) { + float diff = sourceRect.right - fBitmapBounds.right; + fDestinationRect.right -= diff * fScaleX; + sourceRect.right = fBitmapBounds.right; + } + if (sourceRect.bottom > fBitmapBounds.bottom) { + float diff = sourceRect.bottom - fBitmapBounds.bottom; + fDestinationRect.bottom -= diff * fScaleY; + sourceRect.bottom = fBitmapBounds.bottom; + } + + fOffset.x = fDestinationRect.left - sourceRect.left; + fOffset.y = fDestinationRect.top - sourceRect.top; + + return true; +} + + +bool +Painter::BitmapPainter::_HasScale() +{ + return fScaleX != 1.0 || fScaleY != 1.0; +} + + +bool +Painter::BitmapPainter::_HasAffineTransform() +{ + return !fPainter->fIdentityTransform; +} + + +bool +Painter::BitmapPainter::_HasAlphaMask() +{ + return fPainter->fInternal.fMaskedUnpackedScanline != NULL; +} + + +void +Painter::BitmapPainter::_ConvertColorSpace( + ObjectDeleter& convertedBitmapDeleter) +{ + if (fColorSpace == B_RGBA32) + return; + + if (fColorSpace == B_RGB32 + && (fPainter->fDrawingMode == B_OP_COPY +#if 1 +// Enabling this would make the behavior compatible to BeOS, which +// treats B_RGB32 bitmaps as B_RGB*A*32 bitmaps in B_OP_ALPHA - unlike in +// all other drawing modes, where B_TRANSPARENT_MAGIC_RGBA32 is handled. +// B_RGB32 bitmaps therefore don't draw correctly on BeOS if they actually +// use this color, unless the alpha channel contains 255 for all other +// pixels, which is inconsistent. + || fPainter->fDrawingMode == B_OP_ALPHA +#endif + )) { + return; + } + + BBitmap* conversionBitmap = new(nothrow) BBitmap(fBitmapBounds, + B_BITMAP_NO_SERVER_LINK, B_RGBA32); + if (conversionBitmap == NULL) { + fprintf(stderr, "BitmapPainter::_ConvertColorSpace() - " + "out of memory for creating temporary conversion bitmap\n"); + return; + } + convertedBitmapDeleter.SetTo(conversionBitmap); + + status_t err = conversionBitmap->ImportBits(fBitmap.buf(), + fBitmap.height() * fBitmap.stride(), + fBitmap.stride(), 0, fColorSpace); + if (err < B_OK) { + fprintf(stderr, "BitmapPainter::_ConvertColorSpace() - " + "colorspace conversion failed: %s\n", strerror(err)); + return; + } + + // the original bitmap might have had some of the + // transaparent magic colors set that we now need to + // make transparent in our RGBA32 bitmap again. + switch (fColorSpace) { + case B_RGB32: + _TransparentMagicToAlpha((uint32 *)fBitmap.buf(), + fBitmap.width(), fBitmap.height(), + fBitmap.stride(), B_TRANSPARENT_MAGIC_RGBA32, + conversionBitmap); + break; + + // TODO: not sure if this applies to B_RGBA15 too. It + // should not because B_RGBA15 actually has an alpha + // channel itself and it should have been preserved + // when importing the bitmap. Maybe it applies to + // B_RGB16 though? + case B_RGB15: + _TransparentMagicToAlpha((uint16 *)fBitmap.buf(), + fBitmap.width(), fBitmap.height(), + fBitmap.stride(), B_TRANSPARENT_MAGIC_RGBA15, + conversionBitmap); + break; + + default: + break; + } + + fBitmap.attach((uint8*)conversionBitmap->Bits(), + (uint32)fBitmapBounds.IntegerWidth() + 1, + (uint32)fBitmapBounds.IntegerHeight() + 1, + conversionBitmap->BytesPerRow()); +} + + +template +void +Painter::BitmapPainter::_TransparentMagicToAlpha(sourcePixel* buffer, + uint32 width, uint32 height, uint32 sourceBytesPerRow, + sourcePixel transparentMagic, BBitmap* output) +{ + uint8* sourceRow = (uint8*)buffer; + uint8* destRow = (uint8*)output->Bits(); + uint32 destBytesPerRow = output->BytesPerRow(); + + for (uint32 y = 0; y < height; y++) { + sourcePixel* pixel = (sourcePixel*)sourceRow; + uint32* destPixel = (uint32*)destRow; + for (uint32 x = 0; x < width; x++, pixel++, destPixel++) { + if (*pixel == transparentMagic) + *destPixel &= 0x00ffffff; + } + + sourceRow += sourceBytesPerRow; + destRow += destBytesPerRow; + } +} diff --git a/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.h b/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.h new file mode 100644 index 0000000000..4afaa50645 --- /dev/null +++ b/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.h @@ -0,0 +1,60 @@ +/* + * Copyright 2005-2007, Stephan Aßmus . + * Copyright 2008, Andrej Spielmann . + * Copyright 2015, Julian Harnath + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef BITMAP_PAINTER_H +#define BITMAP_PAINTER_H + +#include + +#include "Painter.h" + + +class Painter::BitmapPainter { +public: + +public: + BitmapPainter(const Painter* painter, + const ServerBitmap* bitmap, + uint32 options); + + void Draw(const BRect& sourceRect, + const BRect& destinationRect); + +private: + bool _DetermineTransform( + BRect sourceRect, + const BRect& destinationRect); + + bool _HasScale(); + bool _HasAffineTransform(); + bool _HasAlphaMask(); + + void _ConvertColorSpace(ObjectDeleter& + convertedBitmapDeleter); + + template + void _TransparentMagicToAlpha(sourcePixel *buffer, + uint32 width, uint32 height, + uint32 sourceBytesPerRow, + sourcePixel transparentMagic, + BBitmap *output); + +private: + const Painter* fPainter; + status_t fStatus; + agg::rendering_buffer fBitmap; + BRect fBitmapBounds; + color_space fColorSpace; + uint32 fOptions; + + BRect fDestinationRect; + double fScaleX; + double fScaleY; + BPoint fOffset; +}; + + +#endif // BITMAP_PAINTER_H diff --git a/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapBilinear.h b/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapBilinear.h new file mode 100644 index 0000000000..5dc75257a1 --- /dev/null +++ b/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapBilinear.h @@ -0,0 +1,520 @@ +/* + * Copyright 2009, Christian Packmann. + * Copyright 2008, Andrej Spielmann . + * Copyright 2005-2014, Stephan Aßmus . + * Copyright 2015, Julian Harnath + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef DRAW_BITMAP_BILINEAR_H +#define DRAW_BITMAP_BILINEAR_H + +#include "Painter.h" + + +// Prototypes for assembler routines +extern "C" { + void bilinear_scale_xloop_mmxsse(const uint8* src, void* dst, + void* xWeights, uint32 xmin, uint32 xmax, uint32 wTop, uint32 srcBPR); +} + + +extern uint32 gSIMDFlags; + + +namespace BitmapPainterPrivate { + + +struct FilterInfo { + uint16 index; // index into source bitmap row/column + uint16 weight; // weight of the pixel at index [0..255] +}; + + +struct FilterData { + FilterInfo* fWeightsX; + FilterInfo* fWeightsY; + uint32 fIndexOffsetX; + uint32 fIndexOffsetY; +}; + + +template +struct DrawBitmapBilinearOptimized { + void Draw(PainterAggInterface& aggInterface, const BRect& destinationRect, + agg::rendering_buffer* bitmap, const FilterData& filterData) + { + fSource = bitmap; + fSourceBytesPerRow = bitmap->stride(); + fDestination = NULL; + fDestinationBytesPerRow = aggInterface.fBuffer.stride(); + fWeightsX = filterData.fWeightsX; + fWeightsY = filterData.fWeightsY; + + const int32 left = (int32)destinationRect.left; + const int32 top = (int32)destinationRect.top; + const int32 right = (int32)destinationRect.right; + const int32 bottom = (int32)destinationRect.bottom; + + renderer_base& baseRenderer = aggInterface.fBaseRenderer; + + // iterate over clipping boxes + baseRenderer.first_clip_box(); + do { + const int32 x1 = max_c(baseRenderer.xmin(), left); + const int32 x2 = min_c(baseRenderer.xmax(), right); + if (x1 > x2) + continue; + + int32 y1 = max_c(baseRenderer.ymin(), top); + int32 y2 = min_c(baseRenderer.ymax(), bottom); + if (y1 > y2) + continue; + + // buffer offset into destination + fDestination = aggInterface.fBuffer.row_ptr(y1) + x1 * 4; + + // x and y are needed as indices into the weight arrays, so the + // offset into the target buffer needs to be compensated + const int32 xIndexL = x1 - left - filterData.fIndexOffsetX; + const int32 xIndexR = x2 - left - filterData.fIndexOffsetX; + y1 -= top + filterData.fIndexOffsetY; + y2 -= top + filterData.fIndexOffsetY; + + //printf("x: %ld - %ld\n", xIndexL, xIndexR); + //printf("y: %ld - %ld\n", y1, y2); + + OptimizedVersion optimizedVersion; + optimizedVersion.DrawToClipRect(xIndexL, xIndexR, y1, y2); + + } while (baseRenderer.next_clip_box()); + } + +protected: + agg::rendering_buffer* fSource; + uint32 fSourceBytesPerRow; + uint8* fDestination; + uint32 fDestinationBytesPerRow; + FilterInfo* fWeightsX; + FilterInfo* fWeightsY; +}; + + +struct BilinearDefault : DrawBitmapBilinearOptimized { + void DrawToClipRect(int32 xIndexL, int32 xIndexR, int32 y1, int32 y2) + { + // In this mode we anticipate many pixels wich need filtering, + // there are no special cases for direct hit pixels except for + // the last column/row and the right/bottom corner pixel. + + // The last column/row handling does not need to be performed + // for all clipping rects! + int32 yMax = y2; + if (fWeightsY[yMax].weight == 255) + yMax--; + int32 xIndexMax = xIndexR; + if (fWeightsX[xIndexMax].weight == 255) + xIndexMax--; + + for (; y1 <= yMax; y1++) { + // cache the weight of the top and bottom row + const uint16 wTop = fWeightsY[y1].weight; + const uint16 wBottom = 255 - fWeightsY[y1].weight; + + // buffer offset into source (top row) + register const uint8* src = fSource->row_ptr(fWeightsY[y1].index); + // buffer handle for destination to be incremented per + // pixel + register uint8* d = fDestination; + + for (int32 x = xIndexL; x <= xIndexMax; x++) { + const uint8* s = src + fWeightsX[x].index; + // calculate the weighted sum of all four + // interpolated pixels + const uint16 wLeft = fWeightsX[x].weight; + const uint16 wRight = 255 - wLeft; + // left and right of top row + uint32 t0 = (s[0] * wLeft + s[4] * wRight) * wTop; + uint32 t1 = (s[1] * wLeft + s[5] * wRight) * wTop; + uint32 t2 = (s[2] * wLeft + s[6] * wRight) * wTop; + + // left and right of bottom row + s += fSourceBytesPerRow; + t0 += (s[0] * wLeft + s[4] * wRight) * wBottom; + t1 += (s[1] * wLeft + s[5] * wRight) * wBottom; + t2 += (s[2] * wLeft + s[6] * wRight) * wBottom; + d[0] = t0 >> 16; + d[1] = t1 >> 16; + d[2] = t2 >> 16; + d += 4; + } + // last column of pixels if necessary + if (xIndexMax < xIndexR) { + const uint8* s = src + fWeightsX[xIndexR].index; + const uint8* sBottom = s + fSourceBytesPerRow; + d[0] = (s[0] * wTop + sBottom[0] * wBottom) >> 8; + d[1] = (s[1] * wTop + sBottom[1] * wBottom) >> 8; + d[2] = (s[2] * wTop + sBottom[2] * wBottom) >> 8; + } + + fDestination += fDestinationBytesPerRow; + } + + // last row of pixels if necessary + // buffer offset into source (bottom row) + register const uint8* src + = fSource->row_ptr(fWeightsY[y2].index); + // buffer handle for destination to be incremented per pixel + register uint8* d = fDestination; + + if (yMax < y2) { + for (int32 x = xIndexL; x <= xIndexMax; x++) { + const uint8* s = src + fWeightsX[x].index; + const uint16 wLeft = fWeightsX[x].weight; + const uint16 wRight = 255 - wLeft; + d[0] = (s[0] * wLeft + s[4] * wRight) >> 8; + d[1] = (s[1] * wLeft + s[5] * wRight) >> 8; + d[2] = (s[2] * wLeft + s[6] * wRight) >> 8; + d += 4; + } + } + + // pixel in bottom right corner if necessary + if (yMax < y2 && xIndexMax < xIndexR) { + const uint8* s = src + fWeightsX[xIndexR].index; + *(uint32*)d = *(uint32*)s; + } + } +}; + + +struct BilinearLowFilterRatio : + DrawBitmapBilinearOptimized { + void DrawToClipRect(int32 xIndexL, int32 xIndexR, int32 y1, int32 y2) + { + // In this mode, we anticipate to hit many destination pixels + // that map directly to a source pixel, we have more branches + // in the inner loop but save time because of the special + // cases. If there are too few direct hit pixels, the branches + // only waste time. + + for (; y1 <= y2; y1++) { + // cache the weight of the top and bottom row + const uint16 wTop = fWeightsY[y1].weight; + const uint16 wBottom = 255 - fWeightsY[y1].weight; + + // buffer offset into source (top row) + register const uint8* src = fSource->row_ptr(fWeightsY[y1].index); + // buffer handle for destination to be incremented per + // pixel + register uint8* d = fDestination; + + if (wTop == 255) { + for (int32 x = xIndexL; x <= xIndexR; x++) { + const uint8* s = src + fWeightsX[x].index; + // This case is important to prevent out + // of bounds access at bottom edge of the source + // bitmap. If the scale is low and integer, it will + // also help the speed. + if (fWeightsX[x].weight == 255) { + // As above, but to prevent out of bounds + // on the right edge. + *(uint32*)d = *(uint32*)s; + } else { + // Only the left and right pixels are + // interpolated, since the top row has 100% + // weight. + const uint16 wLeft = fWeightsX[x].weight; + const uint16 wRight = 255 - wLeft; + d[0] = (s[0] * wLeft + s[4] * wRight) >> 8; + d[1] = (s[1] * wLeft + s[5] * wRight) >> 8; + d[2] = (s[2] * wLeft + s[6] * wRight) >> 8; + } + d += 4; + } + } else { + for (int32 x = xIndexL; x <= xIndexR; x++) { + const uint8* s = src + fWeightsX[x].index; + if (fWeightsX[x].weight == 255) { + // Prevent out of bounds access on the right + // edge or simply speed up. + const uint8* sBottom = s + fSourceBytesPerRow; + d[0] = (s[0] * wTop + sBottom[0] * wBottom) + >> 8; + d[1] = (s[1] * wTop + sBottom[1] * wBottom) + >> 8; + d[2] = (s[2] * wTop + sBottom[2] * wBottom) + >> 8; + } else { + // calculate the weighted sum of all four + // interpolated pixels + const uint16 wLeft = fWeightsX[x].weight; + const uint16 wRight = 255 - wLeft; + // left and right of top row + uint32 t0 = (s[0] * wLeft + s[4] * wRight) + * wTop; + uint32 t1 = (s[1] * wLeft + s[5] * wRight) + * wTop; + uint32 t2 = (s[2] * wLeft + s[6] * wRight) + * wTop; + + // left and right of bottom row + s += fSourceBytesPerRow; + t0 += (s[0] * wLeft + s[4] * wRight) * wBottom; + t1 += (s[1] * wLeft + s[5] * wRight) * wBottom; + t2 += (s[2] * wLeft + s[6] * wRight) * wBottom; + + d[0] = t0 >> 16; + d[1] = t1 >> 16; + d[2] = t2 >> 16; + } + d += 4; + } + } + fDestination += fDestinationBytesPerRow; + } + } +}; + + +#ifdef __INTEL__ + +struct BilinearSimd : DrawBitmapBilinearOptimized { + void DrawToClipRect(int32 xIndexL, int32 xIndexR, int32 y1, int32 y2) + { + // Basically the same as the "standard" mode, but we use SIMD + // routines for the processing of the single display lines. + + // The last column/row handling does not need to be performed + // for all clipping rects! + int32 yMax = y2; + if (fWeightsY[yMax].weight == 255) + yMax--; + int32 xIndexMax = xIndexR; + if (fWeightsX[xIndexMax].weight == 255) + xIndexMax--; + + for (; y1 <= yMax; y1++) { + // cache the weight of the top and bottom row + const uint16 wTop = fWeightsY[y1].weight; + const uint16 wBottom = 255 - fWeightsY[y1].weight; + + // buffer offset into source (top row) + const uint8* src = fSource->row_ptr(fWeightsY[y1].index); + // buffer handle for destination to be incremented per + // pixel + uint8* d = fDestination; + bilinear_scale_xloop_mmxsse(src, fDestination, fWeightsX, xIndexL, + xIndexMax, wTop, fSourceBytesPerRow); + // increase pointer by processed pixels + d += (xIndexMax - xIndexL + 1) * 4; + + // last column of pixels if necessary + if (xIndexMax < xIndexR) { + const uint8* s = src + fWeightsX[xIndexR].index; + const uint8* sBottom = s + fSourceBytesPerRow; + d[0] = (s[0] * wTop + sBottom[0] * wBottom) >> 8; + d[1] = (s[1] * wTop + sBottom[1] * wBottom) >> 8; + d[2] = (s[2] * wTop + sBottom[2] * wBottom) >> 8; + } + + fDestination += fDestinationBytesPerRow; + } + + // last row of pixels if necessary + // buffer offset into source (bottom row) + register const uint8* src = fSource->row_ptr(fWeightsY[y2].index); + // buffer handle for destination to be incremented per pixel + register uint8* d = fDestination; + + if (yMax < y2) { + for (int32 x = xIndexL; x <= xIndexMax; x++) { + const uint8* s = src + fWeightsX[x].index; + const uint16 wLeft = fWeightsX[x].weight; + const uint16 wRight = 255 - wLeft; + d[0] = (s[0] * wLeft + s[4] * wRight) >> 8; + d[1] = (s[1] * wLeft + s[5] * wRight) >> 8; + d[2] = (s[2] * wLeft + s[6] * wRight) >> 8; + d += 4; + } + } + + // pixel in bottom right corner if necessary + if (yMax < y2 && xIndexMax < xIndexR) { + const uint8* s = src + fWeightsX[xIndexR].index; + *(uint32*)d = *(uint32*)s; + } + } +}; + +#endif // __INTEL__ + + +struct DrawBitmapBilinearCopy { + void + Draw(const Painter* painter, PainterAggInterface& aggInterface, + agg::rendering_buffer& bitmap, BPoint offset, + double scaleX, double scaleY, BRect destinationRect) + { + //bigtime_t now = system_time(); + uint32 dstWidth = destinationRect.IntegerWidth() + 1; + uint32 dstHeight = destinationRect.IntegerHeight() + 1; + uint32 srcWidth = bitmap.width(); + uint32 srcHeight = bitmap.height(); + + // Do not calculate more filter weights than necessary and also + // keep the stack based allocations reasonably sized + const BRegion& clippingRegion = *painter->ClippingRegion(); + if (clippingRegion.Frame().IntegerWidth() + 1 < (int32)dstWidth) + dstWidth = clippingRegion.Frame().IntegerWidth() + 1; + if (clippingRegion.Frame().IntegerHeight() + 1 < (int32)dstHeight) + dstHeight = clippingRegion.Frame().IntegerHeight() + 1; + + // When calculating less filter weights than specified by + // destinationRect, we need to compensate the offset. + FilterData filterData; + filterData.fIndexOffsetX = 0; + filterData.fIndexOffsetY = 0; + if (clippingRegion.Frame().left > destinationRect.left) { + filterData.fIndexOffsetX = (int32)(clippingRegion.Frame().left + - destinationRect.left); + } + if (clippingRegion.Frame().top > destinationRect.top) { + filterData.fIndexOffsetY = (int32)(clippingRegion.Frame().top + - destinationRect.top); + } + +//#define FILTER_INFOS_ON_HEAP +#ifdef FILTER_INFOS_ON_HEAP + filterData.fWeightsX = new (nothrow) FilterInfo[dstWidth]; + filterData.fWeightsY = new (nothrow) FilterInfo[dstHeight]; + if (filterData.fWeightsX == NULL || filterData.fWeightsY == NULL) { + delete[] filterData.fWeightsX; + delete[] filterData.fWeightsY; + return; + } +#else + // stack based saves about 200µs on 1.85 GHz Core 2 Duo + // should not pose a problem with stack overflows + // (needs around 12Kb for 1920x1200) + FilterInfo xWeights[dstWidth]; + FilterInfo yWeights[dstHeight]; + filterData.fWeightsX = &xWeights[0]; + filterData.fWeightsY = &yWeights[0]; +#endif + + // Extract the cropping information for the source bitmap, + // If only a part of the source bitmap is to be drawn with scale, + // the offset will be different from the destinationRect left top + // corner. + const int32 xBitmapShift = (int32)(destinationRect.left - offset.x); + const int32 yBitmapShift = (int32)(destinationRect.top - offset.y); + + for (uint32 i = 0; i < dstWidth; i++) { + // fractional index into source + // NOTE: It is very important to calculate the fractional index + // into the source pixel grid like this to prevent out of bounds + // access! It will result in the rightmost pixel of the destination + // to access the rightmost pixel of the source with a weighting + // of 255. This in turn will trigger an optimization in the loop + // that also prevents out of bounds access. + float index = (i + filterData.fIndexOffsetX) * (srcWidth - 1) + / (srcWidth * scaleX - 1); + // round down to get the left pixel + filterData.fWeightsX[i].index = (uint16)index; + filterData.fWeightsX[i].weight = + 255 - (uint16)((index - filterData.fWeightsX[i].index) * 255); + // handle cropped source bitmap + filterData.fWeightsX[i].index += xBitmapShift; + // precompute index for 32 bit pixels + filterData.fWeightsX[i].index *= 4; + } + + for (uint32 i = 0; i < dstHeight; i++) { + // fractional index into source + // NOTE: It is very important to calculate the fractional index + // into the source pixel grid like this to prevent out of bounds + // access! It will result in the bottommost pixel of the + // destination to access the bottommost pixel of the source with a + // weighting of 255. This in turn will trigger an optimization in + // the loop that also prevents out of bounds access. + float index = (i + filterData.fIndexOffsetY) * (srcHeight - 1) + / (srcHeight * scaleY - 1); + // round down to get the top pixel + filterData.fWeightsY[i].index = (uint16)index; + filterData.fWeightsY[i].weight = + 255 - (uint16)((index - filterData.fWeightsY[i].index) * 255); + // handle cropped source bitmap + filterData.fWeightsY[i].index += yBitmapShift; + } + //printf("X: %d/%d ... %d/%d, %d/%d (%ld)\n", + // xWeights[0].index, xWeights[0].weight, + // xWeights[dstWidth - 2].index, xWeights[dstWidth - 2].weight, + // xWeights[dstWidth - 1].index, xWeights[dstWidth - 1].weight, + // dstWidth); + //printf("Y: %d/%d ... %d/%d, %d/%d (%ld)\n", + // yWeights[0].index, yWeights[0].weight, + // yWeights[dstHeight - 2].index, yWeights[dstHeight - 2].weight, + // yWeights[dstHeight - 1].index, yWeights[dstHeight - 1].weight, + // dstHeight); + + // Figure out which version of the code we want to use... + enum { + kOptimizeForLowFilterRatio = 0, + kUseDefaultVersion, + kUseSIMDVersion + }; + + int codeSelect = kUseDefaultVersion; + + uint32 neededSIMDFlags = APPSERVER_SIMD_MMX | APPSERVER_SIMD_SSE; + if ((gSIMDFlags & neededSIMDFlags) == neededSIMDFlags) + codeSelect = kUseSIMDVersion; + else { + if (scaleX == scaleY && (scaleX == 1.5 || scaleX == 2.0 + || scaleX == 2.5 || scaleX == 3.0)) { + codeSelect = kOptimizeForLowFilterRatio; + } + } + + switch (codeSelect) { + case kUseDefaultVersion: + { + BilinearDefault bilinearPainter; + bilinearPainter.Draw(aggInterface, destinationRect, &bitmap, + filterData); + break; + } + + case kOptimizeForLowFilterRatio: + { + BilinearLowFilterRatio bilinearPainter; + bilinearPainter.Draw(aggInterface, destinationRect, + &bitmap, filterData); + break; + } + +#ifdef __INTEL__ + case kUseSIMDVersion: + { + BilinearSimd bilinearPainter; + bilinearPainter.Draw(aggInterface, destinationRect, &bitmap, + filterData); + break; + } +#endif // __INTEL__ + } + +#ifdef FILTER_INFOS_ON_HEAP + delete[] filterData.fWeightsX; + delete[] filterData.fWeightsY; +#endif + //printf("draw bitmap %.5fx%.5f: %lld\n", scaleX, scaleY, + // system_time() - now); + } +}; + + +} // namespace BitmapPainterPrivate + + +#endif // DRAW_BITMAP_BILINEAR_H diff --git a/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapGeneric.h b/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapGeneric.h new file mode 100644 index 0000000000..f148583f81 --- /dev/null +++ b/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapGeneric.h @@ -0,0 +1,112 @@ +/* + * Copyright 2009, Christian Packmann. + * Copyright 2008, Andrej Spielmann . + * Copyright 2005-2014, Stephan Aßmus . + * Copyright 2015, Julian Harnath + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef DRAW_BITMAP_GENERIC_H +#define DRAW_BITMAP_GENERIC_H + +#include "Painter.h" + + +struct DrawBitmapGeneric { + static void + Draw(const Painter* painter, PainterAggInterface& aggInterface, + agg::rendering_buffer& bitmap, BPoint offset, + double scaleX, double scaleY, BRect destinationRect, uint32 options) + { + // pixel format attached to bitmap + typedef agg::pixfmt_bgra32 pixfmt_image; + pixfmt_image pixf_img(bitmap); + + agg::trans_affine srcMatrix; + // NOTE: R5 seems to ignore this offset when drawing bitmaps + // srcMatrix *= agg::trans_affine_translation(-actualBitmapRect.left, + // -actualBitmapRect.top); + srcMatrix *= painter->Transform(); + + agg::trans_affine imgMatrix; + imgMatrix *= agg::trans_affine_translation( + offset.x - destinationRect.left, offset.y - destinationRect.top); + imgMatrix *= agg::trans_affine_scaling(scaleX, scaleY); + imgMatrix *= agg::trans_affine_translation(destinationRect.left, + destinationRect.top); + imgMatrix *= painter->Transform(); + imgMatrix.invert(); + + // image interpolator + typedef agg::span_interpolator_linear<> interpolator_type; + interpolator_type interpolator(imgMatrix); + + // scanline allocator + agg::span_allocator spanAllocator; + + // image accessor attached to pixel format of bitmap + typedef agg::image_accessor_clone source_type; + source_type source(pixf_img); + + // clip to the current clipping region's frame + if (painter->IsIdentityTransform()) { + destinationRect = destinationRect + & painter->ClippingRegion()->Frame(); + } + // convert to pixel coords (versus pixel indices) + destinationRect.right++; + destinationRect.bottom++; + + // path enclosing the bitmap + agg::path_storage& path = aggInterface.fPath; + rasterizer_type& rasterizer = aggInterface.fRasterizer; + + path.remove_all(); + path.move_to(destinationRect.left, destinationRect.top); + path.line_to(destinationRect.right, destinationRect.top); + path.line_to(destinationRect.right, destinationRect.bottom); + path.line_to(destinationRect.left, destinationRect.bottom); + path.close_polygon(); + + agg::conv_transform transformedPath(path, + srcMatrix); + rasterizer.reset(); + rasterizer.add_path(transformedPath); + + if ((options & B_FILTER_BITMAP_BILINEAR) != 0) { + // image filter (bilinear) + typedef agg::span_image_filter_rgba_bilinear< + source_type, interpolator_type> span_gen_type; + span_gen_type spanGenerator(source, interpolator); + + // render the path with the bitmap as scanline fill + if (aggInterface.fMaskedUnpackedScanline != NULL) { + agg::render_scanlines_aa(rasterizer, + *aggInterface.fMaskedUnpackedScanline, + aggInterface.fBaseRenderer, spanAllocator, spanGenerator); + } else { + agg::render_scanlines_aa(rasterizer, + aggInterface.fUnpackedScanline, + aggInterface.fBaseRenderer, spanAllocator, spanGenerator); + } + } else { + // image filter (nearest neighbor) + typedef agg::span_image_filter_rgba_nn< + source_type, interpolator_type> span_gen_type; + span_gen_type spanGenerator(source, interpolator); + + // render the path with the bitmap as scanline fill + if (aggInterface.fMaskedUnpackedScanline != NULL) { + agg::render_scanlines_aa(rasterizer, + *aggInterface.fMaskedUnpackedScanline, + aggInterface.fBaseRenderer, spanAllocator, spanGenerator); + } else { + agg::render_scanlines_aa(rasterizer, + aggInterface.fUnpackedScanline, + aggInterface.fBaseRenderer, spanAllocator, spanGenerator); + } + } + } +}; + + +#endif // DRAW_BITMAP_GENERIC_H diff --git a/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNearestNeighbor.h b/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNearestNeighbor.h new file mode 100644 index 0000000000..59fc68b097 --- /dev/null +++ b/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNearestNeighbor.h @@ -0,0 +1,143 @@ +/* + * Copyright 2009, Christian Packmann. + * Copyright 2008, Andrej Spielmann . + * Copyright 2005-2014, Stephan Aßmus . + * Copyright 2015, Julian Harnath + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef DRAW_BITMAP_NEAREST_NEIGHBOR_H +#define DRAW_BITMAP_NEAREST_NEIGHBOR_H + +#include "Painter.h" + + +struct DrawBitmapNearestNeighborCopy { + static void + Draw(const Painter* painter, PainterAggInterface& aggInterface, + agg::rendering_buffer& bitmap, BPoint offset, + double scaleX, double scaleY, BRect destinationRect) + { + //bigtime_t now = system_time(); + uint32 dstWidth = destinationRect.IntegerWidth() + 1; + uint32 dstHeight = destinationRect.IntegerHeight() + 1; + uint32 srcWidth = bitmap.width(); + uint32 srcHeight = bitmap.height(); + + // Do not calculate more filter weights than necessary and also + // keep the stack based allocations reasonably sized + const BRegion& clippingRegion = *painter->ClippingRegion(); + if (clippingRegion.Frame().IntegerWidth() + 1 < (int32)dstWidth) + dstWidth = clippingRegion.Frame().IntegerWidth() + 1; + if (clippingRegion.Frame().IntegerHeight() + 1 < (int32)dstHeight) + dstHeight = clippingRegion.Frame().IntegerHeight() + 1; + + // When calculating less filter weights than specified by + // destinationRect, we need to compensate the offset. + uint32 filterWeightXIndexOffset = 0; + uint32 filterWeightYIndexOffset = 0; + if (clippingRegion.Frame().left > destinationRect.left) { + filterWeightXIndexOffset = (int32)(clippingRegion.Frame().left + - destinationRect.left); + } + if (clippingRegion.Frame().top > destinationRect.top) { + filterWeightYIndexOffset = (int32)(clippingRegion.Frame().top + - destinationRect.top); + } + + // should not pose a problem with stack overflows + // (needs around 6Kb for 1920x1200) + uint16 xIndices[dstWidth]; + uint16 yIndices[dstHeight]; + + // Extract the cropping information for the source bitmap, + // If only a part of the source bitmap is to be drawn with scale, + // the offset will be different from the destinationRect left top + // corner. + const int32 xBitmapShift = (int32)(destinationRect.left - offset.x); + const int32 yBitmapShift = (int32)(destinationRect.top - offset.y); + + for (uint32 i = 0; i < dstWidth; i++) { + // index into source + uint16 index = (uint16)((i + filterWeightXIndexOffset) * srcWidth + / (srcWidth * scaleX)); + // round down to get the left pixel + xIndices[i] = index; + // handle cropped source bitmap + xIndices[i] += xBitmapShift; + // precompute index for 32 bit pixels + xIndices[i] *= 4; + } + + for (uint32 i = 0; i < dstHeight; i++) { + // index into source + uint16 index = (uint16)((i + filterWeightYIndexOffset) * srcHeight + / (srcHeight * scaleY)); + // round down to get the top pixel + yIndices[i] = index; + // handle cropped source bitmap + yIndices[i] += yBitmapShift; + } + //printf("X: %d ... %d, %d (%ld or %f)\n", + // xIndices[0], xIndices[dstWidth - 2], xIndices[dstWidth - 1], + // dstWidth, srcWidth * scaleX); + //printf("Y: %d ... %d, %d (%ld or %f)\n", + // yIndices[0], yIndices[dstHeight - 2], yIndices[dstHeight - 1], + // dstHeight, srcHeight * scaleY); + + const int32 left = (int32)destinationRect.left; + const int32 top = (int32)destinationRect.top; + const int32 right = (int32)destinationRect.right; + const int32 bottom = (int32)destinationRect.bottom; + + const uint32 dstBPR = aggInterface.fBuffer.stride(); + + renderer_base& baseRenderer = aggInterface.fBaseRenderer; + + // iterate over clipping boxes + baseRenderer.first_clip_box(); + do { + const int32 x1 = max_c(baseRenderer.xmin(), left); + const int32 x2 = min_c(baseRenderer.xmax(), right); + if (x1 > x2) + continue; + + int32 y1 = max_c(baseRenderer.ymin(), top); + int32 y2 = min_c(baseRenderer.ymax(), bottom); + if (y1 > y2) + continue; + + // buffer offset into destination + uint8* dst = aggInterface.fBuffer.row_ptr(y1) + x1 * 4; + + // x and y are needed as indeces into the wheight arrays, so the + // offset into the target buffer needs to be compensated + const int32 xIndexL = x1 - left - filterWeightXIndexOffset; + const int32 xIndexR = x2 - left - filterWeightXIndexOffset; + y1 -= top + filterWeightYIndexOffset; + y2 -= top + filterWeightYIndexOffset; + + //printf("x: %ld - %ld\n", xIndexL, xIndexR); + //printf("y: %ld - %ld\n", y1, y2); + + for (; y1 <= y2; y1++) { + // buffer offset into source (top row) + register const uint8* src = bitmap.row_ptr(yIndices[y1]); + // buffer handle for destination to be incremented per pixel + register uint32* d = (uint32*)dst; + + for (int32 x = xIndexL; x <= xIndexR; x++) { + *d = *(uint32*)(src + xIndices[x]); + d++; + } + dst += dstBPR; + } + } while (baseRenderer.next_clip_box()); + + //printf("draw bitmap %.5fx%.5f: %lld\n", xScale, yScale, + // system_time() - now); + } +}; + + + +#endif // DRAW_BITMAP_NEAREST_NEIGHBOR_H diff --git a/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNoScale.h b/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNoScale.h new file mode 100644 index 0000000000..61be834b4f --- /dev/null +++ b/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNoScale.h @@ -0,0 +1,169 @@ +/* + * Copyright 2009, Christian Packmann. + * Copyright 2008, Andrej Spielmann . + * Copyright 2005-2014, Stephan Aßmus . + * Copyright 2015, Julian Harnath + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef DRAW_BITMAP_NO_SCALE_H +#define DRAW_BITMAP_NO_SCALE_H + +#include "IntPoint.h" +#include "Painter.h" + + +template +struct DrawBitmapNoScale { + static void + Draw(PainterAggInterface& aggInterface, agg::rendering_buffer& bitmap, + uint32 bytesPerSourcePixel, IntPoint offset, BRect destinationRect) + { + // NOTE: this would crash if destinationRect was large enough to read + // outside the bitmap, so make sure this is not the case before calling + // this function! + uint8* dst = aggInterface.fBuffer.row_ptr(0); + const uint32 dstBPR = aggInterface.fBuffer.stride(); + + const uint8* src = bitmap.row_ptr(0); + const uint32 srcBPR = bitmap.stride(); + + const int32 left = (int32)destinationRect.left; + const int32 top = (int32)destinationRect.top; + const int32 right = (int32)destinationRect.right; + const int32 bottom = (int32)destinationRect.bottom; + +#if DEBUG_DRAW_BITMAP + if (left - offset.x < 0 + || left - offset.x >= (int32)bitmap.width() + || right - offset.x >= (int32)srcBuffer.width() + || top - offset.y < 0 + || top - offset.y >= (int32)bitmap.height() + || bottom - offset.y >= (int32)bitmap.height()) { + char message[256]; + sprintf(message, "reading outside of bitmap (%ld, %ld, %ld, %ld) " + "(%d, %d) (%ld, %ld)", + left - offset.x, top - offset.y, + right - offset.x, bottom - offset.y, + bitmap.width(), bitmap.height(), offset.x, offset.y); + debugger(message); + } +#endif + + const rgb_color* colorMap = SystemPalette(); + renderer_base& baseRenderer = aggInterface.fBaseRenderer; + + // copy rects, iterate over clipping boxes + baseRenderer.first_clip_box(); + do { + int32 x1 = max_c(baseRenderer.xmin(), left); + int32 x2 = min_c(baseRenderer.xmax(), right); + if (x1 <= x2) { + int32 y1 = max_c(baseRenderer.ymin(), top); + int32 y2 = min_c(baseRenderer.ymax(), bottom); + if (y1 <= y2) { + uint8* dstHandle = dst + y1 * dstBPR + x1 * 4; + const uint8* srcHandle = src + (y1 - offset.y) * srcBPR + + (x1 - offset.x) * bytesPerSourcePixel; + + for (; y1 <= y2; y1++) { + BlendType::BlendRow(dstHandle, srcHandle, + x2 - x1 + 1, colorMap); + + dstHandle += dstBPR; + srcHandle += srcBPR; + } + } + } + } while (baseRenderer.next_clip_box()); + } +}; + + +struct CMap8Copy : public DrawBitmapNoScale +{ + static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, + const rgb_color* colorMap) + { + uint32* d = (uint32*)dst; + const uint8* s = src; + while (numPixels--) { + const rgb_color c = colorMap[*s++]; + *d++ = (c.alpha << 24) | (c.red << 16) | (c.green << 8) | (c.blue); + } + } +}; + + +struct CMap8Over : public DrawBitmapNoScale +{ + static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, + const rgb_color* colorMap) + { + uint32* d = (uint32*)dst; + const uint8* s = src; + while (numPixels--) { + const rgb_color c = colorMap[*s++]; + if (c.alpha) + *d = (c.alpha << 24) | (c.red << 16) + | (c.green << 8) | (c.blue); + d++; + } + } +}; + + +struct Bgr32Copy : public DrawBitmapNoScale +{ + static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, + const rgb_color*) + { + memcpy(dst, src, numPixels * 4); + } +}; + + +struct Bgr32Over : public DrawBitmapNoScale +{ + static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, + const rgb_color*) + { + uint32* d = (uint32*)dst; + uint32* s = (uint32*)src; + while (numPixels--) { + if (*s != B_TRANSPARENT_MAGIC_RGBA32) + *(uint32*)d = *(uint32*)s; + d++; + s++; + } + } +}; + + +struct Bgr32Alpha : public DrawBitmapNoScale +{ + static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, + const rgb_color*) + { + uint32* d = (uint32*)dst; + int32 bytes = numPixels * 4; + uint8 buffer[bytes]; + uint8* b = buffer; + while (numPixels--) { + if (src[3] == 255) { + *(uint32*)b = *(uint32*)src; + } else { + *(uint32*)b = *d; + b[0] = ((src[0] - b[0]) * src[3] + (b[0] << 8)) >> 8; + b[1] = ((src[1] - b[1]) * src[3] + (b[1] << 8)) >> 8; + b[2] = ((src[2] - b[2]) * src[3] + (b[2] << 8)) >> 8; + } + d++; + b += 4; + src += 4; + } + memcpy(dst, buffer, bytes); + } +}; + + +#endif // DRAW_BITMAP_NO_SCALE_H diff --git a/src/servers/app/drawing/Painter/painter_bilinear_scale.nasm b/src/servers/app/drawing/Painter/bitmap_painter/painter_bilinear_scale.nasm similarity index 100% rename from src/servers/app/drawing/Painter/painter_bilinear_scale.nasm rename to src/servers/app/drawing/Painter/bitmap_painter/painter_bilinear_scale.nasm From f4f05935dbe4fa5c5b1fda880e23d81a18b11da2 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Sat, 15 Aug 2015 11:14:42 +0200 Subject: [PATCH 020/370] app_server: give Painter direct access to alpha masks * To use alpha masks in optimized drawing code outside of the AGG renderer pipeline, we need to allow access to the alpha mask's underlying buffer: - AlphaMask gets another method which returns its clipped_alpha_mask - clipped_alpha_mask gets a get_hspan() method which returns a span of alpha values without combining it with anything - Painter/PainterAggInterface store a pointer to the clipped_alpha_mask (in addition to the AlphaMask's scanline container) --- src/servers/app/drawing/AlphaMask.cpp | 7 ++ src/servers/app/drawing/AlphaMask.h | 1 + src/servers/app/drawing/Painter/Painter.cpp | 8 +- .../app/drawing/Painter/PainterAggInterface.h | 2 + .../drawing/Painter/agg_clipped_alpha_mask.h | 100 +++++++++++------- 5 files changed, 80 insertions(+), 38 deletions(-) diff --git a/src/servers/app/drawing/AlphaMask.cpp b/src/servers/app/drawing/AlphaMask.cpp index 49636c6296..865425a391 100644 --- a/src/servers/app/drawing/AlphaMask.cpp +++ b/src/servers/app/drawing/AlphaMask.cpp @@ -220,6 +220,13 @@ AlphaMask::Generate() } +agg::clipped_alpha_mask* +AlphaMask::Mask() +{ + return &fCachedMask; +} + + ServerBitmap* AlphaMask::_RenderPicture() const { diff --git a/src/servers/app/drawing/AlphaMask.h b/src/servers/app/drawing/AlphaMask.h index cb1969af7a..81503c0874 100644 --- a/src/servers/app/drawing/AlphaMask.h +++ b/src/servers/app/drawing/AlphaMask.h @@ -32,6 +32,7 @@ public: void SetPrevious(AlphaMask* mask); scanline_unpacked_masked_type* Generate(); + agg::clipped_alpha_mask* Mask(); private: ServerBitmap* _RenderPicture() const; diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 45cd532cc8..c8e83756c2 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -102,6 +102,7 @@ using std::nothrow; #define fSubpixRasterizer fInternal.fSubpixRasterizer #define fSubpixRenderer fInternal.fSubpixRenderer #define fMaskedUnpackedScanline fInternal.fMaskedUnpackedScanline +#define fClippedAlphaMask fInternal.fClippedAlphaMask #define fPath fInternal.fPath #define fCurve fInternal.fCurve @@ -287,10 +288,13 @@ Painter::SetDrawState(const DrawState* state, int32 xOffset, int32 yOffset) fSubpixelPrecise = state->SubPixelPrecise(); - if (state->GetAlphaMask() != NULL) + if (state->GetAlphaMask() != NULL) { fMaskedUnpackedScanline = state->GetAlphaMask()->Generate(); - else + fClippedAlphaMask = state->GetAlphaMask()->Mask(); + } else { fMaskedUnpackedScanline = NULL; + fClippedAlphaMask = NULL; + } // any of these conditions means we need to use a different drawing // mode instance diff --git a/src/servers/app/drawing/Painter/PainterAggInterface.h b/src/servers/app/drawing/Painter/PainterAggInterface.h index 57e9c6fa7e..2f4e6ea16e 100644 --- a/src/servers/app/drawing/Painter/PainterAggInterface.h +++ b/src/servers/app/drawing/Painter/PainterAggInterface.h @@ -29,6 +29,7 @@ struct PainterAggInterface { fSubpixRasterizer(), fSubpixRenderer(fBaseRenderer), fMaskedUnpackedScanline(NULL), + fClippedAlphaMask(NULL), fPath(), fCurve(fPath) { @@ -58,6 +59,7 @@ struct PainterAggInterface { // Alpha-Masked mode: for ClipToPicture // (this uses the standard rasterizer and renderer) scanline_unpacked_masked_type* fMaskedUnpackedScanline; + agg::clipped_alpha_mask* fClippedAlphaMask; agg::path_storage fPath; agg::conv_curve fCurve; diff --git a/src/servers/app/drawing/Painter/agg_clipped_alpha_mask.h b/src/servers/app/drawing/Painter/agg_clipped_alpha_mask.h index 59c77740e9..08e34a251c 100644 --- a/src/servers/app/drawing/Painter/agg_clipped_alpha_mask.h +++ b/src/servers/app/drawing/Painter/agg_clipped_alpha_mask.h @@ -23,7 +23,7 @@ namespace agg public: typedef int8u cover_type; enum cover_scale_e - { + { cover_shift = 8, cover_none = 0, cover_full = 255 @@ -44,46 +44,13 @@ namespace agg void combine_hspan(int x, int y, cover_type* dst, int num_pix) const { - x -= m_xOffset; - y -= m_yOffset; - - int xmax = m_rbuf->width() - 1; - int ymax = m_rbuf->height() - 1; - int count = num_pix; cover_type* covers = dst; - if(y < 0 || y > ymax) - { - memset(dst, m_outside, num_pix * sizeof(cover_type)); + bool has_inside = _set_outside(x, y, covers, count); + if (!has_inside) return; - } - if(x < 0) - { - count += x; - if(count <= 0) - { - memset(dst, m_outside, num_pix * sizeof(cover_type)); - return; - } - memset(covers, m_outside, -x * sizeof(cover_type)); - covers -= x; - x = 0; - } - - if(x + count > xmax) - { - int rest = x + count - xmax - 1; - count -= rest; - if(count <= 0) - { - memset(dst, m_outside, num_pix * sizeof(cover_type)); - return; - } - memset(covers + count, m_outside, rest * sizeof(cover_type)); - } - const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; do { @@ -95,6 +62,67 @@ namespace agg while(--count); } + void get_hspan(int x, int y, cover_type* dst, int num_pix) const + { + int count = num_pix; + cover_type* covers = dst; + + bool has_inside = _set_outside(x, y, covers, count); + if (!has_inside) + return; + + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + memcpy(covers, mask, count); + } + + private: + bool _set_outside(int& x, int& y, cover_type*& covers, + int& count) const + { + x -= m_xOffset; + y -= m_yOffset; + + int xmax = m_rbuf->width() - 1; + int ymax = m_rbuf->height() - 1; + + int num_pix = count; + cover_type* dst = covers; + + if(y < 0 || y > ymax) + { + memset(dst, m_outside, num_pix * sizeof(cover_type)); + return false; + } + + if(x < 0) + { + count += x; + if(count <= 0) + { + memset(dst, m_outside, num_pix * sizeof(cover_type)); + return false; + } + memset(covers, m_outside, -x * sizeof(cover_type)); + covers -= x; + x = 0; + } + + if(x + count > xmax) + { + int rest = x + count - xmax - 1; + count -= rest; + if(count <= 0) + { + memset(dst, m_outside, num_pix * sizeof(cover_type)); + return false; + } + memset(covers + count, m_outside, rest * sizeof(cover_type)); + } + + return true; + } + + private: int m_xOffset; int m_yOffset; From 79a483ebbfdbf0bdf39c99b12c128a4fd088aa1d Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Sat, 15 Aug 2015 11:23:51 +0200 Subject: [PATCH 021/370] app_server: add alpha masked mode to DrawBitmapNoScale * Add another mode to DrawBitmapNoScale for drawing bitmaps using B_OP_COPY with alpha masks. It behaves like the definition for ClipToPicture from the BeBook: pixels with alpha = 0 are ignored, pixels with any alpha > 0 are copied. Before, this fell back to the slower generic AGG-pipeline-based version. * Some light refactoring --- .../Painter/bitmap_painter/BitmapPainter.cpp | 34 +++++--- .../bitmap_painter/DrawBitmapNoScale.h | 79 +++++++++++++------ 2 files changed, 77 insertions(+), 36 deletions(-) diff --git a/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp b/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp index a56635630d..813f291e90 100644 --- a/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp +++ b/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp @@ -82,19 +82,22 @@ Painter::BitmapPainter::Draw(const BRect& sourceRect, if (!_HasScale() && !_HasAffineTransform() && !_HasAlphaMask()) { if (fColorSpace == B_CMAP8) { if (fPainter->fDrawingMode == B_OP_COPY) { - DrawBitmapNoScale::Draw(fPainter->fInternal, - fBitmap, 1, fOffset, fDestinationRect); + DrawBitmapNoScale drawNoScale; + drawNoScale.Draw(fPainter->fInternal, fBitmap, 1, fOffset, + fDestinationRect); return; } if (fPainter->fDrawingMode == B_OP_OVER) { - DrawBitmapNoScale::Draw(fPainter->fInternal, - fBitmap, 1, fOffset, fDestinationRect); + DrawBitmapNoScale drawNoScale; + drawNoScale.Draw(fPainter->fInternal, fBitmap, 1, fOffset, + fDestinationRect); return; } } else if (fColorSpace == B_RGB32) { if (fPainter->fDrawingMode == B_OP_OVER) { - DrawBitmapNoScale::Draw(fPainter->fInternal, - fBitmap, 4, fOffset, fDestinationRect); + DrawBitmapNoScale drawNoScale; + drawNoScale.Draw(fPainter->fInternal, fBitmap, 4, fOffset, + fDestinationRect); return; } } @@ -106,16 +109,27 @@ Painter::BitmapPainter::Draw(const BRect& sourceRect, // optimized version if there is no scale if (!_HasScale() && !_HasAffineTransform() && !_HasAlphaMask()) { if (fPainter->fDrawingMode == B_OP_COPY) { - DrawBitmapNoScale::Draw(fPainter->fInternal, - fBitmap, 4, fOffset, fDestinationRect); + DrawBitmapNoScale drawNoScale; + drawNoScale.Draw(fPainter->fInternal, fBitmap, 4, fOffset, + fDestinationRect); return; } if (fPainter->fDrawingMode == B_OP_OVER || (fPainter->fDrawingMode == B_OP_ALPHA && fPainter->fAlphaSrcMode == B_PIXEL_ALPHA && fPainter->fAlphaFncMode == B_ALPHA_OVERLAY)) { - DrawBitmapNoScale::Draw(fPainter->fInternal, - fBitmap, 4, fOffset, fDestinationRect); + DrawBitmapNoScale drawNoScale; + drawNoScale.Draw(fPainter->fInternal, fBitmap, 4, fOffset, + fDestinationRect); + return; + } + } + + if (!_HasScale() && !_HasAffineTransform() && _HasAlphaMask()) { + if (fPainter->fDrawingMode == B_OP_COPY) { + DrawBitmapNoScale drawNoScale; + drawNoScale.Draw(fPainter->fInternal, fBitmap, 4, fOffset, + fDestinationRect); return; } } diff --git a/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNoScale.h b/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNoScale.h index 61be834b4f..d42371552d 100644 --- a/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNoScale.h +++ b/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNoScale.h @@ -9,12 +9,14 @@ #define DRAW_BITMAP_NO_SCALE_H #include "IntPoint.h" +#include "IntRect.h" #include "Painter.h" template struct DrawBitmapNoScale { - static void +public: + void Draw(PainterAggInterface& aggInterface, agg::rendering_buffer& bitmap, uint32 bytesPerSourcePixel, IntPoint offset, BRect destinationRect) { @@ -49,25 +51,28 @@ struct DrawBitmapNoScale { } #endif - const rgb_color* colorMap = SystemPalette(); + fColorMap = SystemPalette(); + fAlphaMask = aggInterface.fClippedAlphaMask; renderer_base& baseRenderer = aggInterface.fBaseRenderer; // copy rects, iterate over clipping boxes baseRenderer.first_clip_box(); do { - int32 x1 = max_c(baseRenderer.xmin(), left); - int32 x2 = min_c(baseRenderer.xmax(), right); - if (x1 <= x2) { - int32 y1 = max_c(baseRenderer.ymin(), top); - int32 y2 = min_c(baseRenderer.ymax(), bottom); - if (y1 <= y2) { - uint8* dstHandle = dst + y1 * dstBPR + x1 * 4; - const uint8* srcHandle = src + (y1 - offset.y) * srcBPR - + (x1 - offset.x) * bytesPerSourcePixel; + fRect.left = max_c(baseRenderer.xmin(), left); + fRect.right = min_c(baseRenderer.xmax(), right); + if (fRect.left <= fRect.right) { + fRect.top = max_c(baseRenderer.ymin(), top); + fRect.bottom = min_c(baseRenderer.ymax(), bottom); + if (fRect.top <= fRect.bottom) { + uint8* dstHandle = dst + fRect.top * dstBPR + + fRect.left * 4; + const uint8* srcHandle = src + + (fRect.top - offset.y) * srcBPR + + (fRect.left - offset.x) * bytesPerSourcePixel; - for (; y1 <= y2; y1++) { - BlendType::BlendRow(dstHandle, srcHandle, - x2 - x1 + 1, colorMap); + for (; fRect.top <= fRect.bottom; fRect.top++) { + static_cast(this)->BlendRow(dstHandle, + srcHandle, fRect.right - fRect.left + 1); dstHandle += dstBPR; srcHandle += srcBPR; @@ -76,18 +81,22 @@ struct DrawBitmapNoScale { } } while (baseRenderer.next_clip_box()); } + +protected: + IntRect fRect; + const rgb_color* fColorMap; + const agg::clipped_alpha_mask* fAlphaMask; }; struct CMap8Copy : public DrawBitmapNoScale { - static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color* colorMap) + void BlendRow(uint8* dst, const uint8* src, int32 numPixels) { uint32* d = (uint32*)dst; const uint8* s = src; while (numPixels--) { - const rgb_color c = colorMap[*s++]; + const rgb_color c = fColorMap[*s++]; *d++ = (c.alpha << 24) | (c.red << 16) | (c.green << 8) | (c.blue); } } @@ -96,13 +105,12 @@ struct CMap8Copy : public DrawBitmapNoScale struct CMap8Over : public DrawBitmapNoScale { - static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color* colorMap) + void BlendRow(uint8* dst, const uint8* src, int32 numPixels) { uint32* d = (uint32*)dst; const uint8* s = src; while (numPixels--) { - const rgb_color c = colorMap[*s++]; + const rgb_color c = fColorMap[*s++]; if (c.alpha) *d = (c.alpha << 24) | (c.red << 16) | (c.green << 8) | (c.blue); @@ -114,8 +122,7 @@ struct CMap8Over : public DrawBitmapNoScale struct Bgr32Copy : public DrawBitmapNoScale { - static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color*) + void BlendRow(uint8* dst, const uint8* src, int32 numPixels) { memcpy(dst, src, numPixels * 4); } @@ -124,8 +131,7 @@ struct Bgr32Copy : public DrawBitmapNoScale struct Bgr32Over : public DrawBitmapNoScale { - static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color*) + void BlendRow(uint8* dst, const uint8* src, int32 numPixels) { uint32* d = (uint32*)dst; uint32* s = (uint32*)src; @@ -141,8 +147,7 @@ struct Bgr32Over : public DrawBitmapNoScale struct Bgr32Alpha : public DrawBitmapNoScale { - static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color*) + void BlendRow(uint8* dst, const uint8* src, int32 numPixels) { uint32* d = (uint32*)dst; int32 bytes = numPixels * 4; @@ -166,4 +171,26 @@ struct Bgr32Alpha : public DrawBitmapNoScale }; +struct Bgr32CopyMasked : public DrawBitmapNoScale +{ + void BlendRow(uint8* dst, const uint8* src, int32 numPixels) + { + uint8 covers[numPixels]; + fAlphaMask->get_hspan(fRect.left, fRect.top, covers, numPixels); + + uint32* destination = (uint32*)dst; + uint32* source = (uint32*)src; + uint8* mask = (uint8*)&covers[0]; + + while (numPixels--) { + if (*mask != 0) + *destination = *source; + destination++; + source++; + mask++; + } + } +}; + + #endif // DRAW_BITMAP_NO_SCALE_H From 64c6e038ebf396d2bc65fae21533458355fd6b90 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Sat, 15 Aug 2015 12:50:32 +0200 Subject: [PATCH 022/370] app_server: bilinear bitmap painting: alpha overlay support * Add support for pixel alpha overlay mode in the optimized bilinear- scaled bitmap drawing code of BitmapPainter. For now, only BilinearDefault supports this. DrawBitmapBilinear gets the colour type and draw mode as template parameters to minimize code duplication and allow simple extension with further pixel formats and modes. Avoids, for this mode, fallback to the slower generic AGG-pipeline-based version. --- .../Painter/bitmap_painter/BitmapPainter.cpp | 16 +- .../bitmap_painter/DrawBitmapBilinear.h | 191 +++++++++++++++--- 2 files changed, 172 insertions(+), 35 deletions(-) diff --git a/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp b/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp index 813f291e90..d22e8c0e62 100644 --- a/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp +++ b/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp @@ -138,17 +138,27 @@ Painter::BitmapPainter::Draw(const BRect& sourceRect, if (fPainter->fDrawingMode == B_OP_COPY && !_HasAffineTransform() && !_HasAlphaMask()) { if ((fOptions & B_FILTER_BITMAP_BILINEAR) != 0) { - DrawBitmapBilinearCopy drawBilinear; + DrawBitmapBilinear drawBilinear; drawBilinear.Draw(fPainter, fPainter->fInternal, fBitmap, fOffset, fScaleX, fScaleY, fDestinationRect); - } - else { + } else { DrawBitmapNearestNeighborCopy::Draw(fPainter, fPainter->fInternal, fBitmap, fOffset, fScaleX, fScaleY, fDestinationRect); } return; } + if (fPainter->fDrawingMode == B_OP_ALPHA + && fPainter->fAlphaSrcMode == B_PIXEL_ALPHA + && fPainter->fAlphaFncMode == B_ALPHA_OVERLAY + && !_HasAffineTransform() && !_HasAlphaMask() + && (fOptions & B_FILTER_BITMAP_BILINEAR) != 0) { + DrawBitmapBilinear drawBilinear; + drawBilinear.Draw(fPainter, fPainter->fInternal, + fBitmap, fOffset, fScaleX, fScaleY, fDestinationRect); + return; + } + // for all other cases (non-optimized drawing mode or scaled drawing) DrawBitmapGeneric::Draw(fPainter, fPainter->fInternal, fBitmap, fOffset, fScaleX, fScaleY, fDestinationRect, fOptions); diff --git a/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapBilinear.h b/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapBilinear.h index 5dc75257a1..5268a6b2d4 100644 --- a/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapBilinear.h +++ b/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapBilinear.h @@ -10,6 +10,8 @@ #include "Painter.h" +#include + // Prototypes for assembler routines extern "C" { @@ -83,8 +85,8 @@ struct DrawBitmapBilinearOptimized { //printf("x: %ld - %ld\n", xIndexL, xIndexR); //printf("y: %ld - %ld\n", y1, y2); - OptimizedVersion optimizedVersion; - optimizedVersion.DrawToClipRect(xIndexL, xIndexR, y1, y2); + static_cast(this)->DrawToClipRect( + xIndexL, xIndexR, y1, y2); } while (baseRenderer.next_clip_box()); } @@ -99,7 +101,134 @@ protected: }; -struct BilinearDefault : DrawBitmapBilinearOptimized { +struct ColorTypeRgb { + static void + Interpolate(uint32* t, const uint8* s, uint32 sourceBytesPerRow, + uint16 wLeft, uint16 wTop, uint16 wRight, uint16 wBottom) + { + // left and right of top row + t[0] = (s[0] * wLeft + s[4] * wRight) * wTop; + t[1] = (s[1] * wLeft + s[5] * wRight) * wTop; + t[2] = (s[2] * wLeft + s[6] * wRight) * wTop; + + // left and right of bottom row + s += sourceBytesPerRow; + t[0] += (s[0] * wLeft + s[4] * wRight) * wBottom; + t[1] += (s[1] * wLeft + s[5] * wRight) * wBottom; + t[2] += (s[2] * wLeft + s[6] * wRight) * wBottom; + + t[0] >>= 16; + t[1] >>= 16; + t[2] >>= 16; + } + + static void + InterpolateLastColumn(uint32* t, const uint8* s, const uint8* sBottom, + uint16 wTop, uint16 wBottom) + { + t[0] = (s[0] * wTop + sBottom[0] * wBottom) >> 8; + t[1] = (s[1] * wTop + sBottom[1] * wBottom) >> 8; + t[2] = (s[2] * wTop + sBottom[2] * wBottom) >> 8; + } + + static void + InterpolateLastRow(uint32* t, const uint8* s, uint16 wLeft, + uint16 wRight) + { + t[0] = (s[0] * wLeft + s[4] * wRight) >> 8; + t[1] = (s[1] * wLeft + s[5] * wRight) >> 8; + t[2] = (s[2] * wLeft + s[6] * wRight) >> 8; + } +}; + + +struct ColorTypeRgba { + static void + Interpolate(uint32* t, const uint8* s, uint32 sourceBytesPerRow, + uint16 wLeft, uint16 wTop, uint16 wRight, uint16 wBottom) + { + // left and right of top row + t[0] = (s[0] * wLeft + s[4] * wRight) * wTop; + t[1] = (s[1] * wLeft + s[5] * wRight) * wTop; + t[2] = (s[2] * wLeft + s[6] * wRight) * wTop; + t[3] = (s[3] * wLeft + s[7] * wRight) * wTop; + + // left and right of bottom row + s += sourceBytesPerRow; + + t[0] += (s[0] * wLeft + s[4] * wRight) * wBottom; + t[1] += (s[1] * wLeft + s[5] * wRight) * wBottom; + t[2] += (s[2] * wLeft + s[6] * wRight) * wBottom; + t[3] += (s[3] * wLeft + s[7] * wRight) * wBottom; + + t[0] >>= 16; + t[1] >>= 16; + t[2] >>= 16; + t[3] >>= 16; + } + + static void + InterpolateLastColumn(uint32* t, const uint8* s, const uint8* sBottom, + uint16 wTop, uint16 wBottom) + { + t[0] = (s[0] * wTop + sBottom[0] * wBottom) >> 8; + t[1] = (s[1] * wTop + sBottom[1] * wBottom) >> 8; + t[2] = (s[2] * wTop + sBottom[2] * wBottom) >> 8; + t[3] = (s[3] * wTop + sBottom[3] * wBottom) >> 8; + } + + static void + InterpolateLastRow(uint32* t, const uint8* s, uint16 wLeft, + uint16 wRight) + { + t[0] = (s[0] * wLeft + s[4] * wRight) >> 8; + t[1] = (s[1] * wLeft + s[5] * wRight) >> 8; + t[2] = (s[2] * wLeft + s[6] * wRight) >> 8; + t[3] = (s[3] * wLeft + s[7] * wRight) >> 8; + } +}; + + +struct DrawModeCopy { + static void + Blend(uint8*& d, uint32* t) + { + d[0] = t[0]; + d[1] = t[1]; + d[2] = t[2]; + d += 4; + } +}; + + +struct DrawModeAlphaOverlay { + static void + Blend(uint8*& d, uint32* t) + { + uint8 t0 = t[0]; + uint8 t1 = t[1]; + uint8 t2 = t[2]; + uint8 t3 = t[3]; + + if (t3 == 255) { + d[0] = t0; + d[1] = t1; + d[2] = t2; + } else { + d[0] = ((t0 - d[0]) * t3 + (d[0] << 8)) >> 8; + d[1] = ((t1 - d[1]) * t3 + (d[1] << 8)) >> 8; + d[2] = ((t2 - d[2]) * t3 + (d[2] << 8)) >> 8; + } + + d += 4; + } +}; + + +template +struct BilinearDefault : + DrawBitmapBilinearOptimized > { + void DrawToClipRect(int32 xIndexL, int32 xIndexR, int32 y1, int32 y2) { // In this mode we anticipate many pixels wich need filtering, @@ -122,38 +251,33 @@ struct BilinearDefault : DrawBitmapBilinearOptimized { // buffer offset into source (top row) register const uint8* src = fSource->row_ptr(fWeightsY[y1].index); + // buffer handle for destination to be incremented per // pixel register uint8* d = fDestination; for (int32 x = xIndexL; x <= xIndexMax; x++) { const uint8* s = src + fWeightsX[x].index; + // calculate the weighted sum of all four // interpolated pixels const uint16 wLeft = fWeightsX[x].weight; const uint16 wRight = 255 - wLeft; - // left and right of top row - uint32 t0 = (s[0] * wLeft + s[4] * wRight) * wTop; - uint32 t1 = (s[1] * wLeft + s[5] * wRight) * wTop; - uint32 t2 = (s[2] * wLeft + s[6] * wRight) * wTop; - // left and right of bottom row - s += fSourceBytesPerRow; - t0 += (s[0] * wLeft + s[4] * wRight) * wBottom; - t1 += (s[1] * wLeft + s[5] * wRight) * wBottom; - t2 += (s[2] * wLeft + s[6] * wRight) * wBottom; - d[0] = t0 >> 16; - d[1] = t1 >> 16; - d[2] = t2 >> 16; - d += 4; + uint32 t[4]; + ColorType::Interpolate(&t[0], s, fSourceBytesPerRow, + wLeft, wTop, wRight, wBottom); + DrawMode::Blend(d, &t[0]); } // last column of pixels if necessary if (xIndexMax < xIndexR) { const uint8* s = src + fWeightsX[xIndexR].index; const uint8* sBottom = s + fSourceBytesPerRow; - d[0] = (s[0] * wTop + sBottom[0] * wBottom) >> 8; - d[1] = (s[1] * wTop + sBottom[1] * wBottom) >> 8; - d[2] = (s[2] * wTop + sBottom[2] * wBottom) >> 8; + + uint32 t[4]; + ColorType::InterpolateLastColumn(&t[0], s, sBottom, wTop, + wBottom); + DrawMode::Blend(d, &t[0]); } fDestination += fDestinationBytesPerRow; @@ -171,10 +295,9 @@ struct BilinearDefault : DrawBitmapBilinearOptimized { const uint8* s = src + fWeightsX[x].index; const uint16 wLeft = fWeightsX[x].weight; const uint16 wRight = 255 - wLeft; - d[0] = (s[0] * wLeft + s[4] * wRight) >> 8; - d[1] = (s[1] * wLeft + s[5] * wRight) >> 8; - d[2] = (s[2] * wLeft + s[6] * wRight) >> 8; - d += 4; + uint32 t[4]; + ColorType::InterpolateLastRow(&t[0], s, wLeft, wRight); + DrawMode::Blend(d, &t[0]); } } @@ -349,7 +472,8 @@ struct BilinearSimd : DrawBitmapBilinearOptimized { #endif // __INTEL__ -struct DrawBitmapBilinearCopy { +template +struct DrawBitmapBilinear { void Draw(const Painter* painter, PainterAggInterface& aggInterface, agg::rendering_buffer& bitmap, BPoint offset, @@ -466,20 +590,23 @@ struct DrawBitmapBilinearCopy { int codeSelect = kUseDefaultVersion; - uint32 neededSIMDFlags = APPSERVER_SIMD_MMX | APPSERVER_SIMD_SSE; - if ((gSIMDFlags & neededSIMDFlags) == neededSIMDFlags) - codeSelect = kUseSIMDVersion; - else { - if (scaleX == scaleY && (scaleX == 1.5 || scaleX == 2.0 - || scaleX == 2.5 || scaleX == 3.0)) { - codeSelect = kOptimizeForLowFilterRatio; + if (typeid(ColorType) == typeid(ColorTypeRgb) + && typeid(DrawMode) == typeid(DrawModeCopy)) { + uint32 neededSIMDFlags = APPSERVER_SIMD_MMX | APPSERVER_SIMD_SSE; + if ((gSIMDFlags & neededSIMDFlags) == neededSIMDFlags) + codeSelect = kUseSIMDVersion; + else { + if (scaleX == scaleY && (scaleX == 1.5 || scaleX == 2.0 + || scaleX == 2.5 || scaleX == 3.0)) { + codeSelect = kOptimizeForLowFilterRatio; + } } } switch (codeSelect) { case kUseDefaultVersion: { - BilinearDefault bilinearPainter; + BilinearDefault bilinearPainter; bilinearPainter.Draw(aggInterface, destinationRect, &bitmap, filterData); break; From 01c730420420627cf60877c5c018a8b180fa6ceb Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Sat, 15 Aug 2015 12:53:50 +0200 Subject: [PATCH 023/370] app_server: fix comment header in pixel alpha overlay modes --- .../Painter/drawing_modes/DrawingModeAlphaPO.h | 12 ++++++------ .../Painter/drawing_modes/DrawingModeAlphaPOSUBPIX.h | 2 +- .../Painter/drawing_modes/DrawingModeAlphaPOSolid.h | 8 ++++---- .../drawing_modes/DrawingModeAlphaPOSolidSUBPIX.h | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPO.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPO.h index bd82411c34..1d2d27f002 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPO.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPO.h @@ -2,7 +2,7 @@ * Copyright 2005, Stephan Aßmus . All rights reserved. * Distributed under the terms of the MIT License. * - * DrawingMode implementing B_OP_ALPHA in "Constant Overlay" mode on B_RGBA32. + * DrawingMode implementing B_OP_ALPHA in "Pixel Overlay" mode on B_RGBA32. * */ @@ -43,7 +43,7 @@ blend_pixel_alpha_po(int x, int y, const color_type& c, uint8 cover, // blend_hline_alpha_po void -blend_hline_alpha_po(int x, int y, unsigned len, +blend_hline_alpha_po(int x, int y, unsigned len, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { @@ -65,7 +65,7 @@ blend_hline_alpha_po(int x, int y, unsigned len, // blend_solid_hspan_alpha_po void -blend_solid_hspan_alpha_po(int x, int y, unsigned len, +blend_solid_hspan_alpha_po(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { @@ -90,7 +90,7 @@ blend_solid_hspan_alpha_po(int x, int y, unsigned len, // blend_solid_vspan_alpha_po void -blend_solid_vspan_alpha_po(int x, int y, unsigned len, +blend_solid_vspan_alpha_po(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { @@ -114,8 +114,8 @@ blend_solid_vspan_alpha_po(int x, int y, unsigned len, // blend_color_hspan_alpha_po void -blend_color_hspan_alpha_po(int x, int y, unsigned len, - const color_type* colors, +blend_color_hspan_alpha_po(int x, int y, unsigned len, + const color_type* colors, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSUBPIX.h index 7cc0b1c509..1d4227e8f3 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSUBPIX.h @@ -3,7 +3,7 @@ * Copyright 2008, Andrej Spielmann . * All rights reserved. Distributed under the terms of the MIT License. * - * DrawingMode implementing B_OP_ALPHA in "Constant Overlay" mode on B_RGBA32. + * DrawingMode implementing B_OP_ALPHA in "Pixel Overlay" mode on B_RGBA32. * */ diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolid.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolid.h index 53ea222f5b..fa850be0a8 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolid.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolid.h @@ -2,7 +2,7 @@ * Copyright 2005, Stephan Aßmus . All rights reserved. * Distributed under the terms of the MIT License. * - * DrawingMode implementing B_OP_ALPHA in "Constant Overlay" mode on B_RGBA32. + * DrawingMode implementing B_OP_ALPHA in "Pixel Overlay" mode on B_RGBA32. * */ @@ -27,7 +27,7 @@ blend_pixel_alpha_po_solid(int x, int y, const color_type& c, uint8 cover, // blend_hline_alpha_po_solid void -blend_hline_alpha_po_solid(int x, int y, unsigned len, +blend_hline_alpha_po_solid(int x, int y, unsigned len, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { @@ -64,7 +64,7 @@ blend_hline_alpha_po_solid(int x, int y, unsigned len, // blend_solid_hspan_alpha_po_solid void -blend_solid_hspan_alpha_po_solid(int x, int y, unsigned len, +blend_solid_hspan_alpha_po_solid(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { @@ -88,7 +88,7 @@ blend_solid_hspan_alpha_po_solid(int x, int y, unsigned len, // blend_solid_vspan_alpha_po_solid void -blend_solid_vspan_alpha_po_solid(int x, int y, unsigned len, +blend_solid_vspan_alpha_po_solid(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolidSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolidSUBPIX.h index e52632737c..c8b1f107b7 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolidSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolidSUBPIX.h @@ -3,7 +3,7 @@ * Copyright 2008, Andrej Spielmann . * All rights reserved. Distributed under the terms of the MIT License. * - * DrawingMode implementing B_OP_ALPHA in "Constant Overlay" mode on B_RGBA32. + * DrawingMode implementing B_OP_ALPHA in "Pixel Overlay" mode on B_RGBA32. * */ From ed7b139e08946d93fd3caf56dbc38e709b381094 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Sat, 15 Aug 2015 12:54:36 +0200 Subject: [PATCH 024/370] app_server: fix direct assignment in alpha pixel composite * 'alpha' is 16 bit (alpha * cover) in blend_hline_alpha_pc(), so compare with 255 * 255 --- .../Painter/drawing_modes/DrawingModeAlphaPC.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPC.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPC.h index 0313d3a00e..07a92b8703 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPC.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPC.h @@ -43,7 +43,7 @@ blend_pixel_alpha_pc(int x, int y, const color_type& c, uint8 cover, // blend_hline_alpha_pc void -blend_hline_alpha_pc(int x, int y, unsigned len, +blend_hline_alpha_pc(int x, int y, unsigned len, const color_type& c, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { @@ -52,7 +52,7 @@ blend_hline_alpha_pc(int x, int y, unsigned len, rgb_color color = pattern->ColorAt(x, y); uint16 alpha = color.alpha * cover; if (alpha) { - if (alpha == 255) { + if (alpha == 255 * 255) { ASSIGN_ALPHA_PC(p, color.red, color.green, color.blue); } else { BLEND_ALPHA_PC(p, color.red, color.green, color.blue, alpha); @@ -65,7 +65,7 @@ blend_hline_alpha_pc(int x, int y, unsigned len, // blend_solid_hspan_alpha_pc void -blend_solid_hspan_alpha_pc(int x, int y, unsigned len, +blend_solid_hspan_alpha_pc(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { @@ -88,7 +88,7 @@ blend_solid_hspan_alpha_pc(int x, int y, unsigned len, // blend_solid_vspan_alpha_pc void -blend_solid_vspan_alpha_pc(int x, int y, unsigned len, +blend_solid_vspan_alpha_pc(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { @@ -112,8 +112,8 @@ blend_solid_vspan_alpha_pc(int x, int y, unsigned len, // blend_color_hspan_alpha_pc void -blend_color_hspan_alpha_pc(int x, int y, unsigned len, - const color_type* colors, +blend_color_hspan_alpha_pc(int x, int y, unsigned len, + const color_type* colors, const uint8* covers, uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) { From 801b5d2119148b22e273b9c2639b41d979dc86fa Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Sat, 15 Aug 2015 12:56:37 +0200 Subject: [PATCH 025/370] app_server: add pixel alpha composite solid mode * Same concept as the previously exisiting drawing mode implementations for e.g. pixel alpha overlay mode: when pattern is solid, provide a separate mode implementation which does no unnecessary pattern pixel lookups. This provides a considerable speedup in composite mode when no stipple pattern is used. --- .../drawing_modes/DrawingModeAlphaPCSolid.h | 155 ++++++++++++++++++ .../Painter/drawing_modes/PixelFormat.cpp | 24 ++- 2 files changed, 172 insertions(+), 7 deletions(-) create mode 100644 src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSolid.h diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSolid.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSolid.h new file mode 100644 index 0000000000..da5f0de2ef --- /dev/null +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSolid.h @@ -0,0 +1,155 @@ +/* + * Copyright 2005, Stephan Aßmus + * Copyright 2015, Julian Harnath + * All rights reserved. Distributed under the terms of the MIT License. + * + * DrawingMode implementing B_OP_ALPHA in "Pixel Composite" mode on B_RGBA32. + * + */ + +#ifndef DRAWING_MODE_ALPHA_PC_SOLID_H +#define DRAWING_MODE_ALPHA_PC_SOLID_H + +#include "DrawingMode.h" + + +#define BLEND_ALPHA_PC(d, r, g, b, a) \ +{ \ + BLEND_COMPOSITE16(d, r, g, b, a); \ +} + + +#define ASSIGN_ALPHA_PC(d, r, g, b) \ +{ \ + d[0] = (b); \ + d[1] = (g); \ + d[2] = (r); \ + d[3] = 255; \ +} + + +void +blend_pixel_alpha_pc_solid(int x, int y, const color_type& color, uint8 cover, + agg_buffer* buffer, const PatternHandler*) +{ + uint8* p = buffer->row_ptr(y) + (x << 2); + uint16 alpha = color.a * cover; + if (alpha == 255 * 255) { + ASSIGN_ALPHA_PC(p, color.r, color.g, color.b); + } else { + BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha); + } +} + + +void +blend_hline_alpha_pc_solid(int x, int y, unsigned len, + const color_type& color, uint8 cover, + agg_buffer* buffer, const PatternHandler*) +{ + uint8* p = buffer->row_ptr(y) + (x << 2); + uint16 alpha = color.a * cover; + if (alpha == 0) + return; + + if (alpha == 255 * 255) { + do { + ASSIGN_ALPHA_PC(p, color.r, color.g, color.b); + p += 4; + } while(--len); + return; + } + + do { + BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha); + p += 4; + } while(--len); +} + + +void +blend_solid_hspan_alpha_pc_solid(int x, int y, unsigned len, + const color_type& color, const uint8* covers, + agg_buffer* buffer, const PatternHandler*) +{ + uint8* p = buffer->row_ptr(y) + (x << 2); + do { + uint16 alpha = color.a * *covers; + if (alpha) { + if(alpha == 255 * 255) { + ASSIGN_ALPHA_PC(p, color.r, color.g, color.b); + } else { + BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha); + } + } + covers++; + p += 4; + } while(--len); +} + + +void +blend_solid_vspan_alpha_pc_solid(int x, int y, unsigned len, + const color_type& color, const uint8* covers, + agg_buffer* buffer, const PatternHandler*) +{ + uint8* p = buffer->row_ptr(y) + (x << 2); + do { + uint16 alpha = color.a * *covers; + if (alpha) { + if (alpha == 255 * 255) { + ASSIGN_ALPHA_PC(p, color.r, color.g, color.b); + } else { + BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha); + } + } + covers++; + p += buffer->stride(); + } while(--len); +} + + +void +blend_color_hspan_alpha_pc_solid(int x, int y, unsigned len, + const color_type* colors, + const uint8* covers, uint8 cover, + agg_buffer* buffer, const PatternHandler*) +{ + uint8* p = buffer->row_ptr(y) + (x << 2); + if (covers) { + // non-solid opacity + do { + uint16 alpha = colors->a * *covers; + if (alpha) { + if (alpha == 255 * 255) { + ASSIGN_ALPHA_PC(p, colors->r, colors->g, colors->b); + } else { + BLEND_ALPHA_PC(p, colors->r, colors->g, colors->b, alpha); + } + } + covers++; + p += 4; + ++colors; + } while(--len); + } else { + // solid full opcacity + uint16 alpha = colors->a * cover; + if (alpha == 255 * 255) { + do { + ASSIGN_ALPHA_PC(p, colors->r, colors->g, colors->b); + p += 4; + ++colors; + } while(--len); + // solid partial opacity + } else if (alpha) { + do { + BLEND_ALPHA_PC(p, colors->r, colors->g, colors->b, alpha); + p += 4; + ++colors; + } while(--len); + } + } +} + + +#endif // DRAWING_MODE_ALPHA_PC_SOLID_H diff --git a/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp b/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp index 0e4508ffe3..40ca5d3505 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp +++ b/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp @@ -20,6 +20,7 @@ #include "DrawingModeAlphaCO.h" #include "DrawingModeAlphaCOSolid.h" #include "DrawingModeAlphaPC.h" +#include "DrawingModeAlphaPCSolid.h" #include "DrawingModeAlphaPO.h" #include "DrawingModeAlphaPOSolid.h" #include "DrawingModeBlend.h" @@ -211,7 +212,7 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, case B_OP_COPY: if (text) { fBlendPixel = blend_pixel_copy_text; - fBlendHLine = blend_hline_copy_text; + fBlendHLine = blend_hline_copy_text; fBlendSolidHSpanSubpix = blend_solid_hspan_copy_text_subpix; fBlendSolidHSpan = blend_solid_hspan_copy_text; fBlendSolidVSpan = blend_solid_vspan_copy_text; @@ -327,12 +328,21 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, } fBlendColorHSpan = blend_color_hspan_alpha_po; } else if (alphaFncMode == B_ALPHA_COMPOSITE) { - fBlendPixel = blend_pixel_alpha_pc; - fBlendHLine = blend_hline_alpha_pc; - fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_pc_subpix; - fBlendSolidHSpan = blend_solid_hspan_alpha_pc; - fBlendSolidVSpan = blend_solid_vspan_alpha_pc; - fBlendColorHSpan = blend_color_hspan_alpha_pc; + if (fPatternHandler->IsSolid()) { + fBlendPixel = blend_pixel_alpha_pc_solid; + fBlendHLine = blend_hline_alpha_pc_solid; + fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_pc_subpix; + fBlendSolidHSpan = blend_solid_hspan_alpha_pc_solid; + fBlendSolidVSpan = blend_solid_vspan_alpha_pc_solid; + fBlendColorHSpan = blend_color_hspan_alpha_pc_solid; + } else { + fBlendPixel = blend_pixel_alpha_pc; + fBlendHLine = blend_hline_alpha_pc; + fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_pc_subpix; + fBlendSolidHSpan = blend_solid_hspan_alpha_pc; + fBlendSolidVSpan = blend_solid_vspan_alpha_pc; + fBlendColorHSpan = blend_color_hspan_alpha_pc; + } } } break; From e3d73948690d37330da4349499d4974dcd328f70 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Sat, 15 Aug 2015 13:02:11 +0200 Subject: [PATCH 026/370] app_server: fix test-app_server for launch_daemon changes * Make test-app_server work again in a launch_daemon environment * test_registrar gets a separate signature and port name again so the host system can distinguish it from the system registrar * AppServer is normally a BServer now, however, there can't be two BApplications in one team. A class TestServerLoopAdapter is added, which becomes the base class of AppServer instead of BServer when compiling for libbe_test. It's an adapter class which looks towards AppServer as it if was a BServer, but internally it is derived from MessageLooper (like the old AppServer before the transition to BServer). This way, AppServer can stay a BServer in normal builds and it also avoids having to use too many #ifdefs to distinguish the two versions. --- headers/private/app/RegistrarDefs.h | 9 +- headers/private/app/ServerProtocol.h | 4 + src/kits/app/AppMisc.cpp | 60 +++++++++ src/kits/app/Roster.cpp | 15 ++- src/servers/app/AppServer.cpp | 8 +- src/servers/app/AppServer.h | 14 +- src/servers/app/MessageLooper.cpp | 4 +- src/servers/app/TestServerLoopAdapter.cpp | 121 ++++++++++++++++++ src/servers/app/TestServerLoopAdapter.h | 51 ++++++++ .../app/drawing/DWindowHWInterface.cpp | 3 +- src/servers/app/drawing/ViewHWInterface.cpp | 3 +- src/servers/app/test_app_server.rdef | 2 +- src/servers/registrar/Registrar.cpp | 2 +- src/tests/servers/app/Jamfile | 1 + src/tests/servers/registrar/Jamfile | 2 +- .../servers/registrar/run_test_registrar.cpp | 2 +- .../servers/registrar/test_registrar.rdef | 96 ++++++++++++++ 17 files changed, 381 insertions(+), 16 deletions(-) create mode 100644 src/servers/app/TestServerLoopAdapter.cpp create mode 100644 src/servers/app/TestServerLoopAdapter.h create mode 100644 src/tests/servers/registrar/test_registrar.rdef diff --git a/headers/private/app/RegistrarDefs.h b/headers/private/app/RegistrarDefs.h index 736edbf361..e58216951b 100644 --- a/headers/private/app/RegistrarDefs.h +++ b/headers/private/app/RegistrarDefs.h @@ -23,7 +23,14 @@ namespace BPrivate { extern const char* kRAppLooperPortName; -#define B_REGISTRAR_SIGNATURE "application/x-vnd.haiku-registrar" +#ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST +# define B_REGISTRAR_SIGNATURE "application/x-vnd.haiku-registrar" +# define B_REGISTRAR_PORT_NAME "system:roster" +#else +# define B_REGISTRAR_SIGNATURE "application/x-vnd.test-registrar" +# define B_REGISTRAR_PORT_NAME "haiku-test:roster" +#endif + #define B_REGISTRAR_AUTHENTICATION_PORT_NAME "auth" diff --git a/headers/private/app/ServerProtocol.h b/headers/private/app/ServerProtocol.h index 897baa18e2..8e6bc00f4f 100644 --- a/headers/private/app/ServerProtocol.h +++ b/headers/private/app/ServerProtocol.h @@ -16,6 +16,10 @@ #include +#ifdef HAIKU_TARGET_PLATFORM_LIBBE_TEST +# define SERVER_PORT_NAME "haiku-test:app_server" +#endif + #if TEST_MODE # define SERVER_INPUT_PORT "haiku-test:input port" #endif diff --git a/src/kits/app/AppMisc.cpp b/src/kits/app/AppMisc.cpp index 1a607f785f..e996190ab8 100644 --- a/src/kits/app/AppMisc.cpp +++ b/src/kits/app/AppMisc.cpp @@ -176,6 +176,9 @@ is_app_showing_modal_window(team_id team) } +#ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST + + /*! Creates a connection with the desktop. */ status_t @@ -208,4 +211,61 @@ create_desktop_connection(ServerLink* link, const char* name, int32 capacity) } +#else // HAIKU_TARGET_PLATFORM_LIBBE_TEST + + +static port_id sServerPort = -1; + + +port_id +get_app_server_port() +{ + if (sServerPort < 0) { + // No need for synchronization - in the worst case, we'll call + // find_port() twice. + sServerPort = find_port(SERVER_PORT_NAME); + } + + return sServerPort; +} + + +/*! Creates a connection with the desktop. +*/ +status_t +create_desktop_connection(ServerLink* link, const char* name, int32 capacity) +{ + port_id serverPort = get_app_server_port(); + if (serverPort < 0) + return serverPort; + + // Create the port so that the app_server knows where to send messages + port_id clientPort = create_port(capacity, name); + if (clientPort < 0) + return clientPort; + + link->SetTo(serverPort, clientPort); + + link->StartMessage(AS_GET_DESKTOP); + link->Attach(clientPort); + link->Attach(getuid()); + link->AttachString(getenv("TARGET_SCREEN")); + link->Attach(AS_PROTOCOL_VERSION); + + int32 code; + if (link->FlushWithReply(code) != B_OK || code != B_OK) { + link->SetSenderPort(-1); + return B_ERROR; + } + + link->Read(&serverPort); + link->SetSenderPort(serverPort); + + return B_OK; +} + + +#endif // HAIKU_TARGET_PLATFORM_LIBBE_TEST + + } // namespace BPrivate diff --git a/src/kits/app/Roster.cpp b/src/kits/app/Roster.cpp index dc6a914107..46433d1827 100644 --- a/src/kits/app/Roster.cpp +++ b/src/kits/app/Roster.cpp @@ -2604,9 +2604,10 @@ BRoster::_InitMessenger() DBG(OUT("BRoster::InitMessengers()\n")); // find the registrar port + +#ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST BMessage data; - if (BLaunchRoster().GetData("application/x-vnd.Haiku-registrar", data) - == B_OK) { + if (BLaunchRoster().GetData(B_REGISTRAR_SIGNATURE, data) == B_OK) { port_id port = data.GetInt32("port", -1); team_id team = data.GetInt32("team", -1); if (port >= 0) { @@ -2616,6 +2617,16 @@ BRoster::_InitMessenger() B_PREFERRED_TOKEN); } } +#else + port_id rosterPort = find_port(B_REGISTRAR_PORT_NAME); + port_info info; + if (rosterPort >= 0 && get_port_info(rosterPort, &info) == B_OK) { + DBG(OUT(" found roster port\n")); + + BMessenger::Private(fMessenger).SetTo(info.team, rosterPort, + B_PREFERRED_TOKEN); + } +#endif DBG(OUT("BRoster::InitMessengers() done\n")); } diff --git a/src/servers/app/AppServer.cpp b/src/servers/app/AppServer.cpp index 710d61c79a..9090086e72 100644 --- a/src/servers/app/AppServer.cpp +++ b/src/servers/app/AppServer.cpp @@ -48,7 +48,8 @@ uint32 gAppServerSIMDFlags = 0; */ AppServer::AppServer(status_t* status) : - BServer("application/x-vnd.Haiku-app_server", "picasso", -1, false, status), + SERVER_BASE("application/x-vnd.Haiku-app_server", "picasso", -1, false, + status), fDesktopLock("AppServerDesktopLock") { openlog("app_server", 0, LOG_DAEMON); @@ -153,7 +154,10 @@ AppServer::QuitRequested() wait_for_thread(thread, &status); } - return BServer::QuitRequested(); + delete this; + exit(0); + + return SERVER_BASE::QuitRequested(); #else return false; #endif diff --git a/src/servers/app/AppServer.h b/src/servers/app/AppServer.h index 9320edb9d1..e25beaad58 100644 --- a/src/servers/app/AppServer.h +++ b/src/servers/app/AppServer.h @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -23,12 +22,21 @@ #include "ServerConfig.h" +#ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST +# include +# define SERVER_BASE BServer +#else +# include "TestServerLoopAdapter.h" +# define SERVER_BASE TestServerLoopAdapter +#endif + + class ServerApp; class BitmapManager; class Desktop; -class AppServer : public BServer { +class AppServer : public SERVER_BASE { public: AppServer(status_t* status); virtual ~AppServer(); @@ -39,7 +47,7 @@ public: private: Desktop* _CreateDesktop(uid_t userID, const char* targetScreen); - Desktop* _FindDesktop(uid_t userID, + virtual Desktop* _FindDesktop(uid_t userID, const char* targetScreen); void _LaunchInputServer(); diff --git a/src/servers/app/MessageLooper.cpp b/src/servers/app/MessageLooper.cpp index e801712eed..2828b8ef4d 100644 --- a/src/servers/app/MessageLooper.cpp +++ b/src/servers/app/MessageLooper.cpp @@ -154,9 +154,9 @@ MessageLooper::_MessageLooper() Lock(); - if (code == kMsgQuitLooper) { + if (code == kMsgQuitLooper) Quit(); - } else + else _DispatchMessage(code, receiver); Unlock(); diff --git a/src/servers/app/TestServerLoopAdapter.cpp b/src/servers/app/TestServerLoopAdapter.cpp new file mode 100644 index 0000000000..a12cdc86b6 --- /dev/null +++ b/src/servers/app/TestServerLoopAdapter.cpp @@ -0,0 +1,121 @@ +/* + * Copyright 2001-2015, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Authors: + * DarkWyrm + * Axel Dörfler, axeld@pinc-software.de + * Stephan Aßmus + * Christian Packmann + * Julian Harnath + */ +#include "TestServerLoopAdapter.h" + +#include "Desktop.h" +#include "ServerConfig.h" +#include "ServerProtocol.h" + +#include + +#include + +//#define DEBUG_SERVER +#ifdef DEBUG_SERVER +# include +# define STRACE(x) printf x +#else +# define STRACE(x) ; +#endif + + +TestServerLoopAdapter::TestServerLoopAdapter(const char* signature, + const char*, port_id, bool, status_t* outError) + : + MessageLooper("test-app_server"), + fMessagePort(_CreatePort()) +{ + fLink.SetReceiverPort(fMessagePort); + *outError = B_OK; +} + + +TestServerLoopAdapter::~TestServerLoopAdapter() +{ +} + + +bool +TestServerLoopAdapter::Run() +{ + rename_thread(find_thread(NULL), "picasso"); + _message_thread((void*)this); + return true; +} + + +void +TestServerLoopAdapter::_DispatchMessage(int32 code, + BPrivate::LinkReceiver& link) +{ + switch (code) { + case AS_GET_DESKTOP: + { + port_id replyPort = 0; + link.Read(&replyPort); + + int32 userID = -1; + link.Read(&userID); + + char* targetScreen = NULL; + link.ReadString(&targetScreen); + + int32 version = -1; + link.Read(&version); + + BMessage message(AS_GET_DESKTOP); + message.AddInt32("user", userID); + message.AddInt32("version", version); + message.AddString("target", targetScreen); + MessageReceived(&message); + + // AppServer will try to send a reply, we just let that fail + // since we can find out the port by getting the desktop instance + // ourselves + + free(targetScreen); + Desktop* desktop = _FindDesktop(userID, targetScreen); + + BPrivate::LinkSender reply(replyPort); + if (desktop != NULL) { + reply.StartMessage(B_OK); + reply.Attach(desktop->MessagePort()); + } else + reply.StartMessage(B_ERROR); + + reply.Flush(); + + break; + } + + case B_QUIT_REQUESTED: + { + QuitRequested(); + break; + } + + default: + STRACE(("Server::MainLoop received unexpected code %" B_PRId32 " " + "(offset %" B_PRId32 ")\n", code, code - SERVER_TRUE)); + break; + } +} + + +port_id +TestServerLoopAdapter::_CreatePort() +{ + port_id port = create_port(DEFAULT_MONITOR_PORT_SIZE, SERVER_PORT_NAME); + if (port < B_OK) + debugger("test-app_server could not create message port"); + return port; +} diff --git a/src/servers/app/TestServerLoopAdapter.h b/src/servers/app/TestServerLoopAdapter.h new file mode 100644 index 0000000000..f3d2879f6e --- /dev/null +++ b/src/servers/app/TestServerLoopAdapter.h @@ -0,0 +1,51 @@ +/* + * Copyright 2001-2015, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Authors: + * DarkWyrm + * Axel Dörfler, axeld@pinc-software.de + * Julian Harnath, + */ +#ifndef TEST_SERVER_LOOP_ADAPTER_H +#define TEST_SERVER_LOOP_ADAPTER_H + +#include "MessageLooper.h" + + +class BMessage; +class Desktop; + + +class TestServerLoopAdapter : public MessageLooper { +public: + TestServerLoopAdapter(const char* signature, + const char* looperName, port_id port, + bool initGui, status_t* outError); + virtual ~TestServerLoopAdapter(); + + // MessageLooper interface + virtual port_id MessagePort() const { return fMessagePort; } + virtual bool Run(); + + // BApplication interface + virtual void MessageReceived(BMessage* message) = 0; + virtual bool QuitRequested() { return true; } + +private: + // MessageLooper interface + virtual void _DispatchMessage(int32 code, + BPrivate::LinkReceiver &link); + + virtual Desktop* _FindDesktop(uid_t userID, + const char* targetScreen) = 0; + port_id _CreatePort(); + + + +private: + port_id fMessagePort; +}; + + +#endif // TEST_SERVER_LOOP_ADAPTER_H diff --git a/src/servers/app/drawing/DWindowHWInterface.cpp b/src/servers/app/drawing/DWindowHWInterface.cpp index a903ab5b1a..70e535c7b5 100644 --- a/src/servers/app/drawing/DWindowHWInterface.cpp +++ b/src/servers/app/drawing/DWindowHWInterface.cpp @@ -694,7 +694,8 @@ DWindowHWInterface::SetMode(const display_mode& mode) // has not been created either, but we need one to display // a real BWindow in the test environment. // be_app->Run() needs to be called in another thread - BApplication* app = new BApplication("application/x-vnd.haiku-app-server"); + BApplication* app = new BApplication( + "application/x-vnd.Haiku-test-app_server"); app->Unlock(); thread_id appThread = spawn_thread(run_app_thread, "app thread", diff --git a/src/servers/app/drawing/ViewHWInterface.cpp b/src/servers/app/drawing/ViewHWInterface.cpp index fe4ca9879c..4fec110348 100644 --- a/src/servers/app/drawing/ViewHWInterface.cpp +++ b/src/servers/app/drawing/ViewHWInterface.cpp @@ -483,7 +483,8 @@ ViewHWInterface::SetMode(const display_mode& mode) // has not been created either, but we need one to display // a real BWindow in the test environment. // be_app->Run() needs to be called in another thread - BApplication* app = new BApplication("application/x-vnd.haiku-app-server"); + BApplication* app = new BApplication( + "application/x-vnd.Haiku-test-app_server"); app->Unlock(); thread_id appThread = spawn_thread(run_app_thread, "app thread", diff --git a/src/servers/app/test_app_server.rdef b/src/servers/app/test_app_server.rdef index 29a0c4c9fe..e71bea4fbc 100644 --- a/src/servers/app/test_app_server.rdef +++ b/src/servers/app/test_app_server.rdef @@ -2,7 +2,7 @@ * app_server.rdef */ -resource app_signature "application/x-vnd.Haiku-app-server"; +resource app_signature "application/x-vnd.Haiku-test-app_server"; resource app_flags B_EXCLUSIVE_LAUNCH ; diff --git a/src/servers/registrar/Registrar.cpp b/src/servers/registrar/Registrar.cpp index 79b3d02a66..7987a1bc63 100644 --- a/src/servers/registrar/Registrar.cpp +++ b/src/servers/registrar/Registrar.cpp @@ -57,7 +57,7 @@ static const bigtime_t kRosterSanityEventInterval = 1000000LL; */ Registrar::Registrar(status_t* _error) : - BServer(B_REGISTRAR_SIGNATURE, "system:roster", -1, false, _error), + BServer(B_REGISTRAR_SIGNATURE, B_REGISTRAR_PORT_NAME, -1, false, _error), fRoster(NULL), fClipboardHandler(NULL), fMIMEManager(NULL), diff --git a/src/tests/servers/app/Jamfile b/src/tests/servers/app/Jamfile index de8d379f46..24598d765f 100644 --- a/src/tests/servers/app/Jamfile +++ b/src/tests/servers/app/Jamfile @@ -127,6 +127,7 @@ SharedLibrary libtestappserver.so : ProfileMessageSupport.cpp EventDispatcher.cpp EventStream.cpp + TestServerLoopAdapter.cpp MessageLooper.cpp # Decorator diff --git a/src/tests/servers/registrar/Jamfile b/src/tests/servers/registrar/Jamfile index 91d8c362c2..fe142624dc 100644 --- a/src/tests/servers/registrar/Jamfile +++ b/src/tests/servers/registrar/Jamfile @@ -110,7 +110,7 @@ Server test_registrar libstorage_kit_mime.a be localestub [ TargetLibstdc++ ] : - registrar.rdef + test_registrar.rdef ; if $(TARGET_PLATFORM) = libbe_test { diff --git a/src/tests/servers/registrar/run_test_registrar.cpp b/src/tests/servers/registrar/run_test_registrar.cpp index 20cf63bcb1..a32a2382a7 100644 --- a/src/tests/servers/registrar/run_test_registrar.cpp +++ b/src/tests/servers/registrar/run_test_registrar.cpp @@ -53,7 +53,7 @@ main(int argc, char* argv[]) while (get_next_thread_info(teamInfo.team, &threadCookie, &threadInfo) == B_OK) { // search for the roster thread - if (!strcmp(threadInfo.name, "_roster_thread_")) { + if (!strcmp(threadInfo.name, "roster")) { port_id port = find_port("haiku-test:roster"); port_info portInfo; if (get_port_info(port, &portInfo) == B_OK diff --git a/src/tests/servers/registrar/test_registrar.rdef b/src/tests/servers/registrar/test_registrar.rdef new file mode 100644 index 0000000000..2748c0b157 --- /dev/null +++ b/src/tests/servers/registrar/test_registrar.rdef @@ -0,0 +1,96 @@ +/* + * registrar.rdef + */ + +resource app_signature "application/x-vnd.test-registrar"; + +resource app_flags B_EXCLUSIVE_LAUNCH | B_BACKGROUND_APP; + /* the registrar's application flags are actually + * ignored. + * The actually used flags are set in TRoster::Init(). + */ + +resource app_version { + major = 1, + middle = 0, + minor = 0, + + variety = B_APPV_ALPHA, + internal = 0, + + short_info = "registrar", + long_info = "registrar ©2005-2008 Haiku Inc." +}; + +#ifdef HAIKU_TARGET_PLATFORM_HAIKU + +resource vector_icon array { + $"6E6369660704006B0500020006023BB8A43D8642BF898E3DBC1F4BAE5447805C" + $"00E3AD00FFBC8F05020106023D66A73B07B6B9BEF73C1A2B48379549C4DE3D76" + $"9564FF536E4402000602B898C93319083A5C163FF4CC4AB5EA4451BB00B58A00" + $"FF8565030200060236EEF83B80F5BF3E743AB74A4B669742DBD600FFEFC0FFFF" + $"DE7C05FF0D0A044D5B585B59594D530A0626484C5B4E594E32282626270A0426" + $"484C5B4C3426270A0448542A452A2C48370A042C442C2D2A2C2A450A044C5B4E" + $"594E324C340A04282626274C344E320A042A45485448512C4408023133313C08" + $"023534353E08023936394008023D373D4208022E344040090A00010010011584" + $"00040A0101011001178400040A020102000A030103000A040104000A04010500" + $"0A050106000A050107000A06050C0B0A0908100117820004" +}; + +#else + +resource large_icon array { + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFF00D9D9D90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFF00D98383D9D90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFF00D900008383D9D90000FFFFFFFFFFFFFFFFFF00000000FFFFFFFFFF" + $"FFFFFFFF00D9008F00008383D9D9000000000000FFFF003FD9D9D90000FFFFFF" + $"FFFFFFFF00D9008F8F8F00008383D9D900003F3F00003FD9D9D9D9D9D90000FF" + $"FFFFFFFF00D9008F3F8F8F8F00008383D9D900003F3FAAAAD9D9D9D9D9D98300" + $"FFFFFFFF00D9003F3F8F3F8F8F8F00008383D9D900008383AAAAD9D9D983AA00" + $"FFFFFFFF00D9008F3F3F3F8F3F8F8F8F00008383D9D900003F3FAAAA83AAAA00" + $"FFFFFFFF00D9008F3F8F3F8F3F8F8F8F8F8F00008383D9D900D93F3FAAAAAA00" + $"FFFFFFFF00D9008F3F8F3F3F3F8F8F8F8F8F8F8F000083AA00D9D9D983AA0111" + $"FFFFFFFF00D9008F8F8F3F8F3F8F8F8F8F8F8F8F8F0083AA00D9D9D9D9AA0017" + $"FFFFFFFF00D9008F8F8F8F8F3F3F8F8F8F8F8F8F8F0083AA00D9D9D9D9830011" + $"FFFFFFFF00D9008F8F8F8F8F8F8F3F8F8F8F8F8F8F0083AA00D9D9D983AA0111" + $"FFFFFFFF00D900008F8F8F8F8F8F8F8F8F8F8F8F8F0083AA00D9D983AA001111" + $"FFFFFFFF0000838300008F8F8F8F8F8F8F8F8F8F8F0083AA00D983AA001111FF" + $"FFFFFFFFFF000000838300008F8F8F8F8F8F8F8F8F0083AA0083AA001111FFFF" + $"FFFFFFFF003FD9830000838300008F8F8F8F8F8F8F0083AA00AA001111FFFFFF" + $"FFFFFF003FD98383001E0000838300008F8F8F8F8F0083AA00001111FFFFFFFF" + $"FFFF003FD98383031ED9D9830000838300008F8F8F0083AA001111FFFFFFFFFF" + $"FF003FD98383003FD9D98383003F0000838300008F0083AA0011FFFFFFFFFFFF" + $"003FD98383003FD9D98383003FD9D9D900008383000083AA0011FFFFFFFFFFFF" + $"00D98383003FD9D98383003FD9D98383003F0000838383AA0011FFFFFFFFFFFF" + $"FF0000003FD9D98383003FD9D98383003FD98383000083001111FFFFFFFFFFFF" + $"FFFF003FD9D98383003FD9D98383003FD98383001111001111FFFFFFFFFFFFFF" + $"FFFF00D9838306003FD9D98383003FD98383001111FFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFF0000001000D9D98383003FD98383001111FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFF000000003FD98300001111FFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF000000111111FFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" +}; + +resource mini_icon array { + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFF000000FFFFFFFFFFFFFFFFFFFFFF" + $"FF03D9D9D90000FFFFFFFF0000FFFFFF" + $"FF03D9B6B6D9D900000000D9D90000FF" + $"FF03D9B669B6B6D9D90000AAAAD98300" + $"FF03D9B6116868B6B6D9D9003FAAAA00" + $"FF03D9B68F681B8FB683AA00D9D9AA00" + $"FF03D9B68F181B8FB683AA003FD9AA01" + $"FF03D9B6B68F188FB683AA00D9830011" + $"FF03038383B6B68FB683AA00830011FF" + $"FF00D933048383B6B683AA000011FFFF" + $"00D98300D90303838383AA0011FFFFFF" + $"008300D98300D90303030011FFFFFFFF" + $"FF00D98300D900D9830011FFFFFFFFFF" + $"FFFF0000000000000011FFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" +}; + +#endif // HAIKU_TARGET_PLATFORM_HAIKU From 1cd452ea0362086a2cdcaf93fbec292f23ff9d78 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Sun, 23 Aug 2015 00:29:38 +0200 Subject: [PATCH 027/370] app_server: Drawing mode fixups * TODO: squash commit before merge into master --- src/servers/app/DrawState.cpp | 11 ++++++++--- src/servers/app/DrawState.h | 4 ++-- src/servers/app/ServerPicture.cpp | 4 ++-- src/servers/app/ServerWindow.cpp | 6 ++++-- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/servers/app/DrawState.cpp b/src/servers/app/DrawState.cpp index de5c81173e..8d07c8e453 100644 --- a/src/servers/app/DrawState.cpp +++ b/src/servers/app/DrawState.cpp @@ -526,21 +526,26 @@ DrawState::SetPattern(const Pattern& pattern) } -void +bool DrawState::SetDrawingMode(drawing_mode mode) { - if (!fDrawingModeLocked) + if (!fDrawingModeLocked) { fDrawingMode = mode; + return true; + } + return false; } -void +bool DrawState::SetBlendingMode(source_alpha srcMode, alpha_function fncMode) { if (!fDrawingModeLocked) { fAlphaSrcMode = srcMode; fAlphaFncMode = fncMode; + return true; } + return false; } diff --git a/src/servers/app/DrawState.h b/src/servers/app/DrawState.h index 7e7274cdf3..6f39022b92 100644 --- a/src/servers/app/DrawState.h +++ b/src/servers/app/DrawState.h @@ -100,11 +100,11 @@ public: { return fPattern; } // drawing/blending mode - void SetDrawingMode(drawing_mode mode); + bool SetDrawingMode(drawing_mode mode); drawing_mode GetDrawingMode() const { return fDrawingMode; } - void SetBlendingMode(source_alpha srcMode, + bool SetBlendingMode(source_alpha srcMode, alpha_function fncMode); source_alpha AlphaSrcMode() const { return fAlphaSrcMode; } diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index bec689149f..20d3719c4e 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -626,8 +626,8 @@ set_pen_location(Canvas* canvas, BPoint pt) static void set_drawing_mode(Canvas* canvas, drawing_mode mode) { - canvas->CurrentState()->SetDrawingMode(mode); - canvas->GetDrawingEngine()->SetDrawingMode(mode); + if (canvas->CurrentState()->SetDrawingMode(mode)) + canvas->GetDrawingEngine()->SetDrawingMode(mode); } diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 369e13454a..b91ce89115 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -2200,7 +2200,8 @@ fDesktop->LockSingleWindow(); if (opacity != 255) { fCurrentView->CurrentState()->SetDrawingMode(B_OP_ALPHA); - fCurrentView->CurrentState()->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE); + fCurrentView->CurrentState()->SetBlendingMode(B_PIXEL_ALPHA, + B_ALPHA_COMPOSITE); fCurrentView->CurrentState()->SetDrawingModeLocked(true); } @@ -3466,7 +3467,8 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link) if (opacity != 255) { fCurrentView->CurrentState()->SetDrawingMode(B_OP_ALPHA); - fCurrentView->CurrentState()->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE); + fCurrentView->CurrentState()->SetBlendingMode(B_PIXEL_ALPHA, + B_ALPHA_COMPOSITE); fCurrentView->CurrentState()->SetDrawingModeLocked(true); } From bafd2b461acb32cfb40755067d408e480b0d099e Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Sun, 23 Aug 2015 00:31:10 +0200 Subject: [PATCH 028/370] app_server: PictureBoundingBoxPlayer fixups * TODO: squash commit before merge into master --- src/servers/app/PictureBoundingBoxPlayer.cpp | 12 ++++++------ src/servers/app/PictureBoundingBoxPlayer.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/servers/app/PictureBoundingBoxPlayer.cpp b/src/servers/app/PictureBoundingBoxPlayer.cpp index b330a78265..c8b931ce0c 100644 --- a/src/servers/app/PictureBoundingBoxPlayer.cpp +++ b/src/servers/app/PictureBoundingBoxPlayer.cpp @@ -50,12 +50,12 @@ typedef PictureBoundingBoxPlayer::State BoundingBoxState; class PictureBoundingBoxPlayer::State { public: - State(DrawState* drawState, BRect* boundingBox) + State(const DrawState* drawState, BRect* boundingBox) : fDrawState(drawState->Squash()), fBoundingBox(boundingBox) { - fBoundingBox->Set(INT_MAX, INT_MAX, 0, 0); + fBoundingBox->Set(INT_MAX, INT_MAX, INT_MIN, INT_MIN); } ~State() @@ -97,7 +97,7 @@ public: private: void _AffineTransformRect(BRect& rect) { - BAffineTransform transform = fDrawState->Transform(); + BAffineTransform transform = fDrawState->CombinedTransform(); if (transform.IsIdentity()) return; @@ -111,8 +111,8 @@ private: float minX = INT_MAX; float minY = INT_MAX; - float maxX = 0; - float maxY = 0; + float maxX = INT_MIN; + float maxY = INT_MIN; for (uint32 i = 0; i < 4; i++) { if (transformedShape[i].x < minX) @@ -776,7 +776,7 @@ const static void* kTableEntries[] = { /* static */ void PictureBoundingBoxPlayer::Play(ServerPicture* picture, - DrawState* drawState, BRect* outBoundingBox) + const DrawState* drawState, BRect* outBoundingBox) { State state(drawState, outBoundingBox); diff --git a/src/servers/app/PictureBoundingBoxPlayer.h b/src/servers/app/PictureBoundingBoxPlayer.h index 37ae88e2c3..115f1acbfb 100644 --- a/src/servers/app/PictureBoundingBoxPlayer.h +++ b/src/servers/app/PictureBoundingBoxPlayer.h @@ -20,7 +20,7 @@ public: public: static void Play(ServerPicture* picture, - DrawState* drawState, + const DrawState* drawState, BRect* outBoundingBox); }; From 9b417f6486256a8166b79c1f92178503e39c4408 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Sun, 23 Aug 2015 00:38:55 +0200 Subject: [PATCH 029/370] app_server: rework AlphaMask, use bounds for mask pictures * Refactor AlphaMask class to separate the mask from its source. This allows use to not just a BPicture as source for a pixel alpha mask, but also e.g. a BShape in the future (not yet implemented). * For BPicture-based masks, use the PictureBoundingBoxPlayer to determine the size of the resulting mask bitmap. The masks are now drawn into bitmaps of this size (instead of the whole view size). When alpha masks are stacked, their bounding rectangles intersect (i.e. masks further up in the stack can never be larger than masks lower in the stack). The bitmap of a mask always contains the state of itself blended with all masks in the stack below it. This also avoids frequent rerendering of the masks. They are now independent of view size. When the view origin (in screen coordinates) changes we only have to reattach the mask buffer, without having to redraw it. * The class UniformAlphaMask is used for simple masks with the same alpha value in all pixels, it uses no mask bitmap at all. Currently, it can only be used on its own and not be stacked together with other mask types. --- src/servers/app/Canvas.cpp | 2 +- src/servers/app/DrawState.cpp | 25 +- src/servers/app/DrawState.h | 5 +- src/servers/app/Layer.cpp | 6 +- src/servers/app/ServerWindow.cpp | 8 +- src/servers/app/drawing/AlphaMask.cpp | 492 ++++++++++++-------- src/servers/app/drawing/AlphaMask.h | 122 +++-- src/servers/app/drawing/Painter/Painter.cpp | 3 +- 8 files changed, 397 insertions(+), 266 deletions(-) diff --git a/src/servers/app/Canvas.cpp b/src/servers/app/Canvas.cpp index 3c53676e62..66e28ed770 100644 --- a/src/servers/app/Canvas.cpp +++ b/src/servers/app/Canvas.cpp @@ -246,7 +246,7 @@ Canvas::BlendLayer(Layer* layer) fDrawState->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE); fDrawState->SetTransformEnabled(false); - AlphaMask* mask = new AlphaMask(layer->Opacity()); + AlphaMask* mask = new UniformAlphaMask(layer->Opacity()); if (mask == NULL) { layerBitmap->ReleaseReference(); return; diff --git a/src/servers/app/DrawState.cpp b/src/servers/app/DrawState.cpp index 8d07c8e453..8bae0e1ebb 100644 --- a/src/servers/app/DrawState.cpp +++ b/src/servers/app/DrawState.cpp @@ -110,8 +110,6 @@ DrawState::~DrawState() { delete fClippingRegion; delete fPreviousState; - if (fAlphaMask != NULL) - fAlphaMask->ReleaseReference(); } @@ -389,15 +387,10 @@ DrawState::SetTransformEnabled(bool enabled) DrawState* -DrawState::Squash() +DrawState::Squash() const { DrawState* const squashedState = new DrawState(*this); - - squashedState->fOrigin = fCombinedOrigin; - squashedState->fScale = fCombinedScale; - squashedState->fTransform = fCombinedTransform; - - return squashedState; + return squashedState->PushState(); } @@ -461,24 +454,14 @@ DrawState::SetAlphaMask(AlphaMask* mask) { // NOTE: In BeOS, it wasn't possible to clip to a BPicture and keep // regular custom clipping to a BRegion at the same time. - if (fAlphaMask == mask) - return; - - if (mask != NULL) - mask->AcquireReference(); - if (fAlphaMask != NULL) - fAlphaMask->ReleaseReference(); - fAlphaMask = mask; - if (fAlphaMask != NULL && fPreviousState != NULL) - fAlphaMask->SetPrevious(fPreviousState->fAlphaMask); - + fAlphaMask.SetTo(mask); } AlphaMask* DrawState::GetAlphaMask() const { - return fAlphaMask; + return fAlphaMask.Get(); } diff --git a/src/servers/app/DrawState.h b/src/servers/app/DrawState.h index 6f39022b92..3572874b7a 100644 --- a/src/servers/app/DrawState.h +++ b/src/servers/app/DrawState.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "ServerFont.h" @@ -70,7 +71,7 @@ public: { return fCombinedTransform; } void SetTransformEnabled(bool enabled); - DrawState* Squash(); + DrawState* Squash() const; // additional clipping as requested by client void SetClippingRegion(const BRegion* region); @@ -166,7 +167,7 @@ protected: BRegion* fClippingRegion; - AlphaMask* fAlphaMask; + BReference fAlphaMask; rgb_color fHighColor; rgb_color fLowColor; diff --git a/src/servers/app/Layer.cpp b/src/servers/app/Layer.cpp index 1c80ad736b..96bf38eafd 100644 --- a/src/servers/app/Layer.cpp +++ b/src/servers/app/Layer.cpp @@ -121,10 +121,10 @@ Layer::RenderToBitmap(Canvas* canvas) LayerCanvas layerCanvas(layerEngine, canvas->CurrentState()); AlphaMask* const mask = layerCanvas.GetAlphaMask(); - BPoint oldOffset; + IntPoint oldOffset; if (mask != NULL) { // Move alpha mask to bitmap origin - oldOffset = mask->Update(BPoint(0, 0)); + oldOffset = mask->SetViewOrigin(IntPoint(0, 0)); } canvas->CurrentState()->SetDrawingMode(B_OP_ALPHA); @@ -147,7 +147,7 @@ Layer::RenderToBitmap(Canvas* canvas) // Note: this needs to be adapted if setting alpha masks is // implemented as BPicture command (the mask now might be a different // one than before). - mask->Update(oldOffset); + mask->SetViewOrigin(oldOffset); layerCanvas.ResyncDrawState(); } diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index b91ce89115..7322cd8adc 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -1942,11 +1942,13 @@ fDesktop->LockSingleWindow(); if (picture == NULL) break; - AlphaMask* mask = new(std::nothrow) AlphaMask( - picture, inverse, where, *fCurrentView->CurrentState()); + AlphaMask* const mask = new PictureAlphaMask( + fCurrentView->GetAlphaMask(), picture, + *fCurrentView->CurrentState(), where, inverse); fCurrentView->SetAlphaMask(mask); if (mask != NULL) mask->ReleaseReference(); + _UpdateDrawState(fCurrentView); picture->ReleaseReference(); @@ -3812,7 +3814,7 @@ ServerWindow::_UpdateDrawState(View* view) BPoint leftTop(0, 0); if (view->GetAlphaMask() != NULL) { view->LocalToScreenTransform().Apply(&leftTop); - view->GetAlphaMask()->Update(view->Bounds(), leftTop); + view->GetAlphaMask()->SetViewOrigin(leftTop); leftTop = BPoint(0, 0); } view->PenToScreenTransform().Apply(&leftTop); diff --git a/src/servers/app/drawing/AlphaMask.cpp b/src/servers/app/drawing/AlphaMask.cpp index 865425a391..fc5e00659d 100644 --- a/src/servers/app/drawing/AlphaMask.cpp +++ b/src/servers/app/drawing/AlphaMask.cpp @@ -15,222 +15,73 @@ #include "BitmapManager.h" #include "Canvas.h" #include "DrawingEngine.h" +#include "PictureBoundingBoxPlayer.h" #include "ServerBitmap.h" #include "ServerPicture.h" +#include "Shape.h" -AlphaMask::AlphaMask(ServerPicture* picture, bool inverse, BPoint origin, - const DrawState& drawState) +// #pragma mark - AlphaMask + + +AlphaMask::AlphaMask(AlphaMask* previousMask, bool inverse) : - fPreviousMask(NULL), - - fPicture(picture), + fPreviousMask(previousMask), + fBounds(), + fViewOrigin(), fInverse(inverse), - fOrigin(origin), fBackgroundOpacity(0), - fDrawState(drawState), - - fViewBounds(), - fViewOffset(), - - fCachedBitmap(NULL), - fCachedBounds(), - fCachedOffset(), - + fBits(NULL), fBuffer(), - fCachedMask(), - fScanline(fCachedMask) + fMask(), + fScanline(fMask) { - fPicture->AcquireReference(); } AlphaMask::AlphaMask(uint8 backgroundOpacity) : - fPreviousMask(NULL), - - fPicture(NULL), + fPreviousMask(), + fBounds(), + fViewOrigin(), fInverse(false), - fOrigin(0, 0), fBackgroundOpacity(backgroundOpacity), - fDrawState(), - - fViewBounds(), - fViewOffset(), - - fCachedBitmap(NULL), - fCachedBounds(), - fCachedOffset(), - + fBits(NULL), fBuffer(), - fCachedMask(), - fScanline(fCachedMask) + fMask(), + fScanline(fMask) { } AlphaMask::~AlphaMask() { - if (fPicture != NULL) - fPicture->ReleaseReference(); - delete[] fCachedBitmap; - SetPrevious(NULL); + delete[] fBits; } -void -AlphaMask::Update(BRect bounds, BPoint offset) +IntPoint +AlphaMask::SetViewOrigin(IntPoint viewOrigin) { - fViewBounds = bounds; - fViewOffset = offset; + if (viewOrigin == fViewOrigin) + return fViewOrigin; - if (fPreviousMask != NULL) - fPreviousMask->Update(bounds, offset); -} + IntPoint oldOrigin = fViewOrigin; + fViewOrigin = viewOrigin; - -BPoint -AlphaMask::Update(BPoint offset) -{ - BPoint oldOffset = fViewOffset; - fViewOffset = offset; - - if (oldOffset == fCachedOffset && fCachedBitmap != NULL) { - // No need to redraw the picture when only the offset is shifted - fCachedOffset = offset; - _AttachMaskToBuffer(); - } - - if (fPreviousMask != NULL) - fPreviousMask->Update(offset); - - return oldOffset; -} - - -void -AlphaMask::SetPrevious(AlphaMask* mask) -{ - // Since multiple DrawStates can point to the same AlphaMask, - // don't accept ourself as the "previous" mask on the state stack. - if (mask == this || mask == fPreviousMask) - return; - - if (mask != NULL) - mask->AcquireReference(); - if (fPreviousMask != NULL) - fPreviousMask->ReleaseReference(); - fPreviousMask = mask; -} - - -scanline_unpacked_masked_type* -AlphaMask::Generate() -{ - if (fPicture == NULL) { - fBuffer.attach(NULL, 0, 0, 0); - _AttachMaskToBuffer(); - return &fScanline; - } - - if (!fViewBounds.IsValid()) - return NULL; - - // See if a cached bitmap can be used. Don't use it when the view offset - // or bounds have changed. - if (fCachedBitmap != NULL - && fViewBounds == fCachedBounds && fViewOffset == fCachedOffset) { - return &fScanline; - } - - uint32 width = fViewBounds.IntegerWidth() + 1; - uint32 height = fViewBounds.IntegerHeight() + 1; - - if (fViewBounds != fCachedBounds || fCachedBitmap == NULL) { - delete[] fCachedBitmap; - fCachedBitmap = new(std::nothrow) uint8[width * height]; - } - - // If rendering the picture fails, we will draw without any clipping. - ServerBitmap* bitmap = _RenderPicture(); - if (bitmap == NULL || fCachedBitmap == NULL) { - fBuffer.attach(NULL, 0, 0, 0); - return NULL; - } - - uint8* bits = bitmap->Bits(); - uint32 bytesPerRow = bitmap->BytesPerRow(); - uint8* row = bits; - uint8* pixel = fCachedBitmap; - - // Let any previous masks also regenerate themselves. Updating the cached - // mask bitmap is only necessary after the view size changed or the - // scrolling offset, which definitely affects any masks of lower states - // as well, so it works recursively until the bottom mask is regenerated. - bool transferBitmap = true; - if (fPreviousMask != NULL) { - fPreviousMask->Generate(); - if (fPreviousMask->fCachedBitmap != NULL) { - uint8* previousBits = fPreviousMask->fCachedBitmap; - for (uint32 y = 0; y < height; y++) { - for (uint32 x = 0; x < width; x++) { - if (previousBits[0] != 0) { - if (fInverse) - pixel[0] = 255 - row[3]; - else - pixel[0] = row[3]; - pixel[0] = pixel[0] * previousBits[0] / 255; - } else - pixel[0] = 0; - previousBits++; - pixel++; - row += 4; - } - bits += bytesPerRow; - row = bits; - } - transferBitmap = false; - } - } - - if (transferBitmap) { - for (uint32 y = 0; y < height; y++) { - for (uint32 x = 0; x < width; x++) { - if (fInverse) - pixel[0] = 255 - row[3]; - else - pixel[0] = row[3]; - pixel++; - row += 4; - } - bits += bytesPerRow; - row = bits; - } - } - - bitmap->ReleaseReference(); - - fCachedBounds = fViewBounds; - fCachedOffset = fViewOffset; - - fBuffer.attach(fCachedBitmap, width, height, width); _AttachMaskToBuffer(); - return &fScanline; -} + if (fPreviousMask != NULL) + fPreviousMask->SetViewOrigin(viewOrigin); - -agg::clipped_alpha_mask* -AlphaMask::Mask() -{ - return &fCachedMask; + return oldOrigin; } ServerBitmap* -AlphaMask::_RenderPicture() const +AlphaMask::_CreateTemporaryBitmap(BRect bounds) const { - UtilityBitmap* bitmap = new(std::nothrow) UtilityBitmap(fViewBounds, + UtilityBitmap* bitmap = new(std::nothrow) UtilityBitmap(bounds, B_RGBA32, 0); if (bitmap == NULL) return NULL; @@ -240,43 +91,272 @@ AlphaMask::_RenderPicture() const return NULL; } - // Clear the bitmap with the transparent color memset(bitmap->Bits(), fBackgroundOpacity, bitmap->BitsLength()); - // Render the picture to the bitmap - BitmapHWInterface interface(bitmap); - DrawingEngine* engine = interface.CreateDrawingEngine(); - if (engine == NULL) { - delete bitmap; - return NULL; - } - - OffscreenCanvas canvas(engine, fDrawState); - canvas.PushState(); - - if (engine->LockParallelAccess()) { - // FIXME ConstrainClippingRegion docs says passing NULL disables - // all clipping. This doesn't work and will crash in Painter. - BRegion clipping; - clipping.Include(fViewBounds); - engine->ConstrainClippingRegion(&clipping); - fPicture->Play(&canvas); - engine->UnlockParallelAccess(); - } - - canvas.PopState(); - delete engine; - return bitmap; } +void +AlphaMask::_Generate() +{ + ServerBitmap* const bitmap = _RenderSource(); + BReference bitmapRef(bitmap, true); + if (bitmap == NULL) { + _SetNoClipping(); + return; + } + + const int32 width = fBounds.IntegerWidth() + 1; + const int32 height = fBounds.IntegerHeight() + 1; + + delete[] fBits; + fBits = new(std::nothrow) uint8[width * height]; + + uint8* source = bitmap->Bits(); + uint8* destination = fBits; + uint32 numPixels = width * height; + + if (fPreviousMask != NULL) { + int32 previousStartX = fBounds.left - fPreviousMask->fBounds.left; + int32 previousStartY = fBounds.top - fPreviousMask->fBounds.top; + if (previousStartX < 0) + previousStartX = 0; + if (previousStartY < 0) + previousStartY = 0; + + for (int32 y = previousStartY; y < previousStartY + height; y++) { + uint8* previousRow = fPreviousMask->fBuffer.row_ptr(y); + for (int32 x = previousStartX; x < previousStartX + width; x++) { + uint8 sourceAlpha = fInverse ? 255 - source[3] : source[3]; + *destination = sourceAlpha * previousRow[x] / 255; + destination++; + source += 4; + } + } + } else { + while (numPixels--) { + *destination = fInverse ? 255 - source[3] : source[3]; + destination++; + source += 4; + } + } + + fBuffer.attach(fBits, width, height, width); + _AttachMaskToBuffer(); +} + + +void +AlphaMask::_SetNoClipping() +{ + fBuffer.attach(NULL, 0, 0, 0); + _AttachMaskToBuffer(); +} + + void AlphaMask::_AttachMaskToBuffer() { uint8 outsideOpacity = fInverse ? 255 - fBackgroundOpacity : fBackgroundOpacity; - fCachedMask.attach(fBuffer, fViewOffset.x + fOrigin.x, - fViewOffset.y + fOrigin.y, outsideOpacity); + AlphaMask* previousMask = fPreviousMask; + while (previousMask != NULL && outsideOpacity != 0) { + uint8 previousOutsideOpacity = previousMask->fInverse + ? 255 - previousMask->fBackgroundOpacity + : previousMask->fBackgroundOpacity; + outsideOpacity = outsideOpacity * previousOutsideOpacity / 255; + previousMask = previousMask->fPreviousMask; + } + + const IntPoint maskOffset = _Offset(); + const int32 offsetX = fBounds.left + maskOffset.x + fViewOrigin.x; + const int32 offsetY = fBounds.top + maskOffset.y + fViewOrigin.y; + + fMask.attach(fBuffer, offsetX, offsetY, outsideOpacity); +} + + +// #pragma mark - UniformAlphaMask + + +UniformAlphaMask::UniformAlphaMask(uint8 opacity) + : + AlphaMask(opacity) +{ + fBounds.Set(0, 0, 0, 0); + _SetNoClipping(); +} + + +ServerBitmap* +UniformAlphaMask::_RenderSource() +{ + return NULL; +} + + +IntPoint +UniformAlphaMask::_Offset() +{ + return IntPoint(0, 0); +} + + +// #pragma mark - VectorAlphaMask + + +template +VectorAlphaMask::VectorAlphaMask(AlphaMask* previousMask, + BPoint where, bool inverse) + : + AlphaMask(previousMask, inverse), + fWhere(where) +{ +} + + +template +ServerBitmap* +VectorAlphaMask::_RenderSource() +{ + fBounds = static_cast(this)->DetermineBoundingBox(); + if (fPreviousMask != NULL) + fBounds = fBounds & fPreviousMask->fBounds; + if (!fBounds.IsValid()) + return NULL; + + ServerBitmap* bitmap = _CreateTemporaryBitmap(fBounds); + if (bitmap == NULL) + return NULL; + + // Render the picture to the bitmap + BitmapHWInterface interface(bitmap); + DrawingEngine* engine = interface.CreateDrawingEngine(); + if (engine == NULL) { + bitmap->ReleaseReference(); + return NULL; + } + engine->SetRendererOffset(fBounds.left, fBounds.top); + + OffscreenCanvas canvas(engine, + static_cast(this)->GetDrawState()); + + DrawState* const drawState = canvas.CurrentState(); + drawState->SetDrawingMode(B_OP_ALPHA); + drawState->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE); + drawState->SetDrawingModeLocked(true); + canvas.PushState(); + + if (engine->LockParallelAccess()) { + BRegion clipping; + clipping.Set((clipping_rect)fBounds); + engine->ConstrainClippingRegion(&clipping); + static_cast(this)->DrawVectors(&canvas); + engine->UnlockParallelAccess(); + } + + delete engine; + + return bitmap; +} + + +template +IntPoint +VectorAlphaMask::_Offset() +{ + return fWhere; +} + + + +// #pragma mark - PictureAlphaMask + + +PictureAlphaMask::PictureAlphaMask(AlphaMask* previousMask, + ServerPicture* picture, const DrawState& drawState, BPoint where, + bool inverse) + : + VectorAlphaMask(previousMask, where, inverse), + fPicture(picture), + fDrawState(new DrawState(drawState)) +{ + _Generate(); +} + + +PictureAlphaMask::~PictureAlphaMask() +{ + delete fDrawState; +} + + +void +PictureAlphaMask::DrawVectors(Canvas* canvas) +{ + fPicture->Play(canvas); +} + + +BRect +PictureAlphaMask::DetermineBoundingBox() const +{ + BRect boundingBox; + PictureBoundingBoxPlayer::Play(fPicture, fDrawState, &boundingBox); + + if (!boundingBox.IsValid()) + return boundingBox; + + // Round up and add an additional 2 pixels on the bottom/right to + // compensate for the various types of rounding used in Painter. + boundingBox.left = floorf(boundingBox.left); + boundingBox.right = ceilf(boundingBox.right) + 2; + boundingBox.top = floorf(boundingBox.top); + boundingBox.bottom = ceilf(boundingBox.bottom) + 2; + + return boundingBox; +} + + +const DrawState& +PictureAlphaMask::GetDrawState() const +{ + return *fDrawState; +} + + +// #pragma mark - ShapeAlphaMask + + +ShapeAlphaMask::ShapeAlphaMask(AlphaMask* previousMask, BPoint where, + bool inverse) + : + VectorAlphaMask(previousMask, where, inverse), + fDrawState() +{ + _Generate(); +} + + +void +ShapeAlphaMask::DrawVectors(Canvas* canvas) +{ + // TODO +} + + +BRect +ShapeAlphaMask::DetermineBoundingBox() const +{ + // TODO + return BRect(0, 0, 0, 0); +} + + +const DrawState& +ShapeAlphaMask::GetDrawState() const +{ + return fDrawState; } diff --git a/src/servers/app/drawing/AlphaMask.h b/src/servers/app/drawing/AlphaMask.h index 81503c0874..4b9d2ffcb3 100644 --- a/src/servers/app/drawing/AlphaMask.h +++ b/src/servers/app/drawing/AlphaMask.h @@ -13,59 +13,123 @@ #include "DrawState.h" #include "drawing/Painter/defines.h" +#include "IntRect.h" +class BShape; class ServerBitmap; class ServerPicture; +// #pragma mark - AlphaMask + + class AlphaMask : public BReferenceable { public: - AlphaMask(ServerPicture* mask, bool inverse, - BPoint origin, const DrawState& drawState); + AlphaMask(AlphaMask* previousMask, + bool inverse); AlphaMask(uint8 backgroundOpacity); - ~AlphaMask(); + virtual ~AlphaMask(); - void Update(BRect bounds, BPoint offset); - BPoint Update(BPoint offset); + IntPoint SetViewOrigin(IntPoint viewOrigin); - void SetPrevious(AlphaMask* mask); + scanline_unpacked_masked_type* Scanline() + { return &fScanline; } - scanline_unpacked_masked_type* Generate(); - agg::clipped_alpha_mask* Mask(); + agg::clipped_alpha_mask* Mask() + { return &fMask; } + +protected: + ServerBitmap* _CreateTemporaryBitmap(BRect bounds) const; + void _Generate(); + void _SetNoClipping(); private: - ServerBitmap* _RenderPicture() const; + virtual ServerBitmap* _RenderSource() = 0; + virtual IntPoint _Offset() = 0; + void _AttachMaskToBuffer(); +public: + BReference fPreviousMask; + IntRect fBounds; private: - AlphaMask* fPreviousMask; - - ServerPicture* fPicture; + IntPoint fViewOrigin; const bool fInverse; - BPoint fOrigin; - // position of this mask, relative to - // either its parent mask, or (if there - // is none) the canvas uint8 fBackgroundOpacity; - DrawState fDrawState; - // draw state used for drawing fPicture - - BRect fViewBounds; - // determines alpha mask size - BPoint fViewOffset; - // position of alpha mask in screen - // coordinates - - uint8* fCachedBitmap; - BRect fCachedBounds; - BPoint fCachedOffset; + uint8* fBits; agg::rendering_buffer fBuffer; - agg::clipped_alpha_mask fCachedMask; + agg::clipped_alpha_mask fMask; scanline_unpacked_masked_type fScanline; }; +class UniformAlphaMask : public AlphaMask { +public: + UniformAlphaMask(uint8 opacity); + +private: + virtual ServerBitmap* _RenderSource(); + virtual IntPoint _Offset(); +}; + + +// #pragma mark - VectorAlphaMask + + +template +class VectorAlphaMask : public AlphaMask { +public: + VectorAlphaMask(AlphaMask* previousMask, + BPoint where, bool inverse); + +private: + virtual ServerBitmap* _RenderSource(); + virtual IntPoint _Offset(); + +protected: + BPoint fWhere; +}; + + +// #pragma mark - PictureAlphaMask + + +class PictureAlphaMask : public VectorAlphaMask { +public: + PictureAlphaMask(AlphaMask* previousMask, + ServerPicture* picture, + const DrawState& drawState, BPoint where, + bool inverse); + virtual ~PictureAlphaMask(); + + void DrawVectors(Canvas* canvas); + BRect DetermineBoundingBox() const; + const DrawState& GetDrawState() const; + +private: + BReference fPicture; + DrawState* fDrawState; +}; + + +// #pragma mark - ShapeAlphaMask + + +class ShapeAlphaMask : public VectorAlphaMask { +public: + ShapeAlphaMask(AlphaMask* previousMask, + BPoint where, bool inverse); + + void DrawVectors(Canvas* canvas); + BRect DetermineBoundingBox() const; + const DrawState& GetDrawState() const; + +private: + DrawState fDrawState; +}; + + #endif // ALPHA_MASK_H diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index c8e83756c2..e382b8dfd4 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -280,6 +280,7 @@ Painter::SetDrawState(const DrawState* state, int32 xOffset, int32 yOffset) // and messed up the state. For other graphics state changes, the // Painter methods are used directly, so this function is much less // speed critical than it used to be. + SetTransform(state->CombinedTransform(), xOffset, yOffset); SetPenSize(state->PenSize()); @@ -289,7 +290,7 @@ Painter::SetDrawState(const DrawState* state, int32 xOffset, int32 yOffset) fSubpixelPrecise = state->SubPixelPrecise(); if (state->GetAlphaMask() != NULL) { - fMaskedUnpackedScanline = state->GetAlphaMask()->Generate(); + fMaskedUnpackedScanline = state->GetAlphaMask()->Scanline(); fClippedAlphaMask = state->GetAlphaMask()->Mask(); } else { fMaskedUnpackedScanline = NULL; From 96f94789c48c03076bb7f350ea1e0ba8a8ebcad0 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Fri, 23 Oct 2015 19:30:31 +0200 Subject: [PATCH 030/370] input_server: fix debug build. --- src/servers/input/BottomlineWindow.cpp | 2 +- src/servers/input/InputServer.cpp | 1 + src/servers/input/MethodReplicant.cpp | 4 ++-- src/servers/input/MouseSettings.cpp | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/servers/input/BottomlineWindow.cpp b/src/servers/input/BottomlineWindow.cpp index aebfb4c982..49dc457c4a 100644 --- a/src/servers/input/BottomlineWindow.cpp +++ b/src/servers/input/BottomlineWindow.cpp @@ -85,7 +85,7 @@ BottomlineWindow::HandleInputMethodEvent(BMessage* event, EventList& newEvents) || event->FindString("be:string", &string) != B_OK) return; - SERIAL_PRINT(("IME : %i, %s\n", opcode, string)); + SERIAL_PRINT(("IME : %" B_PRId32 ", %s\n", opcode, string)); SERIAL_PRINT(("IME : confirmed\n")); int32 length = strlen(string); diff --git a/src/servers/input/InputServer.cpp b/src/servers/input/InputServer.cpp index 2cef3847d2..9ad4c7e431 100644 --- a/src/servers/input/InputServer.cpp +++ b/src/servers/input/InputServer.cpp @@ -10,6 +10,7 @@ #include "MethodReplicant.h" #include +#include #include #include diff --git a/src/servers/input/MethodReplicant.cpp b/src/servers/input/MethodReplicant.cpp index 18823ed67b..601b57aa2c 100644 --- a/src/servers/input/MethodReplicant.cpp +++ b/src/servers/input/MethodReplicant.cpp @@ -131,8 +131,8 @@ MethodReplicant::AttachedToWindow() void MethodReplicant::MessageReceived(BMessage* message) { - PRINT(("%s what:%c%c%c%c\n", __PRETTY_FUNCTION__, message->what >> 24, - message->what >> 16, message->what >> 8, message->what)); + PRINT(("%s what:%c%c%c%c\n", __PRETTY_FUNCTION__, (char)(message->what >> 24), + (char)(message->what >> 16), (char)(message->what >> 8), (char)message->what)); PRINT_OBJECT(*message); switch (message->what) { diff --git a/src/servers/input/MouseSettings.cpp b/src/servers/input/MouseSettings.cpp index df81cd3cd3..dca38b7f59 100644 --- a/src/servers/input/MouseSettings.cpp +++ b/src/servers/input/MouseSettings.cpp @@ -146,7 +146,7 @@ MouseSettings::Dump() printf("mouse mode:\t%s\n", mode); char *focus_follows_mouse_mode = "unknown"; - switch (fMode) { + switch (fFocusFollowsMouseMode) { case B_NORMAL_FOCUS_FOLLOWS_MOUSE: focus_follows_mouse_mode = "normal"; break; From 7c088080ec1495bd1562c116660b40a651873c75 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Sun, 25 Oct 2015 10:13:04 +0100 Subject: [PATCH 031/370] Split the big userguide package into one per language. Splitting the almost 70 MiB userguide package into one package per language at ~4.5 MiB saves time and space when installing/updating. At the online tool that manages the user guide pages, we have to make changes to fall back to the online page if you try to switch to a language you haven't installed locally. See #9322. --- build/jam/OptionalPackages | 35 ++- build/jam/packages/HaikuUserguide | 255 +++++++++++++++++- build/jam/repositories/Haiku | 18 +- src/data/package_infos/any/haiku_userguide_ca | 18 ++ src/data/package_infos/any/haiku_userguide_de | 18 ++ src/data/package_infos/any/haiku_userguide_en | 18 ++ src/data/package_infos/any/haiku_userguide_es | 18 ++ src/data/package_infos/any/haiku_userguide_fi | 18 ++ src/data/package_infos/any/haiku_userguide_fr | 18 ++ src/data/package_infos/any/haiku_userguide_hu | 18 ++ src/data/package_infos/any/haiku_userguide_it | 18 ++ src/data/package_infos/any/haiku_userguide_jp | 18 ++ src/data/package_infos/any/haiku_userguide_pl | 18 ++ .../package_infos/any/haiku_userguide_pt_BR | 18 ++ .../package_infos/any/haiku_userguide_pt_PT | 18 ++ src/data/package_infos/any/haiku_userguide_ru | 18 ++ src/data/package_infos/any/haiku_userguide_sk | 18 ++ .../package_infos/any/haiku_userguide_sv_SE | 18 ++ src/data/package_infos/any/haiku_userguide_uk | 18 ++ .../package_infos/any/haiku_userguide_zh_CN | 18 ++ 20 files changed, 607 insertions(+), 7 deletions(-) create mode 100644 src/data/package_infos/any/haiku_userguide_ca create mode 100644 src/data/package_infos/any/haiku_userguide_de create mode 100644 src/data/package_infos/any/haiku_userguide_en create mode 100644 src/data/package_infos/any/haiku_userguide_es create mode 100644 src/data/package_infos/any/haiku_userguide_fi create mode 100644 src/data/package_infos/any/haiku_userguide_fr create mode 100644 src/data/package_infos/any/haiku_userguide_hu create mode 100644 src/data/package_infos/any/haiku_userguide_it create mode 100644 src/data/package_infos/any/haiku_userguide_jp create mode 100644 src/data/package_infos/any/haiku_userguide_pl create mode 100644 src/data/package_infos/any/haiku_userguide_pt_BR create mode 100644 src/data/package_infos/any/haiku_userguide_pt_PT create mode 100644 src/data/package_infos/any/haiku_userguide_ru create mode 100644 src/data/package_infos/any/haiku_userguide_sk create mode 100644 src/data/package_infos/any/haiku_userguide_sv_SE create mode 100644 src/data/package_infos/any/haiku_userguide_uk create mode 100644 src/data/package_infos/any/haiku_userguide_zh_CN diff --git a/build/jam/OptionalPackages b/build/jam/OptionalPackages index 774268b79c..6a6971058a 100644 --- a/build/jam/OptionalPackages +++ b/build/jam/OptionalPackages @@ -206,8 +206,41 @@ if [ IsOptionalHaikuImagePackageAdded WebPositive ] { # Welcome if [ IsOptionalHaikuImagePackageAdded Welcome ] { - AddPackageFilesToHaikuImage system : haiku_userguide.hpkg + AddPackageFilesToHaikuImage system : haiku_userguide_ca.hpkg : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_de.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_en.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_es.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_fi.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_fr.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_hu.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_it.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_jp.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_pl.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_pt_BR.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_pt_PT.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_ru.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_sk.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_sv_SE.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_uk.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_userguide_zh_CN.hpkg + : nameFromMetaInfo ; + AddPackageFilesToHaikuImage system : haiku_welcome.hpkg : nameFromMetaInfo ; AddSymlinkToHaikuImage home Desktop : /boot/system/bin/welcome diff --git a/build/jam/packages/HaikuUserguide b/build/jam/packages/HaikuUserguide index 00ca0da9e9..c42519abec 100644 --- a/build/jam/packages/HaikuUserguide +++ b/build/jam/packages/HaikuUserguide @@ -1,9 +1,254 @@ -local haikuUserGuidePackage = haiku_userguide.hpkg ; -HaikuPackage $(haikuUserGuidePackage) ; +# CA +local haikuUserGuidePackageCA = haiku_userguide_ca.hpkg ; +HaikuPackage $(haikuUserGuidePackageCA) ; -CopyDirectoryToPackage documentation : [ FDirName $(HAIKU_TOP) docs userguide ] - : userguide ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide ca ] + : ca ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; AddFilesToPackage bin : userguide ; -BuildHaikuPackage $(haikuUserGuidePackage) : haiku_userguide ; +BuildHaikuPackage $(haikuUserGuidePackageCA) : haiku_userguide_ca ; + +# DE +local haikuUserGuidePackageDE = haiku_userguide_de.hpkg ; +HaikuPackage $(haikuUserGuidePackageDE) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide de ] + : ca ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackageDE) : haiku_userguide_de ; + +# EN +local haikuUserGuidePackageEN = haiku_userguide_en.hpkg ; +HaikuPackage $(haikuUserGuidePackageEN) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide en ] + : en ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackageEN) : haiku_userguide_en ; + +# ES +local haikuUserGuidePackageES = haiku_userguide_es.hpkg ; +HaikuPackage $(haikuUserGuidePackageES) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide es ] + : es ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackageES) : haiku_userguide_es ; + +# FI +local haikuUserGuidePackageFI = haiku_userguide_fi.hpkg ; +HaikuPackage $(haikuUserGuidePackageFI) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide fi ] + : fi ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackageFI) : haiku_userguide_fi ; + +# FR +local haikuUserGuidePackageFR = haiku_userguide_fr.hpkg ; +HaikuPackage $(haikuUserGuidePackageFR) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide fr ] + : fr ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackageFR) : haiku_userguide_fr ; + +# HU +local haikuUserGuidePackageHU = haiku_userguide_hu.hpkg ; +HaikuPackage $(haikuUserGuidePackageHU) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide hu ] + : hu ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackageHU) : haiku_userguide_hu ; + +# IT +local haikuUserGuidePackageIT = haiku_userguide_it.hpkg ; +HaikuPackage $(haikuUserGuidePackageIT) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide it ] + : it ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackageIT) : haiku_userguide_it ; + +# JP +local haikuUserGuidePackageJP = haiku_userguide_jp.hpkg ; +HaikuPackage $(haikuUserGuidePackageJP) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide jp ] + : jp ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackageJP) : haiku_userguide_jp ; + +# PL +local haikuUserGuidePackagePL = haiku_userguide_pl.hpkg ; +HaikuPackage $(haikuUserGuidePackagePL) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide pl ] + : pl ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackagePL) : haiku_userguide_pl ; + +# PT_BR +local haikuUserGuidePackagePT_BR = haiku_userguide_pt_BR.hpkg ; +HaikuPackage $(haikuUserGuidePackagePT_BR) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide pt_BR ] + : pt_BR ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackagePT_BR) : haiku_userguide_pt_BR ; + +# PT_PT +local haikuUserGuidePackagePT_PT = haiku_userguide_pt_PT.hpkg ; +HaikuPackage $(haikuUserGuidePackagePT_PT) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide pt_PT ] + : pt_PT ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackagePT_PT) : haiku_userguide_pt_PT ; + +# RU +local haikuUserGuidePackageRU = haiku_userguide_ru.hpkg ; +HaikuPackage $(haikuUserGuidePackageRU) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide ru ] + : ru ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackageRU) : haiku_userguide_ru ; + +# SK +local haikuUserGuidePackageSK = haiku_userguide_sk.hpkg ; +HaikuPackage $(haikuUserGuidePackageSK) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide sk ] + : sk ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackageSK) : haiku_userguide_sk ; + +# SV_SE +local haikuUserGuidePackageSV_SE = haiku_userguide_sv_SE.hpkg ; +HaikuPackage $(haikuUserGuidePackageSV_SE) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide sv_SE ] + : sv_SE ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackageSV_SE) : haiku_userguide_sv_SE ; + +# UK +local haikuUserGuidePackageUK = haiku_userguide_uk.hpkg ; +HaikuPackage $(haikuUserGuidePackageUK) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide uk ] + : uk ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackageUK) : haiku_userguide_uk ; + +# ZH_CN +local haikuUserGuidePackageZH_CN = haiku_userguide_zh_CN.hpkg ; +HaikuPackage $(haikuUserGuidePackageZH_CN) ; + +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide zh_CN ] + : zh_CN ; +CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] + : images ; +AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] + : Haiku-doc.css ; +SEARCH on userguide = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToPackage bin : userguide ; + +BuildHaikuPackage $(haikuUserGuidePackageZH_CN) : haiku_userguide_zh_CN ; diff --git a/build/jam/repositories/Haiku b/build/jam/repositories/Haiku index ae30e3b4c3..14f5ebeaf7 100644 --- a/build/jam/repositories/Haiku +++ b/build/jam/repositories/Haiku @@ -12,7 +12,23 @@ local packages = [ FFilterByBuildFeatures haiku haiku_devel haiku_loader - haiku_userguide + haiku_userguide_ca + haiku_userguide_de + haiku_userguide_en + haiku_userguide_es + haiku_userguide_fi + haiku_userguide_fr + haiku_userguide_hu + haiku_userguide_it + haiku_userguide_jp + haiku_userguide_pl + haiku_userguide_pt_BR + haiku_userguide_pt_PT + haiku_userguide_ru + haiku_userguide_sk + haiku_userguide_sv_SE + haiku_userguide_uk + haiku_userguide_zh_CN haiku_welcome makefile_engine netfs@!x86_64 diff --git a/src/data/package_infos/any/haiku_userguide_ca b/src/data/package_infos/any/haiku_userguide_ca new file mode 100644 index 0000000000..6d6e4f9462 --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_ca @@ -0,0 +1,18 @@ +name haiku_userguide_ca +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_ca=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_de b/src/data/package_infos/any/haiku_userguide_de new file mode 100644 index 0000000000..021dbe3e32 --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_de @@ -0,0 +1,18 @@ +name haiku_userguide_de +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_de=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_en b/src/data/package_infos/any/haiku_userguide_en new file mode 100644 index 0000000000..f81095dc4b --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_en @@ -0,0 +1,18 @@ +name haiku_userguide_en +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_en=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_es b/src/data/package_infos/any/haiku_userguide_es new file mode 100644 index 0000000000..ef4b6fb90c --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_es @@ -0,0 +1,18 @@ +name haiku_userguide_es +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_es=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_fi b/src/data/package_infos/any/haiku_userguide_fi new file mode 100644 index 0000000000..05ddb61c78 --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_fi @@ -0,0 +1,18 @@ +name haiku_userguide_fi +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_fi=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_fr b/src/data/package_infos/any/haiku_userguide_fr new file mode 100644 index 0000000000..b88ca68705 --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_fr @@ -0,0 +1,18 @@ +name haiku_userguide_fr +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_fr=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_hu b/src/data/package_infos/any/haiku_userguide_hu new file mode 100644 index 0000000000..e7c3700d93 --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_hu @@ -0,0 +1,18 @@ +name haiku_userguide_hu +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_hu=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_it b/src/data/package_infos/any/haiku_userguide_it new file mode 100644 index 0000000000..650467823a --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_it @@ -0,0 +1,18 @@ +name haiku_userguide_it +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_it=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_jp b/src/data/package_infos/any/haiku_userguide_jp new file mode 100644 index 0000000000..a70ecc8f9d --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_jp @@ -0,0 +1,18 @@ +name haiku_userguide_jp +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_jp=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_pl b/src/data/package_infos/any/haiku_userguide_pl new file mode 100644 index 0000000000..5086158c9e --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_pl @@ -0,0 +1,18 @@ +name haiku_userguide_pl +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_pl=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_pt_BR b/src/data/package_infos/any/haiku_userguide_pt_BR new file mode 100644 index 0000000000..c3a1aad8b4 --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_pt_BR @@ -0,0 +1,18 @@ +name haiku_userguide_pt_BR +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_pt_BR=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_pt_PT b/src/data/package_infos/any/haiku_userguide_pt_PT new file mode 100644 index 0000000000..b0d0f13728 --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_pt_PT @@ -0,0 +1,18 @@ +name haiku_userguide_pt_PT +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_pt_PT=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_ru b/src/data/package_infos/any/haiku_userguide_ru new file mode 100644 index 0000000000..0b44558b9b --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_ru @@ -0,0 +1,18 @@ +name haiku_userguide_ru +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_ru=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_sk b/src/data/package_infos/any/haiku_userguide_sk new file mode 100644 index 0000000000..c46e25c48d --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_sk @@ -0,0 +1,18 @@ +name haiku_userguide_sk +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_sk=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_sv_SE b/src/data/package_infos/any/haiku_userguide_sv_SE new file mode 100644 index 0000000000..dab24a286b --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_sv_SE @@ -0,0 +1,18 @@ +name haiku_userguide_sv_SE +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_sv_SE=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_uk b/src/data/package_infos/any/haiku_userguide_uk new file mode 100644 index 0000000000..47a4d1b0a0 --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_uk @@ -0,0 +1,18 @@ +name haiku_userguide_uk +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_uk=%HAIKU_VERSION% +} + +requires { +} diff --git a/src/data/package_infos/any/haiku_userguide_zh_CN b/src/data/package_infos/any/haiku_userguide_zh_CN new file mode 100644 index 0000000000..afccdbd7b0 --- /dev/null +++ b/src/data/package_infos/any/haiku_userguide_zh_CN @@ -0,0 +1,18 @@ +name haiku_userguide_zh_CN +version %HAIKU_VERSION% +architecture any +summary "The Haiku user documentation" +description "The Haiku user documentation." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2015 Haiku, Inc. et al" +licenses MIT + +provides { + haiku_userguide_zh_CN=%HAIKU_VERSION% +} + +requires { +} From 0507a7886af913546b890b38eebb39b298a5161a Mon Sep 17 00:00:00 2001 From: Humdinger Date: Sun, 25 Oct 2015 10:34:52 +0100 Subject: [PATCH 032/370] Improved LoaderPages for Web+ Solves #9322. Thanks to dsjonny for the original work, that I slightly improved upon. The Userguide and Welcome pages now load the page of the user's system language. --- build/jam/OptionalPackages | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/jam/OptionalPackages b/build/jam/OptionalPackages index 6a6971058a..b9cae13301 100644 --- a/build/jam/OptionalPackages +++ b/build/jam/OptionalPackages @@ -195,7 +195,7 @@ if [ IsOptionalHaikuImagePackageAdded WebPositive ] { AddPackageFilesToHaikuImage system : webpositive.hpkg : nameFromMetaInfo ; InstallOptionalHaikuImagePackage - $(baseURL)/WebPositiveBookmarks-2015-09-05.zip + $(baseURL)/WebPositiveBookmarks-2015-10-25.zip : home config settings WebPositive ; break ; } From 2e17b6504f199aa8954500b731cb7be9a0952279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 21 Oct 2015 21:17:41 +0200 Subject: [PATCH 033/370] BLaunchRoster::ResetStickyEvent() added. * Used to unflag sticky events that already have been triggered once. --- docs/user/app/LaunchRoster.dox | 19 +++++++++++++ headers/private/app/LaunchDaemonDefs.h | 1 + headers/private/app/LaunchRoster.h | 2 ++ src/kits/app/LaunchRoster.cpp | 7 +++++ src/servers/launch/Events.cpp | 37 +++++++++++++++++++++++--- src/servers/launch/Events.h | 2 ++ src/servers/launch/LaunchDaemon.cpp | 35 +++++++++++++++++++++++- 7 files changed, 99 insertions(+), 4 deletions(-) diff --git a/docs/user/app/LaunchRoster.dox b/docs/user/app/LaunchRoster.dox index 0eaf43864f..28dc7a3c2d 100644 --- a/docs/user/app/LaunchRoster.dox +++ b/docs/user/app/LaunchRoster.dox @@ -257,4 +257,23 @@ on { */ +/*! + \fn status_t BLaunchRoster::ResetStickyEvent(const BMessenger& source, + const char* name); + \brief Resets a previously triggered sticky event. + + When an event triggered that is marked as \c B_STICKY_EVENT, its status + will be reset when you call this method for it. + + You must have previously registered the event, in order to make the + launch_daemon do anything. Unknown event notifications will be ignored. + + \param source The messenger the event is coming from. + \param name The name of the event. + \return B_OK if the event could be reset, otherwise an error code. + + \since Haiku R1 +*/ + + //! @} diff --git a/headers/private/app/LaunchDaemonDefs.h b/headers/private/app/LaunchDaemonDefs.h index 9842f850f8..f0452847c5 100644 --- a/headers/private/app/LaunchDaemonDefs.h +++ b/headers/private/app/LaunchDaemonDefs.h @@ -31,6 +31,7 @@ enum { B_REGISTER_LAUNCH_EVENT = 'lnre', B_UNREGISTER_LAUNCH_EVENT = 'lnue', B_NOTIFY_LAUNCH_EVENT = 'lnne', + B_RESET_STICKY_LAUNCH_EVENT = 'lnRe', }; diff --git a/headers/private/app/LaunchRoster.h b/headers/private/app/LaunchRoster.h index 32e05e89e3..970b3120aa 100644 --- a/headers/private/app/LaunchRoster.h +++ b/headers/private/app/LaunchRoster.h @@ -42,6 +42,8 @@ public: const char* name); status_t NotifyEvent(const BMessenger& source, const char* name); + status_t ResetStickyEvent(const BMessenger& source, + const char* name); class Private; diff --git a/src/kits/app/LaunchRoster.cpp b/src/kits/app/LaunchRoster.cpp index dee7401322..eec0128555 100644 --- a/src/kits/app/LaunchRoster.cpp +++ b/src/kits/app/LaunchRoster.cpp @@ -227,6 +227,13 @@ BLaunchRoster::NotifyEvent(const BMessenger& source, const char* name) } +status_t +BLaunchRoster::ResetStickyEvent(const BMessenger& source, const char* name) +{ + return _UpdateEvent(B_RESET_STICKY_LAUNCH_EVENT, source, name); +} + + void BLaunchRoster::_InitMessenger() { diff --git a/src/servers/launch/Events.cpp b/src/servers/launch/Events.cpp index b25fc4bef2..e623aa4fc6 100644 --- a/src/servers/launch/Events.cpp +++ b/src/servers/launch/Events.cpp @@ -86,6 +86,7 @@ public: const BString& Name() const; bool Resolve(uint32 flags); + void ResetSticky(); virtual void ResetTrigger(); virtual status_t Register(EventRegistrator& registrator); @@ -457,12 +458,18 @@ ExternalEvent::Resolve(uint32 flags) void -ExternalEvent::ResetTrigger() +ExternalEvent::ResetSticky() { if ((fFlags & B_STICKY_EVENT) != 0) - return; + Event::ResetTrigger(); +} - Event::ResetTrigger(); + +void +ExternalEvent::ResetTrigger() +{ + if ((fFlags & B_STICKY_EVENT) == 0) + Event::ResetTrigger(); } @@ -642,6 +649,30 @@ Events::TriggerExternalEvent(Event* event, const char* name) } +/*static*/ void +Events::ResetStickyExternalEvent(Event* event, const char* name) +{ + if (event == NULL) + return; + + if (EventContainer* container = dynamic_cast(event)) { + for (int32 index = 0; index < container->Events().CountItems(); + index++) { + Event* event = container->Events().ItemAt(index); + if (ExternalEvent* external = dynamic_cast(event)) { + if (external->Name() == name) { + external->ResetSticky(); + return; + } + } else if (dynamic_cast(event) != NULL) { + ResetStickyExternalEvent(event, name); + } + } + } + return; +} + + /*! This will trigger a demand event, if it exists. \return \c true, if there is a demand event, and it has been diff --git a/src/servers/launch/Events.h b/src/servers/launch/Events.h index d827182a00..46059754b8 100644 --- a/src/servers/launch/Events.h +++ b/src/servers/launch/Events.h @@ -60,6 +60,8 @@ public: const char* name, uint32 flags); static void TriggerExternalEvent(Event* event, const char* name); + static void ResetStickyExternalEvent(Event* event, + const char* name); static bool TriggerDemand(Event* event); }; diff --git a/src/servers/launch/LaunchDaemon.cpp b/src/servers/launch/LaunchDaemon.cpp index 69e925838b..71f46189d7 100644 --- a/src/servers/launch/LaunchDaemon.cpp +++ b/src/servers/launch/LaunchDaemon.cpp @@ -144,7 +144,8 @@ private: void _HandleRegisterLaunchEvent(BMessage* message); void _HandleUnregisterLaunchEvent(BMessage* message); void _HandleNotifyLaunchEvent(BMessage* message); - + void _HandleResetStickyLaunchEvent( + BMessage* message); uid_t _GetUserID(BMessage* message); void _ReadPaths(const BStringList& paths); @@ -463,6 +464,10 @@ LaunchDaemon::MessageReceived(BMessage* message) _HandleNotifyLaunchEvent(message); break; + case B_RESET_STICKY_LAUNCH_EVENT: + _HandleResetStickyLaunchEvent(message); + break; + case kMsgEventTriggered: { // An internal event has been triggered. @@ -762,6 +767,34 @@ LaunchDaemon::_HandleNotifyLaunchEvent(BMessage* message) } +void +LaunchDaemon::_HandleResetStickyLaunchEvent(BMessage* message) +{ + uid_t user = _GetUserID(message); + if (user < 0) + return; + + if (user == 0 || fUserMode) { + // Reset sticky events + const char* name = message->GetString("name"); + const char* ownerName = message->GetString("owner"); + // TODO: support arguments (as selectors) + + ExternalEventSource* event = _FindEvent(ownerName, name); + if (event != NULL) { + // Evaluate all of its jobs + int32 count = event->CountListeners(); + for (int32 index = 0; index < count; index++) { + BaseJob* listener = event->ListenerAt(index); + Events::ResetStickyExternalEvent(listener->Event(), name); + } + } + } + + _ForwardEventMessage(user, message); +} + + uid_t LaunchDaemon::_GetUserID(BMessage* message) { From 5f2abaf7df37f5e2e6cab5dffeed209e89759e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 25 Oct 2015 14:22:00 +0200 Subject: [PATCH 034/370] launch_daemon: Added network_available event & condition. * Not yet tested. --- src/servers/launch/Conditions.cpp | 36 ++++++ src/servers/launch/Events.cpp | 99 ++++++++++++++++ src/servers/launch/Jamfile | 3 +- src/servers/launch/NetworkWatcher.cpp | 165 ++++++++++++++++++++++++++ src/servers/launch/NetworkWatcher.h | 47 ++++++++ 5 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 src/servers/launch/NetworkWatcher.cpp create mode 100644 src/servers/launch/NetworkWatcher.h diff --git a/src/servers/launch/Conditions.cpp b/src/servers/launch/Conditions.cpp index 0231112876..66816197ca 100644 --- a/src/servers/launch/Conditions.cpp +++ b/src/servers/launch/Conditions.cpp @@ -13,6 +13,7 @@ #include #include +#include "NetworkWatcher.h" #include "Utility.h" @@ -102,6 +103,15 @@ private: }; +class NetworkAvailableCondition : public Condition { +public: + virtual bool Test(ConditionContext& context) const; + virtual bool IsConstant(ConditionContext& context) const; + + virtual BString ToString() const; +}; + + static Condition* create_condition(const char* name, const BMessage& args) { @@ -118,6 +128,8 @@ create_condition(const char* name, const BMessage& args) return new ReadOnlyCondition(args); if (strcmp(name, "file_exists") == 0) return new FileExistsCondition(args); + if (strcmp(name, "network_available") == 0) + return new NetworkAvailableCondition(); return NULL; } @@ -445,6 +457,30 @@ FileExistsCondition::ToString() const } +// #pragma mark - network_available + + +bool +NetworkAvailableCondition::Test(ConditionContext& context) const +{ + return NetworkWatcher::NetworkAvailable(false); +} + + +bool +NetworkAvailableCondition::IsConstant(ConditionContext& context) const +{ + return false; +} + + +BString +NetworkAvailableCondition::ToString() const +{ + return "network_available"; +} + + // #pragma mark - diff --git a/src/servers/launch/Events.cpp b/src/servers/launch/Events.cpp index e623aa4fc6..400fb3566b 100644 --- a/src/servers/launch/Events.cpp +++ b/src/servers/launch/Events.cpp @@ -17,6 +17,7 @@ #include "BaseJob.h" #include "LaunchDaemon.h" +#include "NetworkWatcher.h" #include "Utility.h" #include "VolumeWatcher.h" @@ -67,6 +68,16 @@ public: }; +class StickyEvent : public Event { +public: + StickyEvent(Event* parent); + virtual ~StickyEvent(); + + virtual void ResetSticky(); + virtual void ResetTrigger(); +}; + + class DemandEvent : public Event { public: DemandEvent(Event* parent); @@ -132,6 +143,20 @@ public: }; +class NetworkAvailableEvent : public StickyEvent, public NetworkListener { +public: + NetworkAvailableEvent(Event* parent, + const BMessage& args); + + virtual status_t Register(EventRegistrator& registrator); + virtual void Unregister(EventRegistrator& registrator); + + virtual BString ToString() const; + + virtual void NetworkAvailabilityChanged(bool available); +}; + + static Event* create_event(Event* parent, const char* name, const BMessenger* target, const BMessage& args) @@ -149,6 +174,8 @@ create_event(Event* parent, const char* name, const BMessenger* target, return new FileCreatedEvent(parent, args); if (strcmp(name, "volume_mounted") == 0) return new VolumeMountedEvent(parent, args); + if (strcmp(name, "network_available") == 0) + return new NetworkAvailableEvent(parent, args); return new ExternalEvent(parent, name, args); } @@ -389,6 +416,35 @@ OrEvent::ToString() const } +// #pragma mark - StickyEvent + + +StickyEvent::StickyEvent(Event* parent) + : + Event(parent) +{ +} + + +StickyEvent::~StickyEvent() +{ +} + + +void +StickyEvent::ResetSticky() +{ + Event::ResetTrigger(); +} + + +void +StickyEvent::ResetTrigger() +{ + // This is a sticky event; we don't reset the trigger here +} + + // #pragma mark - demand @@ -576,6 +632,49 @@ VolumeMountedEvent::VolumeUnmounted(dev_t device) // #pragma mark - +NetworkAvailableEvent::NetworkAvailableEvent(Event* parent, + const BMessage& args) + : + StickyEvent(parent) +{ +} + + +status_t +NetworkAvailableEvent::Register(EventRegistrator& registrator) +{ + NetworkWatcher::Register(this); + return B_OK; +} + + +void +NetworkAvailableEvent::Unregister(EventRegistrator& registrator) +{ + NetworkWatcher::Unregister(this); +} + + +BString +NetworkAvailableEvent::ToString() const +{ + return "network_available"; +} + + +void +NetworkAvailableEvent::NetworkAvailabilityChanged(bool available) +{ + if (available) + Trigger(); + else + ResetSticky(); +} + + +// #pragma mark - + + /*static*/ Event* Events::FromMessage(const BMessenger& target, const BMessage& message) { diff --git a/src/servers/launch/Jamfile b/src/servers/launch/Jamfile index e7e219894d..a6e7a3d57f 100644 --- a/src/servers/launch/Jamfile +++ b/src/servers/launch/Jamfile @@ -13,6 +13,7 @@ Server launch_daemon Conditions.cpp Events.cpp Job.cpp + NetworkWatcher.cpp SettingsParser.cpp Target.cpp Utility.cpp @@ -25,7 +26,7 @@ Server launch_daemon InitSharedMemoryDirectoryJob.cpp InitTemporaryDirectoryJob.cpp : - be libshared.a libmultiuser_utils.a [ TargetLibstdc++ ] + be network bnetapi libshared.a libmultiuser_utils.a [ TargetLibstdc++ ] : LaunchDaemon.rdef ; diff --git a/src/servers/launch/NetworkWatcher.cpp b/src/servers/launch/NetworkWatcher.cpp new file mode 100644 index 0000000000..442ef02a98 --- /dev/null +++ b/src/servers/launch/NetworkWatcher.cpp @@ -0,0 +1,165 @@ +/* + * Copyright 2015, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ + + +//! The backbone of the NetworkAvailable event, and condition. + + +#include "NetworkWatcher.h" + +#include +#include +#include +#include +#include + +#include "Utility.h" + + +static const bigtime_t kNetworkUpdateInterval = 1000000; + // Update network availability every second + +static BLocker sLocker("network watcher"); +static NetworkWatcher* sWatcher; + +static bool sLastNetworkAvailable; +static bigtime_t sLastNetworkUpdate; + + +NetworkListener::~NetworkListener() +{ +} + + +// #pragma mark - + + +NetworkWatcher::NetworkWatcher() + : + BHandler("network watcher"), + fAvailable(false) +{ + if (be_app->Lock()) { + be_app->AddHandler(this); + + start_watching_network(B_WATCH_NETWORK_INTERFACE_CHANGES + | B_WATCH_NETWORK_LINK_CHANGES, this); + be_app->Unlock(); + } +} + + +NetworkWatcher::~NetworkWatcher() +{ + if (be_app->Lock()) { + stop_watching_network(this); + + be_app->RemoveHandler(this); + be_app->Unlock(); + } +} + + +void +NetworkWatcher::AddListener(NetworkListener* listener) +{ + BAutolock lock(sLocker); + fListeners.AddItem(listener); + + if (fListeners.CountItems() == 1) + UpdateAvailability(); +} + + +void +NetworkWatcher::RemoveListener(NetworkListener* listener) +{ + BAutolock lock(sLocker); + fListeners.RemoveItem(listener); +} + + +int32 +NetworkWatcher::CountListeners() const +{ + BAutolock lock(sLocker); + return fListeners.CountItems(); +} + + +void +NetworkWatcher::MessageReceived(BMessage* message) +{ + switch (message->what) { + case B_NETWORK_MONITOR: + UpdateAvailability(); + break; + } +} + + +/*static*/ void +NetworkWatcher::Register(NetworkListener* listener) +{ + BAutolock lock(sLocker); + if (sWatcher == NULL) + sWatcher = new NetworkWatcher(); + + sWatcher->AddListener(listener); +} + + +/*static*/ void +NetworkWatcher::Unregister(NetworkListener* listener) +{ + BAutolock lock(sLocker); + sWatcher->RemoveListener(listener); + + if (sWatcher->CountListeners() == 0) + delete sWatcher; +} + + +/*static*/ bool +NetworkWatcher::NetworkAvailable(bool immediate) +{ + if (!immediate + && system_time() - sLastNetworkUpdate < kNetworkUpdateInterval) { + return sLastNetworkAvailable; + } + + bool isAvailable = false; + + BNetworkRoster& roster = BNetworkRoster::Default(); + BNetworkInterface interface; + uint32 cookie = 0; + while (roster.GetNextInterface(&cookie, interface) == B_OK) { + uint32 flags = interface.Flags(); + if ((flags & (IFF_LOOPBACK | IFF_CONFIGURING | IFF_UP | IFF_LINK)) + == (IFF_UP | IFF_LINK)) { + isAvailable = true; + break; + } + } + + sLastNetworkAvailable = isAvailable; + sLastNetworkUpdate = system_time(); + return isAvailable; +} + + +void +NetworkWatcher::UpdateAvailability() +{ + bool isAvailable = NetworkAvailable(true); + if (isAvailable != fAvailable) { + fAvailable = isAvailable; + + BAutolock lock(sLocker); + for (int32 i = 0; i < fListeners.CountItems(); i++) { + fListeners.ItemAt(i)->NetworkAvailabilityChanged(fAvailable); + } + } +} diff --git a/src/servers/launch/NetworkWatcher.h b/src/servers/launch/NetworkWatcher.h new file mode 100644 index 0000000000..e2a6ff66cf --- /dev/null +++ b/src/servers/launch/NetworkWatcher.h @@ -0,0 +1,47 @@ +/* + * Copyright 2015, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ +#ifndef NETWORK_WATCHER_H +#define NETWORK_WATCHER_H + + +#include +#include + + +class NetworkListener { +public: + virtual ~NetworkListener(); + + virtual void NetworkAvailabilityChanged(bool available) = 0; +}; + + +class NetworkWatcher : public BHandler { +public: + NetworkWatcher(); + virtual ~NetworkWatcher(); + + void AddListener(NetworkListener* listener); + void RemoveListener(NetworkListener* listener); + int32 CountListeners() const; + + virtual void MessageReceived(BMessage* message); + + static void Register(NetworkListener* listener); + static void Unregister(NetworkListener* listener); + + static bool NetworkAvailable(bool immediate); + +protected: + void UpdateAvailability(); + +protected: + BObjectList + fListeners; + bool fAvailable; +}; + + +#endif // NETWORK_WATCHER_H From 2a76d1c95a3a2100d240d65f4345dcec27ace253 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 25 Oct 2015 14:33:05 +0000 Subject: [PATCH 035/370] Add package for Unknown Horizons and dependencies for x86[_64]. While the game is pure python and packaged for any architecture, the engine (FIFE) is C++ with python binding via swig, making the game only installable on x86 and x86_64. We'd need to provide a python_x86 to support secondary architecture python modules. --- build/jam/repositories/HaikuPorts/x86 | 16 ++++++++++++++++ build/jam/repositories/HaikuPorts/x86_64 | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/build/jam/repositories/HaikuPorts/x86 b/build/jam/repositories/HaikuPorts/x86 index 0ff9a23654..69cc67b807 100644 --- a/build/jam/repositories/HaikuPorts/x86 +++ b/build/jam/repositories/HaikuPorts/x86 @@ -10,6 +10,7 @@ RemotePackageRepository HaikuPorts dejavu-2.34-1 texi2html-1.82-2 timgmsoundfont-fixed-5 + unknown_horizons-2014.1-1 vl_gothic-20141206-1 wqy_microhei-0.2.0~beta-3 : @@ -71,6 +72,7 @@ RemotePackageRepository HaikuPorts curl_devel-7.44.0-1 cvs-1.12.13.1-6 cvsps-2.2b1-1 + cython-0.23.4-1 dbus-1.8.6-1 dbus_devel-1.8.6-1 diffutils-3.3-2 @@ -79,6 +81,9 @@ RemotePackageRepository HaikuPorts dtc-1.4.1-1 expat-2.1.0-1 expat_devel-2.1.0-1 + fife-0.4.0~20150801-1 + fifechan-0.1.2-1 + fifechan_devel-0.1.2-1 file-5.15-1 file_devel-5.15-1 findutils-4.4.2-3 @@ -230,6 +235,8 @@ RemotePackageRepository HaikuPorts neon_devel-0.29.6-7 netcat-1.10-1 ninja-1.5.1-2 + openal-1.13.0-2 + openal_devel-1.13.0-2 openjdk-1.7_2013_11_08-2 openssh-6.9p1-1 # sync openssl with secondary architecture (x86_gcc2) @@ -241,11 +248,13 @@ RemotePackageRepository HaikuPorts perl-5.18.2-2 pixman-0.32.6-1 pkgconfig-0.27.1-2 + pyenet-20141025-1 python-2.7.10-1 python_mako-1.0.1-1 python_setuptools-5.3-2 python_twisted-13.2.0-1 python_zope.interface-4.1.1-2 + pyyaml-3.11-1 qca2-2.0.3-1 qca2_devel-2.0.3-1 qemu-2.1.2-1 @@ -412,12 +421,15 @@ RemotePackageRepository HaikuPorts curl cvs cvsps + cython dbus diffutils dos2unix doxygen dtc expat + fife + fifechan file findutils ffmpeg @@ -501,6 +513,7 @@ RemotePackageRepository HaikuPorts ncurses6 neon netcat + openal openssh openssl p7zip @@ -510,11 +523,13 @@ RemotePackageRepository HaikuPorts pixman pkgconfig pkgconfig_x86_gcc2 + pyenet python python_mako python_setuptools python_twisted python_zope.interface + pyyaml qca2 qemu qrencode @@ -541,6 +556,7 @@ RemotePackageRepository HaikuPorts tiff4 tinyxml transmission + unknown_horizons unrar unzip vim diff --git a/build/jam/repositories/HaikuPorts/x86_64 b/build/jam/repositories/HaikuPorts/x86_64 index b8795169c9..5668c1a7a5 100644 --- a/build/jam/repositories/HaikuPorts/x86_64 +++ b/build/jam/repositories/HaikuPorts/x86_64 @@ -13,6 +13,7 @@ RemotePackageRepository HaikuPorts droid-113-2 texi2html-1.82-2 timgmsoundfont-fixed-5 + unknown_horizons-2014.1-1 vl_gothic-20141206-1 wqy_microhei-0.2.0~beta-3 : @@ -74,6 +75,7 @@ RemotePackageRepository HaikuPorts curl_devel-7.45.0-1 cvs-1.12.13.1-7 cvsps-2.2b1-1 + cython-0.23.4-1 dbus-1.8.6-1 dbus_devel-1.8.6-1 diffutils-3.3-2 @@ -84,6 +86,9 @@ RemotePackageRepository HaikuPorts enca_devel-1.15-1 expat-2.1.0-1 expat_devel-2.1.0-1 + fife-0.4.0~20150801-1 + fifechan-0.1.2-1 + fifechan_devel-0.1.2-1 file-5.25-1 file_devel-5.25-1 findutils-4.4.2-1 @@ -293,6 +298,8 @@ RemotePackageRepository HaikuPorts nspr_devel-4.10.9-1 nss-3.20-1 nss_devel-3.20-1 + openal-1.13.0-2 + openal_devel-1.13.0-2 openssh-7.1p1-1 openssl-1.0.0s-2 openssl_devel-1.0.0s-2 @@ -303,9 +310,12 @@ RemotePackageRepository HaikuPorts pixman-0.32.6-1 pixman_devel-0.32.6-1 pkgconfig-0.27.1-2 + pyenet-20141025-1 python-2.7.10-1 + python_setuptools-5.3-2 python_twisted-13.2.0-1 python_zope.interface-4.1.1-2 + pyyaml-3.11-1 qca2-2.0.3-1 qca2_devel-2.0.3-1 qemu-2.1.2-2 @@ -395,6 +405,7 @@ RemotePackageRepository HaikuPorts curl cvs cvsps + cython dbus diffutils dos2unix @@ -402,6 +413,8 @@ RemotePackageRepository HaikuPorts dtc enca expat + fife + fifechan file findutils ffmpeg @@ -515,6 +528,7 @@ RemotePackageRepository HaikuPorts ninja nspr nss + openal openssh openssl p7zip @@ -523,9 +537,12 @@ RemotePackageRepository HaikuPorts perl pixman pkgconfig + pyenet python + python_setuptools python_twisted python_zope.interface + pyyaml qca2 qemu qrencode From 3b23bfdbaf7a521a01d2f42b2bf27eb50eb7fd86 Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Mon, 26 Oct 2015 23:42:05 +1000 Subject: [PATCH 036/370] Qt5: Add Qt 5.5.1 packages for x86_gcc2 --- build/jam/repositories/HaikuPorts/x86_gcc2 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build/jam/repositories/HaikuPorts/x86_gcc2 b/build/jam/repositories/HaikuPorts/x86_gcc2 index eb882c67e6..e80fc8835b 100644 --- a/build/jam/repositories/HaikuPorts/x86_gcc2 +++ b/build/jam/repositories/HaikuPorts/x86_gcc2 @@ -831,8 +831,9 @@ RemotePackageRepository HaikuPorts qjson_x86-0.8.1-1 qjson_x86_devel-0.8.1-1 qmplay2_x86-15.05.30-2 - qt5base_x86-5.5.0-2 - qt5base_x86_devel-5.5.0-2 + qt5_x86-5.5.1-1 + qt5_x86_devel-5.5.1-1 + qt5_x86_docs-5.5.1-1 quassel_x86-0.10.0-2 quicklaunch-0.9.12-1 qupzilla_x86-1.8.6-1 From d500273dd1ab2a30ef4c93c1c67326fa0b9198f2 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Mon, 26 Oct 2015 17:29:45 +0100 Subject: [PATCH 037/370] Fixed typo for German user guide package. --- build/jam/packages/HaikuUserguide | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/jam/packages/HaikuUserguide b/build/jam/packages/HaikuUserguide index c42519abec..7dc0ef51d8 100644 --- a/build/jam/packages/HaikuUserguide +++ b/build/jam/packages/HaikuUserguide @@ -18,7 +18,7 @@ local haikuUserGuidePackageDE = haiku_userguide_de.hpkg ; HaikuPackage $(haikuUserGuidePackageDE) ; CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide de ] - : ca ; + : de ; CopyDirectoryToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide images ] : images ; AddFilesToPackage documentation userguide : [ FDirName $(HAIKU_TOP) docs userguide Haiku-doc.css ] From 9e80618520b547ff17140020b81fe579f9a7c4ac Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Sun, 25 Oct 2015 10:58:32 +0100 Subject: [PATCH 038/370] hda: PVS1619-21: "unsigned < 0" comparisons * Probably harmless, the overflow on the other side was already checked. --- src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp index eb7e358b7f..7557d732c2 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp +++ b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp @@ -618,7 +618,7 @@ get_control_gain_mute(hda_audio_group* audioGroup, static status_t get_mix(hda_audio_group* audioGroup, multi_mix_value_info * mmvi) { - uint32 id; + int32 id; hda_multi_mixer_control *control = NULL; for (int32 i = 0; i < mmvi->item_count; i++) { id = mmvi->values[i].id - MULTI_CONTROL_FIRSTID; @@ -686,7 +686,7 @@ get_mix(hda_audio_group* audioGroup, multi_mix_value_info * mmvi) static status_t set_mix(hda_audio_group* audioGroup, multi_mix_value_info * mmvi) { - uint32 id; + int32 id; hda_multi_mixer_control *control = NULL; for (int32 i = 0; i < mmvi->item_count; i++) { id = mmvi->values[i].id - MULTI_CONTROL_FIRSTID; From 4286d20b878d4c001c725a1c6db50fb9a8dec114 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Sun, 25 Oct 2015 11:41:28 +0100 Subject: [PATCH 039/370] intel_extreme: PVS 1765-6: only use bool in conditions * Style fix, no functional changes. --- src/add-ons/accelerants/intel_extreme/overlay.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/add-ons/accelerants/intel_extreme/overlay.cpp b/src/add-ons/accelerants/intel_extreme/overlay.cpp index 84c1677289..2d4f41ef3f 100644 --- a/src/add-ons/accelerants/intel_extreme/overlay.cpp +++ b/src/add-ons/accelerants/intel_extreme/overlay.cpp @@ -573,8 +573,8 @@ intel_configure_overlay(overlay_token overlayToken, } if (!gInfo->shared_info->overlay_active - || memcmp(&gInfo->last_overlay_view, view, sizeof(overlay_view)) - || memcmp(&gInfo->last_overlay_frame, window, sizeof(overlay_frame))) { + || memcmp(&gInfo->last_overlay_view, view, sizeof(overlay_view) != 0) + || memcmp(&gInfo->last_overlay_frame, window, sizeof(overlay_frame)) != 0) { // scaling has changed, program window and scaling factor // clip the window to on screen bounds From fe055bf34307fab6c0144d080a01072d701c38ef Mon Sep 17 00:00:00 2001 From: Jeroen Oortwijn Date: Tue, 22 Sep 2015 00:35:15 +0200 Subject: [PATCH 040/370] change html output to confirm to XHTML Strict Several errors in the html output caused WebPositive to not render the file completely. Signed-off-by: Adrien Destugues Fixes #12387. --- src/tools/checkstyle/checkstyle.py | 4 ++-- src/tools/checkstyle/utils.py | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/tools/checkstyle/checkstyle.py b/src/tools/checkstyle/checkstyle.py index fb581ef614..7b86341cab 100755 --- a/src/tools/checkstyle/checkstyle.py +++ b/src/tools/checkstyle/checkstyle.py @@ -58,9 +58,9 @@ cppRules["Operator at line end"] = re.compile('([*=/+\-\|\&\?]|\&&|\|\|)(?=\n)') cppRules["Missing space"] = re.compile('\){') cppRules["Mixed tabs/spaces"] = re.compile('( \t]|\t )+') cppRules["Malformed else"] = re.compile('}[ \t]*\n[ \t]*else') -cppRules["Lines between functions > 2"] \ +cppRules["Lines between functions > 2"] \ = re.compile('(?<=\n})([ \t]*\n){3,}(?=\n)') -cppRules["Lines between functions < 2"] \ +cppRules["Lines between functions < 2"] \ = re.compile('(?<=\n})([ \t]*\n){0,2}(?=.)') cppRules["Windows Line Ending"] = re.compile('\r') cppRules["Bad pointer/reference style"] \ diff --git a/src/tools/checkstyle/utils.py b/src/tools/checkstyle/utils.py index 8b20575811..8b587d4cce 100644 --- a/src/tools/checkstyle/utils.py +++ b/src/tools/checkstyle/utils.py @@ -27,9 +27,9 @@ def openHtml(fileList, outputFileName): -

File list:
""") +

File list:
""") for fileName in fileList: - file.write(fileName + "
") + file.write(fileName + "
") file.write("

") file.close() @@ -37,7 +37,6 @@ def openHtml(fileList, outputFileName): def closeHtml(outputFileName): file = open(outputFileName, 'a') file.write(""" - """) @@ -67,14 +66,14 @@ def renderHtml(text, highlights, sourceFileName, outputFileName): file.write('
')
     count = 1
     for line in temp.split('\n'):
-        file.write(str(count).rjust(4)+"
") + file.write(str(count).rjust(4)+"
") count += 1 file.write('
')
 
     for line in temp.split('\n'):
         file.write(' ' + line.replace('\r', ' ') \
-             + '
') + + '
') file.write("
") From 7676393722c04f18ab707796627d35ed9f2837db Mon Sep 17 00:00:00 2001 From: Markus Himmel Date: Sun, 20 Sep 2015 16:20:17 +0000 Subject: [PATCH 041/370] Minor correction in BTranslatorRoster documentation --- docs/user/translation/TranslatorRoster.dox | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/user/translation/TranslatorRoster.dox b/docs/user/translation/TranslatorRoster.dox index b306be65a6..5aea2382ce 100644 --- a/docs/user/translation/TranslatorRoster.dox +++ b/docs/user/translation/TranslatorRoster.dox @@ -87,8 +87,9 @@ \fn static BTranslatorRoster* BTranslatorRoster::Default(); \brief Gets the default BTranslatorRoster. - There is only one default translator. It is created when it is first - requested. It is poplated according to the following rules: + At any point, there is only one default roster. It is created when it is + first requested (possibly after being deleted) and is poplated according + to the following rules: If the environment variable \c TRANSLATORS is set, it will be populated with all translators that are present in the directories denoted by From ed3c7f8fc262592038890c44bac576177a9a9068 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Mon, 26 Oct 2015 18:43:35 +0100 Subject: [PATCH 042/370] BTranslatorRoster::Default docs: Further rework and typo fixes --- docs/user/translation/TranslatorRoster.dox | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/user/translation/TranslatorRoster.dox b/docs/user/translation/TranslatorRoster.dox index 5aea2382ce..9d464e72b3 100644 --- a/docs/user/translation/TranslatorRoster.dox +++ b/docs/user/translation/TranslatorRoster.dox @@ -87,18 +87,18 @@ \fn static BTranslatorRoster* BTranslatorRoster::Default(); \brief Gets the default BTranslatorRoster. - At any point, there is only one default roster. It is created when it is - first requested (possibly after being deleted) and is poplated according - to the following rules: + At any point, there is only one default roster. It is created when this + method is called for the first time (possibly after being deleted) and is + populated according to the following rules: - If the environment variable \c TRANSLATORS is set, it will be populated - with all translators that are present in the directories denoted by - \c TRANSLATORS. The paths are separated by a colon (:). If - multiple paths contain a translator with the same name, the translator + If the environment variable \c TRANSLATORS is set, the default roster will + be populated with all translators that are present in the directories + denoted by \c TRANSLATORS. The paths are separated by a colon (:). + If multiple paths contain a translator with the same name, the translator that is located in the path that appears earliest in \c TRANSLATORS will be kept. - If \c TRANSLATORS is unset, the user non-packaged add-ons directory, the + If \c TRANSLATORS is not set, the user non-packaged add-ons directory, the user add-ons directory, the system non-packaged add-ons directory and the system add-ons directory will be used. If those directories do not contain a subdirectory \c Translators, it will be created. The subdirectories are From 949cf6ac85e384223acbc2450558fe566e18c256 Mon Sep 17 00:00:00 2001 From: Murai Takashi Date: Sun, 19 Apr 2015 17:56:19 +0900 Subject: [PATCH 043/370] Fix GCC 5 build. * Add -fgnu89-inline flag for libroot/posix/glibc * Change __GNUC__ == 4 to __GNUC__ >= 4 Signed-off-by: Adrien Destugues Fixes #11990, most of the changes had already been done. --- headers/private/media/ServerInterface.h | 2 +- src/kits/interface/Rect.cpp | 4 ++-- src/system/runtime_loader/elf_load_image.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/headers/private/media/ServerInterface.h b/headers/private/media/ServerInterface.h index 59991e617d..177b18a327 100644 --- a/headers/private/media/ServerInterface.h +++ b/headers/private/media/ServerInterface.h @@ -190,7 +190,7 @@ struct reply_data { struct command_data { // yes, it's empty ;) -#if __GNUC__ == 4 +#if __GNUC__ >= 4 int32 _padding; // GCC 2 and GCC 4 treat empty structures differently #endif diff --git a/src/kits/interface/Rect.cpp b/src/kits/interface/Rect.cpp index 06d4e38a49..3c9a0d659a 100644 --- a/src/kits/interface/Rect.cpp +++ b/src/kits/interface/Rect.cpp @@ -332,7 +332,7 @@ OffsetToCopy__5BRectff(BRect* self, float dx, float dy) } -#elif __GNUC__ == 4 +#elif __GNUC__ >= 4 // TODO: remove this when new GCC 4 packages have to be built anyway @@ -390,4 +390,4 @@ _ZN5BRect12OffsetToCopyEff(BRect* self, float dx, float dy) } -#endif // __GNUC__ == 4 +#endif // __GNUC__ >= 4 diff --git a/src/system/runtime_loader/elf_load_image.cpp b/src/system/runtime_loader/elf_load_image.cpp index 011094839a..cfa4e34fcf 100644 --- a/src/system/runtime_loader/elf_load_image.cpp +++ b/src/system/runtime_loader/elf_load_image.cpp @@ -552,7 +552,7 @@ load_image(char const* name, image_type type, const char* rpath, #if __GNUC__ == 2 if ((image->abi & B_HAIKU_ABI_MAJOR) == B_HAIKU_ABI_GCC_4) sSearchPathSubDir = "x86"; - #elif __GNUC__ == 4 + #elif __GNUC__ >= 4 if ((image->abi & B_HAIKU_ABI_MAJOR) == B_HAIKU_ABI_GCC_2) sSearchPathSubDir = "x86_gcc2"; #endif From 1e6dd3feed715e3344f19c80898e54b33f11d736 Mon Sep 17 00:00:00 2001 From: Murai Takashi Date: Sat, 25 Apr 2015 08:08:00 +0900 Subject: [PATCH 044/370] Fix GCC 5 maybe-uninitialized warnings. Signed-off-by: Adrien Destugues Fixes #12020 --- .../accelerants/radeon_hd/atombios/atom.cpp | 22 +++++++++---------- .../kernel/file_systems/bfs/BPlusTree.cpp | 6 ++--- .../x86_physical_page_mapper_large_memory.cpp | 2 +- .../kernel/device_manager/device_manager.cpp | 2 +- src/system/kernel/fs/vfs.cpp | 2 +- .../kernel/messaging/MessagingService.cpp | 2 +- src/system/libroot/os/driver_settings.cpp | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/add-ons/accelerants/radeon_hd/atombios/atom.cpp b/src/add-ons/accelerants/radeon_hd/atombios/atom.cpp index 6c61e53c45..2afcd26a88 100644 --- a/src/add-ons/accelerants/radeon_hd/atombios/atom.cpp +++ b/src/add-ons/accelerants/radeon_hd/atombios/atom.cpp @@ -496,7 +496,7 @@ static void atom_op_add(atom_exec_context *ctx, int *ptr, int arg) { uint8 attr = U8((*ptr)++); - uint32 dst, src, saved; + uint32 dst, src, saved = 0; int dptr = *ptr; dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); src = atom_get_src(ctx, attr, ptr); @@ -513,7 +513,7 @@ static void atom_op_and(atom_exec_context *ctx, int *ptr, int arg) { uint8 attr = U8((*ptr)++); - uint32 dst, src, saved; + uint32 dst, src, saved = 0; int dptr = *ptr; dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); src = atom_get_src(ctx, attr, ptr); @@ -559,7 +559,7 @@ static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg) { uint8 attr = U8((*ptr)++); - uint32 saved; + uint32 saved = 0; int dptr = *ptr; attr &= 0x38; attr |= atom_def_dst[attr>>3]<<6; @@ -684,7 +684,7 @@ static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg) { uint8 attr = U8((*ptr)++); - uint32 dst, mask, src, saved; + uint32 dst, mask, src, saved = 0; int dptr = *ptr; dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); mask = atom_get_src_direct(ctx, ((attr >> 3) & 7), ptr); @@ -740,7 +740,7 @@ static void atom_op_or(atom_exec_context *ctx, int *ptr, int arg) { uint8 attr = U8((*ptr)++); - uint32 dst, src, saved; + uint32 dst, src, saved = 0; int dptr = *ptr; dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); src = atom_get_src(ctx, attr, ptr); @@ -848,7 +848,7 @@ atom_op_setregblock(atom_exec_context *ctx, int *ptr, int arg) static void atom_op_shift_left(atom_exec_context *ctx, int *ptr, int arg) { uint8 attr = U8((*ptr)++), shift; - uint32 saved, dst; + uint32 saved = 0, dst; int dptr = *ptr; attr &= 0x38; attr |= atom_def_dst[attr >> 3] << 6; @@ -866,7 +866,7 @@ static void atom_op_shift_left(atom_exec_context *ctx, int *ptr, int arg) static void atom_op_shift_right(atom_exec_context *ctx, int *ptr, int arg) { uint8 attr = U8((*ptr)++), shift; - uint32 saved, dst; + uint32 saved = 0, dst; int dptr = *ptr; attr &= 0x38; attr |= atom_def_dst[attr >> 3] << 6; @@ -884,7 +884,7 @@ static void atom_op_shift_right(atom_exec_context *ctx, int *ptr, int arg) static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) { uint8 attr = U8((*ptr)++), shift; - uint32 saved, dst; + uint32 saved = 0, dst; int dptr = *ptr; uint32 dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3]; dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); @@ -905,7 +905,7 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg) { uint8 attr = U8((*ptr)++), shift; - uint32 saved, dst; + uint32 saved = 0, dst; int dptr = *ptr; uint32 dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3]; dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); @@ -927,7 +927,7 @@ static void atom_op_sub(atom_exec_context *ctx, int *ptr, int arg) { uint8 attr = U8((*ptr)++); - uint32 dst, src, saved; + uint32 dst, src, saved = 0; int dptr = *ptr; dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); src = atom_get_src(ctx, attr, ptr); @@ -984,7 +984,7 @@ static void atom_op_xor(atom_exec_context *ctx, int *ptr, int arg) { uint8 attr = U8((*ptr)++); - uint32 dst, src, saved; + uint32 dst, src, saved = 0; int dptr = *ptr; dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); src = atom_get_src(ctx, attr, ptr); diff --git a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp index 9a6cf4e6cf..330ed6e6bd 100644 --- a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp @@ -1062,7 +1062,7 @@ BPlusTree::_FindKey(const bplustree_node* node, const uint8* key, for (int16 first = 0, last = node->NumKeys() - 1; first <= last;) { uint16 i = (first + last) >> 1; - uint16 searchLength; + uint16 searchLength = 0; uint8* searchKey = node->KeyAt(i, &searchLength); if (searchKey + searchLength + sizeof(off_t) + sizeof(uint16) > (uint8*)node + fNodeSize @@ -2732,7 +2732,7 @@ TreeIterator::Traverse(int8 direction, void* key, uint16* keyLength, if (node->all_key_count == 0) RETURN_ERROR(B_ERROR); // B_ENTRY_NOT_FOUND ? - uint16 length; + uint16 length = 0; uint8* keyStart = node->KeyAt(fCurrentKey, &length); if (keyStart + length + sizeof(off_t) + sizeof(uint16) > (uint8*)node + fTree->fNodeSize @@ -2991,7 +2991,7 @@ bplustree_node::CheckIntegrity(uint32 nodeSize) const DEBUGGER(("invalid node: key/length count")); for (int32 i = 0; i < NumKeys(); i++) { - uint16 length; + uint16 length = 0; uint8* key = KeyAt(i, &length); if (key + length + sizeof(off_t) + sizeof(uint16) > (uint8*)this + nodeSize diff --git a/src/system/kernel/arch/x86/paging/x86_physical_page_mapper_large_memory.cpp b/src/system/kernel/arch/x86/paging/x86_physical_page_mapper_large_memory.cpp index 07c9446fdc..e816af1ea8 100644 --- a/src/system/kernel/arch/x86/paging/x86_physical_page_mapper_large_memory.cpp +++ b/src/system/kernel/arch/x86/paging/x86_physical_page_mapper_large_memory.cpp @@ -492,7 +492,7 @@ status_t LargeMemoryPhysicalPageMapper::GetPage(phys_addr_t physicalAddress, addr_t* virtualAddress, void** handle) { - PhysicalPageSlot* slot; + PhysicalPageSlot* slot = NULL; status_t error = GetSlot(true, slot); if (error != B_OK) return error; diff --git a/src/system/kernel/device_manager/device_manager.cpp b/src/system/kernel/device_manager/device_manager.cpp index 5537aa0d8d..f42a03094d 100644 --- a/src/system/kernel/device_manager/device_manager.cpp +++ b/src/system/kernel/device_manager/device_manager.cpp @@ -2209,7 +2209,7 @@ init_node_tree(void) {NULL} }; - device_node* node; + device_node* node = NULL; if (register_node(NULL, DEVICE_MANAGER_ROOT_NAME, attrs, NULL, &node) != B_OK) { dprintf("Cannot register Devices Root Node\n"); diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 2d133b8e36..6645658015 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -4121,7 +4121,7 @@ vfs_get_vnode_from_path(const char* path, bool kernel, struct vnode** _vnode) extern "C" status_t vfs_get_vnode(dev_t mountID, ino_t vnodeID, bool canWait, struct vnode** _vnode) { - struct vnode* vnode; + struct vnode* vnode = NULL; status_t status = get_vnode(mountID, vnodeID, &vnode, canWait, false); if (status != B_OK) diff --git a/src/system/kernel/messaging/MessagingService.cpp b/src/system/kernel/messaging/MessagingService.cpp index 728a31eb5b..4b59f25eec 100644 --- a/src/system/kernel/messaging/MessagingService.cpp +++ b/src/system/kernel/messaging/MessagingService.cpp @@ -568,7 +568,7 @@ _user_register_messaging_service(sem_id lockSem, sem_id counterSem) if (!sMessagingService->Lock()) return B_BAD_VALUE; - area_id areaID; + area_id areaID = 0; status_t error = sMessagingService->RegisterService(lockSem, counterSem, areaID); diff --git a/src/system/libroot/os/driver_settings.cpp b/src/system/libroot/os/driver_settings.cpp index 17a6473dfb..9004095dac 100644 --- a/src/system/libroot/os/driver_settings.cpp +++ b/src/system/libroot/os/driver_settings.cpp @@ -282,7 +282,7 @@ parse_parameter(struct driver_parameter *parameter, char **_pos, int32 level) status = get_word(&pos, ¶meter->name, NO_ASSIGNMENT, true); if (status == CONTINUE_PARAMETER) { while (status == CONTINUE_PARAMETER) { - char **newArray, *value; + char **newArray, *value = NULL; status = get_word(&pos, &value, parameter->value_count == 0 ? ALLOW_ASSIGNMENT : IGNORE_ASSIGNMENT, false); if (status < B_OK) From 078b88b12df1f3be41ba3b3a7ef136309d33fdae Mon Sep 17 00:00:00 2001 From: Simon South Date: Wed, 21 Oct 2015 08:18:43 -0400 Subject: [PATCH 045/370] runtime_loader: Randomly position only relocatable code The use of an unreliable test for relocatability effectively broke runtime_loader's support for non-position-independent executables, as it would insist on randomly positioning these files' segments in memory anyway causing the program to quickly crash. With this change runtime_loader uses the object type specified in the file's header to determine whether its segments can be safely relocated, restoring support for non-PI executables. Fixes #12427. Signed-off-by: Adrien Destugues --- headers/private/system/elf_common.h | 11 +++++++++++ src/system/runtime_loader/elf_load_image.cpp | 2 +- src/system/runtime_loader/images.cpp | 16 +++++++++++----- src/system/runtime_loader/images.h | 2 +- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/headers/private/system/elf_common.h b/headers/private/system/elf_common.h index 3e65305563..23ab555032 100644 --- a/headers/private/system/elf_common.h +++ b/headers/private/system/elf_common.h @@ -31,6 +31,17 @@ #define EI_VERSION 6 #define EI_PAD 7 +// e_type (Object file type) +#define ET_NONE 0 // No file type +#define ET_REL 1 // Relocatable file +#define ET_EXEC 2 // Executable file +#define ET_DYN 3 // Shared object file +#define ET_CORE 4 // Core file +#define ET_LOOS 0xfe00 // OS-specific range start +#define ET_HIOS 0xfeff // OS-specific range end +#define ET_LOPROC 0xff00 // Processor-specific range start +#define ET_HIPROC 0xffff // Processor-specific range end + // e_machine (Architecture) #define EM_NONE 0 // No machine #define EM_M32 1 // AT&T WE 32100 diff --git a/src/system/runtime_loader/elf_load_image.cpp b/src/system/runtime_loader/elf_load_image.cpp index cfa4e34fcf..8455645a60 100644 --- a/src/system/runtime_loader/elf_load_image.cpp +++ b/src/system/runtime_loader/elf_load_image.cpp @@ -527,7 +527,7 @@ load_image(char const* name, image_type type, const char* rpath, goto err2; } - status = map_image(fd, path, image); + status = map_image(fd, path, image, eheader.e_type == ET_EXEC); if (status < B_OK) { FATAL("%s: Could not map image: %s\n", image->path, strerror(status)); status = B_ERROR; diff --git a/src/system/runtime_loader/images.cpp b/src/system/runtime_loader/images.cpp index d851f9fd06..2b7f6dfe8c 100644 --- a/src/system/runtime_loader/images.cpp +++ b/src/system/runtime_loader/images.cpp @@ -169,9 +169,9 @@ topological_sort(image_t* image, uint32 slot, image_t** initList, */ static void get_image_region_load_address(image_t* image, uint32 index, long lastDelta, - addr_t& loadAddress, uint32& addressSpecifier) + bool fixed, addr_t& loadAddress, uint32& addressSpecifier) { - if (image->dynamic_ptr != 0) { + if (!fixed) { // relocatable image... we can afford to place wherever if (index == 0) { // but only the first segment gets a free ride @@ -286,7 +286,7 @@ put_image(image_t* image) status_t -map_image(int fd, char const* path, image_t* image) +map_image(int fd, char const* path, image_t* image, bool fixed) { // cut the file name from the path as base name for the created areas const char* baseName = strrchr(path, '/'); @@ -304,10 +304,16 @@ map_image(int fd, char const* path, image_t* image) uint32 addressSpecifier = B_RANDOMIZED_ANY_ADDRESS; for (uint32 i = 0; i < image->num_regions; i++) { + // for BeOS compatibility: if we load an old BeOS executable, we + // have to relocate it, if possible - we recognize it because the + // vmstart is set to 0 (hopefully always) + if (fixed && image->regions[i].vmstart == 0) + fixed = false; + uint32 regionAddressSpecifier; get_image_region_load_address(image, i, i > 0 ? loadAddress - image->regions[i - 1].vmstart : 0, - loadAddress, regionAddressSpecifier); + fixed, loadAddress, regionAddressSpecifier); if (i == 0) { reservedAddress = loadAddress; addressSpecifier = regionAddressSpecifier; @@ -339,7 +345,7 @@ map_image(int fd, char const* path, image_t* image) baseName, i, (image->regions[i].flags & RFLAG_RW) ? "rw" : "ro"); get_image_region_load_address(image, i, - i > 0 ? image->regions[i - 1].delta : 0, loadAddress, + i > 0 ? image->regions[i - 1].delta : 0, fixed, loadAddress, addressSpecifier); // If the image position is arbitrary, we must let it point to the start diff --git a/src/system/runtime_loader/images.h b/src/system/runtime_loader/images.h index 7a309bb6c8..a929040b42 100644 --- a/src/system/runtime_loader/images.h +++ b/src/system/runtime_loader/images.h @@ -50,7 +50,7 @@ void delete_image_struct(image_t* image); void delete_image(image_t* image); void put_image(image_t* image); -status_t map_image(int fd, char const* path, image_t* image); +status_t map_image(int fd, char const* path, image_t* image, bool fixed); void unmap_image(image_t* image); void remap_images(); From d5447eb9c02e0f64f70f2abd94a705b376ba590a Mon Sep 17 00:00:00 2001 From: Simon South Date: Sun, 25 Oct 2015 06:27:26 -0400 Subject: [PATCH 046/370] runtime_loader: Do not assume executable has dynamic segment This prevents a crash when loading a statically linked executable. Fixes #12287. Signed-off-by: Adrien Destugues --- src/system/runtime_loader/elf_symbol_lookup.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system/runtime_loader/elf_symbol_lookup.h b/src/system/runtime_loader/elf_symbol_lookup.h index 433c9abb51..247c945b37 100644 --- a/src/system/runtime_loader/elf_symbol_lookup.h +++ b/src/system/runtime_loader/elf_symbol_lookup.h @@ -58,7 +58,7 @@ struct SymbolLookupInfo { struct SymbolLookupCache { SymbolLookupCache(image_t* image) : - fTableSize(image->symhash[1]), + fTableSize(image->symhash != NULL ? image->symhash[1] : 0), fValues(NULL), fDSOs(NULL), fValuesResolved(NULL) From 1a28be27e84b9257b8d939c4f6716df52e080c58 Mon Sep 17 00:00:00 2001 From: Simon South Date: Tue, 27 Oct 2015 06:57:47 -0400 Subject: [PATCH 047/370] Fix unittests build. Signed-off-by: John Scipione --- src/tests/servers/launch/Jamfile | 3 ++- src/tests/servers/launch/UtilityTest.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tests/servers/launch/Jamfile b/src/tests/servers/launch/Jamfile index 1ce341c0a1..884ad6fbfa 100644 --- a/src/tests/servers/launch/Jamfile +++ b/src/tests/servers/launch/Jamfile @@ -14,9 +14,10 @@ UnitTestLib liblaunch_daemontest.so : UtilityTest.cpp # from the launch_daemon + NetworkWatcher.cpp SettingsParser.cpp Conditions.cpp Utility.cpp - : be libshared.a [ TargetLibstdc++ ] [ TargetLibsupc++ ] + : be network bnetapi libshared.a [ TargetLibstdc++ ] [ TargetLibsupc++ ] ; diff --git a/src/tests/servers/launch/UtilityTest.cpp b/src/tests/servers/launch/UtilityTest.cpp index 70841c93e3..a995258cf3 100644 --- a/src/tests/servers/launch/UtilityTest.cpp +++ b/src/tests/servers/launch/UtilityTest.cpp @@ -50,7 +50,7 @@ UtilityTest::AddTests(BTestSuite& parent) CppUnit::TestSuite& suite = *new CppUnit::TestSuite("UtilityTest"); suite.addTest(new CppUnit::TestCaller( - "UtilityTest::TestTranslatePath", &UtilityTest::TestEmpty)); + "UtilityTest::TestTranslatePath", &UtilityTest::TestTranslatePath)); parent.addTest("UtilityTest", &suite); } From 4c7d851f15025f750b20d98ab65d2a17e1689d7a Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Tue, 27 Oct 2015 22:50:59 +0000 Subject: [PATCH 048/370] Update libsdl packages to include 24 bit screen mode fixes. --- build/jam/repositories/HaikuPorts/x86 | 4 ++-- build/jam/repositories/HaikuPorts/x86_64 | 4 ++-- build/jam/repositories/HaikuPorts/x86_gcc2 | 9 +++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/build/jam/repositories/HaikuPorts/x86 b/build/jam/repositories/HaikuPorts/x86 index 69cc67b807..1d02227495 100644 --- a/build/jam/repositories/HaikuPorts/x86 +++ b/build/jam/repositories/HaikuPorts/x86 @@ -182,8 +182,8 @@ RemotePackageRepository HaikuPorts libqt4_devel-4.8.7-2 libsanta-3.0.1-1 libsanta_devel-3.0.1-1 - libsdl-1.2.15-6 - libsdl_devel-1.2.15-6 + libsdl-1.2.15-9 + libsdl_devel-1.2.15-9 libssh2-1.5.0-1 libssh2_devel-1.5.0-1 libsolv-0.3.0_haiku_2014_12_22-1 diff --git a/build/jam/repositories/HaikuPorts/x86_64 b/build/jam/repositories/HaikuPorts/x86_64 index 5668c1a7a5..7052fa6fe2 100644 --- a/build/jam/repositories/HaikuPorts/x86_64 +++ b/build/jam/repositories/HaikuPorts/x86_64 @@ -230,8 +230,8 @@ RemotePackageRepository HaikuPorts libsamplerate_devel-0.1.8-2 libsndfile-1.0.25-3 libsndfile_devel-1.0.25-3 - libsdl-1.2.15-6 - libsdl_devel-1.2.15-6 + libsdl-1.2.15-9 + libsdl_devel-1.2.15-9 libsdl2-2.0.3-1 libsdl2_devel-2.0.3-1 libssh2-1.5.0-1 diff --git a/build/jam/repositories/HaikuPorts/x86_gcc2 b/build/jam/repositories/HaikuPorts/x86_gcc2 index e80fc8835b..c815545ea3 100644 --- a/build/jam/repositories/HaikuPorts/x86_gcc2 +++ b/build/jam/repositories/HaikuPorts/x86_gcc2 @@ -279,8 +279,8 @@ RemotePackageRepository HaikuPorts libreplaygain_devel-r475-1 libsanta-3.0.0-3 libsanta_devel-3.0.0-3 - libsdl-1.2.15-6 - libsdl_devel-1.2.15-6 + libsdl-1.2.15-9 + libsdl_devel-1.2.15-9 libsdl2-2.0.3-2 libsdl2_devel-2.0.3-2 libsigc++-1.2.7-1 @@ -734,8 +734,8 @@ RemotePackageRepository HaikuPorts libsanta_x86_devel-3.0.1-1 libsigc++_x86-2.4.1-1 libsigc++_x86_devel-2.4.1-1 - libsdl_x86-1.2.15-7 - libsdl_x86_devel-1.2.15-7 + libsdl_x86-1.2.15-9 + libsdl_x86_devel-1.2.15-9 libsdl2_x86-2.0.1-3 libsdl2_x86_devel-2.0.1-3 libsndfile_x86-1.0.25-3 @@ -1148,6 +1148,7 @@ RemotePackageRepository HaikuPorts libsanta_x86 libsamplerate_x86 libsdl + libsdl_x86 libsdl2 libsdl2_x86 libsigc++ From 6c009cde0bf1d306c7d13d2b85f39f9f683761dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Wed, 28 Oct 2015 21:20:38 +0100 Subject: [PATCH 049/370] kernel: avoid dprintf messages for known header types we don't use. * fix a typo in runtime_loader/count_regions(). --- src/system/kernel/elf.cpp | 6 ++++++ src/system/runtime_loader/elf_load_image.cpp | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/elf.cpp b/src/system/kernel/elf.cpp index 66764f71ab..2ed0240787 100644 --- a/src/system/kernel/elf.cpp +++ b/src/system/kernel/elf.cpp @@ -2231,6 +2231,12 @@ load_kernel_add_on(const char *path) case PT_DYNAMIC: image->dynamic_section = programHeaders[i].p_vaddr; continue; + case PT_INTERP: + // should check here for appropriate interpreter + continue; + case PT_PHDR: + // we don't use it + continue; default: dprintf("%s: unhandled pheader type %#" B_PRIx32 "\n", fileName, programHeaders[i].p_type); diff --git a/src/system/runtime_loader/elf_load_image.cpp b/src/system/runtime_loader/elf_load_image.cpp index 8455645a60..c6bcbbff41 100644 --- a/src/system/runtime_loader/elf_load_image.cpp +++ b/src/system/runtime_loader/elf_load_image.cpp @@ -64,7 +64,7 @@ count_regions(const char* imagePath, char const* buff, int phnum, int phentsize) // will be handled at some other place break; case PT_INTERP: - // should check here for appropiate interpreter + // should check here for appropriate interpreter break; case PT_NOTE: // unsupported From 874e9521b2bcdbe346bafe6ef4c59f106cc80327 Mon Sep 17 00:00:00 2001 From: Simon South Date: Wed, 28 Oct 2015 09:53:43 -0400 Subject: [PATCH 050/370] x86_64: Glue code: Keep stack 16-byte-aligned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Duval --- src/system/glue/arch/x86_64/crti.S | 2 ++ src/system/glue/arch/x86_64/crtn.S | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/system/glue/arch/x86_64/crti.S b/src/system/glue/arch/x86_64/crti.S index 3ef8e5f8df..ec26b6d5a3 100644 --- a/src/system/glue/arch/x86_64/crti.S +++ b/src/system/glue/arch/x86_64/crti.S @@ -30,6 +30,7 @@ FUNCTION(_init): // Preserve image ID for call to __haiku_init_after. push %rdi + sub $0x8, %rsp call __haiku_init_before // crtbegin.o stuff comes here @@ -39,5 +40,6 @@ FUNCTION(_fini): push %rbp movq %rsp, %rbp push %rdi + sub $0x8, %rsp call __haiku_term_before // crtend.o stuff comes here diff --git a/src/system/glue/arch/x86_64/crtn.S b/src/system/glue/arch/x86_64/crtn.S index 8ed6433843..6eb07e181a 100644 --- a/src/system/glue/arch/x86_64/crtn.S +++ b/src/system/glue/arch/x86_64/crtn.S @@ -13,6 +13,7 @@ .section .init // The image ID is preserved on the stack. + add $0x8, %rsp pop %rdi call __haiku_init_after movq %rbp, %rsp @@ -20,6 +21,7 @@ ret .section .fini + add $0x8, %rsp pop %rdi call __haiku_term_after movq %rbp, %rsp From 786e7135833b7f72a3f45654282de3de2c2259ab Mon Sep 17 00:00:00 2001 From: Automatic Committer Date: Thu, 29 Oct 2015 05:20:25 +0100 Subject: [PATCH 051/370] Update pci.ids from pciids.sourceforge.net --- src/data/ids/pci.ids | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/data/ids/pci.ids b/src/data/ids/pci.ids index bbe93326fb..dab7e3ff84 100644 --- a/src/data/ids/pci.ids +++ b/src/data/ids/pci.ids @@ -1,8 +1,8 @@ # # List of PCI ID's # -# Version: 2015.10.21 -# Date: 2015-10-21 03:15:02 +# Version: 2015.10.29 +# Date: 2015-10-29 03:15:02 # # Maintained by Albert Pool, Martin Mares, and other volunteers from # the PCI ID Project at http://pci-ids.ucw.cz/. @@ -2093,6 +2093,7 @@ 1458 228c R9 290X WindForce 3X 1458 228d R9 290X WindForce 3X OC 1458 2290 R9 290X WindForce 3X + 1458 22c1 Grenada PRO [Radeon R9 390] 1462 3070 R9 290X Lightning 1462 3071 R9 290X Lightning 1462 3072 R9 290X Lightning LE @@ -3238,6 +3239,7 @@ 174b aa98 Radeon HD 6450 1GB DDR3 aaa0 Tahiti XT HDMI Audio [Radeon HD 7970 Series] aab0 Cape Verde/Pitcairn HDMI Audio [Radeon HD 7700/7800 Series] + aac0 Tobago HDMI Audio [Radeon R7 360 / R9 360 OEM] aac8 Hawaii HDMI Audio ac00 Theater 600 Pro ac02 TV Wonder HD 600 PCIe @@ -7159,7 +7161,7 @@ 1369 a801 LCM200 1397 3136 4xS0-ISDN PCI Adapter 1397 3137 S2M-E1-ISDN PCI Adapter - 1518 0200 Kontron ThinkIO-C + 1518 0200 ThinkIO-C 15ed 1002 MCCS 8-port Serial Hot Swap 15ed 1003 MCCS 16-port Serial Hot Swap # MIL-STD-1553B Board @@ -10493,6 +10495,7 @@ 103c 1985 Pavilion 17-e163sg Notebook PC 5249 RTS5249 PCI Express Card Reader 103c 1909 ZBook 15 + 5286 RTS5286 PCI Express Card Reader 5288 RTS5288 PCI Express Card Reader 5289 RTL8411 PCI Express Card Reader 1043 1457 K55A Laptop @@ -12124,7 +12127,7 @@ 1138 Ziatech Corporation 8905 8905 [STD 32 Bridge] 1139 Dynamic Pictures, Inc - 0001 VGA Compatable 3D Graphics + 0001 VGA Compatible 3D Graphics 113a FWB Inc 113b Network Computing Devices 113c Cyclone Microsystems, Inc. @@ -15104,6 +15107,8 @@ 1752 PCI-1752 1754 PCI-1754 1756 PCI-1756 +# FPGA bridge to two SJA1000 + c302 MIOe-3680 2-Port CAN-Bus MIOe Module with Isolation Protection 13ff Silicon Spice Inc 1400 Artx Inc 1401 9432 TX @@ -15889,7 +15894,6 @@ 1485 ERMA - Electronic GmBH 1486 L3 Communications Telemetry & Instrumentation 1487 MARQUETTE Medical Systems -1488 KONTRON Electronik GmBH 1489 KYE Systems Corporation 148a OPTO 148b INNOMEDIALOGIC Inc. @@ -16880,6 +16884,8 @@ 2464 HSF 56k Data/Fax/Voice Modem (Mob SmartDAA) 2465 HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob SmartDAA) 2466 HSF 56k Data/Fax/Voice/Spkp Modem (Mob SmartDAA) + 2702 HSFi modem RD01-D270 + 1028 8d88 SmartHSFi V92 56K PCI Modem 2f00 HSF 56k HSFi Modem 13e0 8d84 IBM HSFi V.90 13e0 8d85 Compaq Stinger @@ -17296,8 +17302,8 @@ 158d Point Multimedia Systems 158e Lara Technology Inc 158f Ditect Coop -# nee 3PAR Inc. -1590 Hewlett-Packard Company +# formerly 3PAR Inc. +1590 Hewlett Packard Enterprise 0001 Eagle Cluster Manager 0002 Osprey Cluster Manager 0003 Harrier Cluster Manager @@ -18514,6 +18520,7 @@ 184a Thales Computers 1100 MAX II cPLD 1850 Advantest Corporation + 0048 EK220-66401 Computer Interface Card 1851 Microtune, Inc. 1852 Anritsu Corp. 1853 SMSC Automotive Infotainment System Group @@ -21860,9 +21867,9 @@ 1028 0000 Ethernet 10G X710 rNDC 1028 1f99 Ethernet 10G 4P X710/I350 rNDC 1028 1f9c Ethernet 10G 4P X710 SFP+ rNDC - 103c 0000 HPE Ethernet 10Gb 562SFP+ Adapter - 103c 22fc HPE Ethernet 10Gb 2-port 562FLR-SFP+ Adapter - 103c 22fd HPE Ethernet 10Gb 2-port 562SFP+ Adapter + 103c 0000 Ethernet 10Gb 562SFP+ Adapter + 103c 22fc HP Ethernet 10Gb 2-port 562FLR-SFP+ Adapter + 103c 22fd HP Ethernet 10Gb 2-port 562SFP+ Adapter 1137 0000 Ethernet Converged NIC X710-4 1137 013b Ethernet Converged NIC X710-4 17aa 0000 ThinkServer X710 AnyFabric for 10GbE SFP+ @@ -22024,6 +22031,7 @@ e4bf 3100 CX1-BAND 1962 80960RM (i960RM) Microprocessor 105a 0000 SuperTrak SX6000 I2O CPU + 19df DNV SMBus controller 1a21 82840 840 [Carmel] Chipset Host Bridge (Hub A) 1a23 82840 840 [Carmel] Chipset AGP Bridge 1a24 82840 840 [Carmel] Chipset PCI Bridge (Hub B) @@ -25728,6 +25736,7 @@ 530d 80310 (IOP) IO Processor 5845 QEMU NVM Express Controller 1af4 1100 QEMU Virtual Machine + 5ad4 Broxton SMBus Controller 65c0 5100 Chipset Memory Controller Hub 65e2 5100 Chipset PCI Express x4 Port 2 65e3 5100 Chipset PCI Express x4 Port 3 @@ -26381,6 +26390,7 @@ a012 Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller 144d c072 Notebook N150P a013 Atom Processor D4xx/D5xx/N4xx/N5xx CHAPS counter + a102 Sunrise Point-H SATA controller [AHCI mode] a103 Sunrise Point-H SATA Controller [AHCI mode] a105 Sunrise Point-H SATA Controller [RAID mode] a107 Sunrise Point-H SATA Controller [RAID mode] @@ -26555,7 +26565,7 @@ 8686 ScaleMP 1010 vSMPowered system controller [vSMP CTL] 8800 Trigem Computer Inc. - 2008 Video assistent component + 2008 Video assistant component 8866 T-Square Design Inc. 8888 Silicon Magic 8912 TRX From c4d22bb93335914504386f14fef0123f1c366427 Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Fri, 30 Oct 2015 00:28:43 +1000 Subject: [PATCH 052/370] Update liqt4 packages for x86_gcc2 --- build/jam/repositories/HaikuPorts/x86_gcc2 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build/jam/repositories/HaikuPorts/x86_gcc2 b/build/jam/repositories/HaikuPorts/x86_gcc2 index c815545ea3..98e692e903 100644 --- a/build/jam/repositories/HaikuPorts/x86_gcc2 +++ b/build/jam/repositories/HaikuPorts/x86_gcc2 @@ -415,6 +415,7 @@ RemotePackageRepository HaikuPorts qrencode_devel-3.3.0-1 # the non-devel package isn't useful qrencode_kdl_devel-3.3.0-2 + qsystray-0.1-2 rdesktop-1.8.0-2 readline-6.3.8-1 readline_devel-6.3.8-1 @@ -725,8 +726,8 @@ RemotePackageRepository HaikuPorts libpng_x86_devel-1.5.22-1 libpng16_x86-1.6.18-1 libpng16_x86_devel-1.6.18-1 - libqt4_x86-4.8.6.4-4 - libqt4_x86_devel-4.8.6.4-4 + libqt4_x86-4.8.7-3 + libqt4_x86_devel-4.8.7-3 librecad_x86-2.0.7-1 libsamplerate_x86-0.1.8-1 libsamplerate_x86_devel-0.1.8-1 From 9e5091d7a3240c8c58f02c853feee6388d0b1d0d Mon Sep 17 00:00:00 2001 From: Simon South Date: Wed, 28 Oct 2015 20:10:43 -0400 Subject: [PATCH 053/370] Build without linker warnings about missing entry symbols. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * BootRules: Use -Xlinker option correctly to specify entry point. * KernelRules: Build kernel add-ons as shared objects explicitly. Signed-off-by: Jérôme Duval --- build/jam/BootRules | 2 +- build/jam/KernelRules | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/jam/BootRules b/build/jam/BootRules index e66a6f9d0f..63efcc5237 100644 --- a/build/jam/BootRules +++ b/build/jam/BootRules @@ -145,5 +145,5 @@ rule BuildMBR binary : source actions BuildMBR { $(RM) $(1) - $(HAIKU_CC_$(HAIKU_PACKAGING_ARCH)) $(2) -o $(1) $(MBRFLAGS) -nostdlib -Xlinker --oformat=binary -Xlinker -S -Xlinker -N -Xlinker "-e start" -Xlinker "-Ttext=0x600" + $(HAIKU_CC_$(HAIKU_PACKAGING_ARCH)) $(2) -o $(1) $(MBRFLAGS) -nostdlib -Xlinker --oformat=binary -Xlinker -S -Xlinker -N -Xlinker --entry=start -Xlinker -Ttext=0x600 } diff --git a/build/jam/KernelRules b/build/jam/KernelRules index 7fc8b47762..11fda4f6e0 100644 --- a/build/jam/KernelRules +++ b/build/jam/KernelRules @@ -139,7 +139,7 @@ rule KernelAddon # compile and link SetupKernel $(sources) : : false ; - local linkFlags = -nostdlib -Xlinker --no-undefined + local linkFlags = -shared -nostdlib -Xlinker --no-undefined -Xlinker -soname=\"$(target:G=)\" $(TARGET_KERNEL_ADDON_LINKFLAGS) ; LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ] $(linkFlags) ; Main $(target) : $(sources) ; From 736bd376e920195c373def865fcc2bfe682dd939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 30 Oct 2015 01:49:58 +0100 Subject: [PATCH 054/370] configure: remove help text for --remote-user This option got removed in hrev46738. --- configure | 2 -- 1 file changed, 2 deletions(-) diff --git a/configure b/configure index 1bedae3b10..a7549571d1 100755 --- a/configure +++ b/configure @@ -75,8 +75,6 @@ options: on to the make building the build tools. --no-downloads Do not download anything. Useful when trying to bootstrap and build Haiku from source only. - --remote-user Use given username when logging into - git.haiku-os.org (via ssh). --target=TARGET Select build target platform. [default=${TARGET_PLATFORM}] valid targets=r5,bone,dano,haiku From 961fc581b72510cee93b8920e85f7eea3505c46a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 30 Oct 2015 01:51:49 +0100 Subject: [PATCH 055/370] configure: Fix copy-paste from hrev49029 --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index a7549571d1..aa9477d0e8 100755 --- a/configure +++ b/configure @@ -88,7 +88,7 @@ options: ones the secondary architectures. --target-board ARM only: Specify the board to build for. Must be one of beagle,rpi1,rpi2,cubieboard4,verdex,overo. - --update re-runs last configure invocation [cubieboard4must be given + --update re-runs last configure invocation [must be given as first option!] --use-clang Build with host Clang instead of GCC cross compiler From ec54f923efca567e22a4133b718dedfde692e548 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Fri, 30 Oct 2015 10:16:52 +0100 Subject: [PATCH 056/370] Improved description of welcome and userguide packages. --- src/data/package_infos/any/haiku_userguide | 11 +++++++++-- src/data/package_infos/any/haiku_userguide_ca | 14 ++++++++++++-- src/data/package_infos/any/haiku_userguide_de | 14 ++++++++++++-- src/data/package_infos/any/haiku_userguide_en | 9 ++++++++- src/data/package_infos/any/haiku_userguide_es | 14 ++++++++++++-- src/data/package_infos/any/haiku_userguide_fi | 14 ++++++++++++-- src/data/package_infos/any/haiku_userguide_fr | 14 ++++++++++++-- src/data/package_infos/any/haiku_userguide_hu | 14 ++++++++++++-- src/data/package_infos/any/haiku_userguide_it | 14 ++++++++++++-- src/data/package_infos/any/haiku_userguide_jp | 14 ++++++++++++-- src/data/package_infos/any/haiku_userguide_pl | 15 +++++++++++++-- src/data/package_infos/any/haiku_userguide_pt_BR | 14 ++++++++++++-- src/data/package_infos/any/haiku_userguide_pt_PT | 14 ++++++++++++-- src/data/package_infos/any/haiku_userguide_ru | 14 ++++++++++++-- src/data/package_infos/any/haiku_userguide_sk | 14 ++++++++++++-- src/data/package_infos/any/haiku_userguide_sv_SE | 14 ++++++++++++-- src/data/package_infos/any/haiku_userguide_uk | 14 ++++++++++++-- src/data/package_infos/any/haiku_userguide_zh_CN | 14 ++++++++++++-- src/data/package_infos/any/haiku_welcome | 10 ++++++++-- 19 files changed, 218 insertions(+), 37 deletions(-) diff --git a/src/data/package_infos/any/haiku_userguide b/src/data/package_infos/any/haiku_userguide index 965d5c3054..7bf548f9b7 100644 --- a/src/data/package_infos/any/haiku_userguide +++ b/src/data/package_infos/any/haiku_userguide @@ -2,12 +2,19 @@ name haiku_userguide version %HAIKU_VERSION% architecture any summary "The Haiku user documentation" -description "The Haiku user documentation." +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku." packager "The Haiku build system" vendor "Haiku Project" -copyrights "2001-2013 Haiku, Inc. et al" +copyrights "2001-2015 Haiku, Inc. et al" licenses MIT provides { diff --git a/src/data/package_infos/any/haiku_userguide_ca b/src/data/package_infos/any/haiku_userguide_ca index 6d6e4f9462..2f97777559 100644 --- a/src/data/package_infos/any/haiku_userguide_ca +++ b/src/data/package_infos/any/haiku_userguide_ca @@ -1,8 +1,18 @@ name haiku_userguide_ca version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (Catalan translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the Catalan translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_de b/src/data/package_infos/any/haiku_userguide_de index 021dbe3e32..05a1cd7da1 100644 --- a/src/data/package_infos/any/haiku_userguide_de +++ b/src/data/package_infos/any/haiku_userguide_de @@ -1,8 +1,18 @@ name haiku_userguide_de version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (German translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the German translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_en b/src/data/package_infos/any/haiku_userguide_en index f81095dc4b..152e11ec3d 100644 --- a/src/data/package_infos/any/haiku_userguide_en +++ b/src/data/package_infos/any/haiku_userguide_en @@ -2,7 +2,14 @@ name haiku_userguide_en version %HAIKU_VERSION% architecture any summary "The Haiku user documentation" -description "The Haiku user documentation." +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku." packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_es b/src/data/package_infos/any/haiku_userguide_es index ef4b6fb90c..84c970de1d 100644 --- a/src/data/package_infos/any/haiku_userguide_es +++ b/src/data/package_infos/any/haiku_userguide_es @@ -1,8 +1,18 @@ name haiku_userguide_es version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (Spanish translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the Spanish translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_fi b/src/data/package_infos/any/haiku_userguide_fi index 05ddb61c78..f65e38299f 100644 --- a/src/data/package_infos/any/haiku_userguide_fi +++ b/src/data/package_infos/any/haiku_userguide_fi @@ -1,8 +1,18 @@ name haiku_userguide_fi version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (Finnish translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the Finnish translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_fr b/src/data/package_infos/any/haiku_userguide_fr index b88ca68705..5a8bcc3c7b 100644 --- a/src/data/package_infos/any/haiku_userguide_fr +++ b/src/data/package_infos/any/haiku_userguide_fr @@ -1,8 +1,18 @@ name haiku_userguide_fr version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (French translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the French translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_hu b/src/data/package_infos/any/haiku_userguide_hu index e7c3700d93..e7f8b72cc1 100644 --- a/src/data/package_infos/any/haiku_userguide_hu +++ b/src/data/package_infos/any/haiku_userguide_hu @@ -1,8 +1,18 @@ name haiku_userguide_hu version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (Hungarian translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the Hungarian translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_it b/src/data/package_infos/any/haiku_userguide_it index 650467823a..ad15a54f32 100644 --- a/src/data/package_infos/any/haiku_userguide_it +++ b/src/data/package_infos/any/haiku_userguide_it @@ -1,8 +1,18 @@ name haiku_userguide_it version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (Italian translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the Italian translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_jp b/src/data/package_infos/any/haiku_userguide_jp index a70ecc8f9d..6d044b356c 100644 --- a/src/data/package_infos/any/haiku_userguide_jp +++ b/src/data/package_infos/any/haiku_userguide_jp @@ -1,8 +1,18 @@ name haiku_userguide_jp version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (Japanese translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the Japanese translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_pl b/src/data/package_infos/any/haiku_userguide_pl index 5086158c9e..f22308f358 100644 --- a/src/data/package_infos/any/haiku_userguide_pl +++ b/src/data/package_infos/any/haiku_userguide_pl @@ -1,8 +1,19 @@ name haiku_userguide_pl version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (Polish translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the Polish translation of the user guide. Thanks to everyone who \ +contributed!" + packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_pt_BR b/src/data/package_infos/any/haiku_userguide_pt_BR index c3a1aad8b4..c1f5f532e9 100644 --- a/src/data/package_infos/any/haiku_userguide_pt_BR +++ b/src/data/package_infos/any/haiku_userguide_pt_BR @@ -1,8 +1,18 @@ name haiku_userguide_pt_BR version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (Brazilian translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the Brazilian translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_pt_PT b/src/data/package_infos/any/haiku_userguide_pt_PT index b0d0f13728..4f3e927082 100644 --- a/src/data/package_infos/any/haiku_userguide_pt_PT +++ b/src/data/package_infos/any/haiku_userguide_pt_PT @@ -1,8 +1,18 @@ name haiku_userguide_pt_PT version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (Portuguese translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the Portuguese translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_ru b/src/data/package_infos/any/haiku_userguide_ru index 0b44558b9b..5de1aa69e5 100644 --- a/src/data/package_infos/any/haiku_userguide_ru +++ b/src/data/package_infos/any/haiku_userguide_ru @@ -1,8 +1,18 @@ name haiku_userguide_ru version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (Russian translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the Russian translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_sk b/src/data/package_infos/any/haiku_userguide_sk index c46e25c48d..d87afb83cd 100644 --- a/src/data/package_infos/any/haiku_userguide_sk +++ b/src/data/package_infos/any/haiku_userguide_sk @@ -1,8 +1,18 @@ name haiku_userguide_sk version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (Slovak translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the Slovak translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_sv_SE b/src/data/package_infos/any/haiku_userguide_sv_SE index dab24a286b..722f2dd786 100644 --- a/src/data/package_infos/any/haiku_userguide_sv_SE +++ b/src/data/package_infos/any/haiku_userguide_sv_SE @@ -1,8 +1,18 @@ name haiku_userguide_sv_SE version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (Swedish translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the Swedish translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_uk b/src/data/package_infos/any/haiku_userguide_uk index 47a4d1b0a0..dd24e9bdc9 100644 --- a/src/data/package_infos/any/haiku_userguide_uk +++ b/src/data/package_infos/any/haiku_userguide_uk @@ -1,8 +1,18 @@ name haiku_userguide_uk version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (Ukrainian translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the Ukrainian translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_userguide_zh_CN b/src/data/package_infos/any/haiku_userguide_zh_CN index afccdbd7b0..17b59e1879 100644 --- a/src/data/package_infos/any/haiku_userguide_zh_CN +++ b/src/data/package_infos/any/haiku_userguide_zh_CN @@ -1,8 +1,18 @@ name haiku_userguide_zh_CN version %HAIKU_VERSION% architecture any -summary "The Haiku user documentation" -description "The Haiku user documentation." +summary "The Haiku user documentation (Chinese translation)" +description "The user guide describes the Haiku operating system from a \ +user's perspective. +It's recommended reading for people that are new to the system as well as the \ +seasoned Haiku or former BeOS user. It describes the fundamentals of the \ +graphical user interface as well as the special features that are unique to \ +the BeOS/Haiku system. All included applications and preferences are \ +described in detail and tips and little workshops help to work most \ +efficiently under Haiku. + +This is the Chinese translation of the user guide. Thanks to everyone who \ +contributed!" packager "The Haiku build system" vendor "Haiku Project" diff --git a/src/data/package_infos/any/haiku_welcome b/src/data/package_infos/any/haiku_welcome index 97f731fb40..64b1d163ac 100644 --- a/src/data/package_infos/any/haiku_welcome +++ b/src/data/package_infos/any/haiku_welcome @@ -2,12 +2,18 @@ name haiku_welcome version %HAIKU_VERSION% architecture any summary "The Haiku welcome documentation" -description "The Haiku welcome documentation for new users." +description "The Haiku welcome documentation was put together especially \ +for new users. It provides information on how to report bugs and answers the \ +most pressing questions like how to find and install software, how to get in \ +contact and where to find more resources for programmers and endusers online. + +This package includes several translations of the welcome documentation. \ +Thanks to everyone who contributed!" packager "The Haiku build system" vendor "Haiku Project" -copyrights "2001-2013 Haiku, Inc. et al" +copyrights "2001-2015 Haiku, Inc. et al" licenses "MIT" provides { From ef8ce1adf7020944e7f3ec1f1c72a24f34c3bdf4 Mon Sep 17 00:00:00 2001 From: autonielx Date: Sat, 31 Oct 2015 06:30:26 +0100 Subject: [PATCH 057/370] Update translations from Pootle --- .../dnsclient/zh_Hans.catkeys | 10 ++++++++++ .../network_settings/ftpd/zh_Hans.catkeys | 3 +++ .../network_settings/ipv4/zh_Hans.catkeys | 2 ++ .../network_settings/ipv6/zh_Hans.catkeys | 2 ++ .../network_settings/sshd/zh_Hans.catkeys | 3 +++ .../network_settings/telnetd/zh_Hans.catkeys | 3 +++ .../add-ons/translators/gif/zh_Hans.catkeys | 3 ++- .../add-ons/translators/jpeg/zh_Hans.catkeys | 3 ++- .../translators/jpeg2000/zh_Hans.catkeys | 3 ++- .../add-ons/translators/ppm/zh_Hans.catkeys | 4 +++- .../add-ons/translators/psd/zh_Hans.catkeys | 4 +++- .../add-ons/translators/sgi/zh_Hans.catkeys | 4 +++- .../add-ons/translators/tga/zh_Hans.catkeys | 4 +++- .../add-ons/translators/tiff/zh_Hans.catkeys | 3 ++- .../translators/wonderbrush/zh_Hans.catkeys | 3 ++- .../catalogs/apps/aboutsystem/zh_Hans.catkeys | 6 +++++- data/catalogs/apps/bootmanager/ru.catkeys | 2 +- data/catalogs/apps/haikudepot/zh_Hans.catkeys | 5 ++++- data/catalogs/apps/icon-o-matic/fr.catkeys | 6 +++++- data/catalogs/apps/mail/zh_Hans.catkeys | 5 ++++- .../catalogs/apps/mediaplayer/zh_Hans.catkeys | 3 ++- data/catalogs/apps/terminal/zh_Hans.catkeys | 5 ++++- data/catalogs/bin/dstcheck/zh_Hans.catkeys | 3 ++- data/catalogs/kits/tracker/zh_Hans.catkeys | 4 +++- data/catalogs/kits/zh_Hans.catkeys | 3 ++- .../preferences/media/zh_Hans.catkeys | 5 ++++- .../preferences/network/zh_Hans.catkeys | 19 ++++++++++++++++++- .../preferences/printers/zh_Hans.catkeys | 3 ++- .../preferences/screen/zh_Hans.catkeys | 3 ++- 29 files changed, 103 insertions(+), 23 deletions(-) create mode 100644 data/catalogs/add-ons/network_settings/dnsclient/zh_Hans.catkeys create mode 100644 data/catalogs/add-ons/network_settings/ftpd/zh_Hans.catkeys create mode 100644 data/catalogs/add-ons/network_settings/ipv4/zh_Hans.catkeys create mode 100644 data/catalogs/add-ons/network_settings/ipv6/zh_Hans.catkeys create mode 100644 data/catalogs/add-ons/network_settings/sshd/zh_Hans.catkeys create mode 100644 data/catalogs/add-ons/network_settings/telnetd/zh_Hans.catkeys diff --git a/data/catalogs/add-ons/network_settings/dnsclient/zh_Hans.catkeys b/data/catalogs/add-ons/network_settings/dnsclient/zh_Hans.catkeys new file mode 100644 index 0000000000..5edd69b9fd --- /dev/null +++ b/data/catalogs/add-ons/network_settings/dnsclient/zh_Hans.catkeys @@ -0,0 +1,10 @@ +1 english x-vnd.Haiku-DNSClientService 2825577357 +DNS settings DNSClientServiceAddOn DNS 设置 +Move down DNSSettingsView 下移 +DNS settings DNSSettingsView DNS 设置 +Remove DNSSettingsView 移除 +Domain: DNSSettingsView 域名: +Add DNSSettingsView 添加 +Server: DNSSettingsView 服务器: +Move up DNSSettingsView 上移 +Apply DNSSettingsView 应用 diff --git a/data/catalogs/add-ons/network_settings/ftpd/zh_Hans.catkeys b/data/catalogs/add-ons/network_settings/ftpd/zh_Hans.catkeys new file mode 100644 index 0000000000..4352ce882c --- /dev/null +++ b/data/catalogs/add-ons/network_settings/ftpd/zh_Hans.catkeys @@ -0,0 +1,3 @@ +1 english x-vnd.Haiku-FTPService 4086152171 +FTP server FTPServiceAddOn FTP 服务器 +The FTP server allows you to remotely access the files on your machine using the FTP protocol.\n\nPlease note that it is an insecure and unencrypted connection. FTPServiceAddOn FTP 服务器允许您在您的设备上通过 FTP 协议来远程访问文件。\n\n请注意这是一种不安全、未加密的连接。 diff --git a/data/catalogs/add-ons/network_settings/ipv4/zh_Hans.catkeys b/data/catalogs/add-ons/network_settings/ipv4/zh_Hans.catkeys new file mode 100644 index 0000000000..842a222b2a --- /dev/null +++ b/data/catalogs/add-ons/network_settings/ipv4/zh_Hans.catkeys @@ -0,0 +1,2 @@ +1 english x-vnd.Haiku-IPv4Interface 2854844856 +IPv4 IPv4InterfaceAddOn IPv4 diff --git a/data/catalogs/add-ons/network_settings/ipv6/zh_Hans.catkeys b/data/catalogs/add-ons/network_settings/ipv6/zh_Hans.catkeys new file mode 100644 index 0000000000..a11f368a59 --- /dev/null +++ b/data/catalogs/add-ons/network_settings/ipv6/zh_Hans.catkeys @@ -0,0 +1,2 @@ +1 english x-vnd.Haiku-IPv6Interface 1391114020 +IPv6 IPv6InterfaceAddOn IPv6 diff --git a/data/catalogs/add-ons/network_settings/sshd/zh_Hans.catkeys b/data/catalogs/add-ons/network_settings/sshd/zh_Hans.catkeys new file mode 100644 index 0000000000..8f58c33b00 --- /dev/null +++ b/data/catalogs/add-ons/network_settings/sshd/zh_Hans.catkeys @@ -0,0 +1,3 @@ +1 english x-vnd.Haiku-SSHService 770129055 +The SSH server allows you to remotely access your machine with a terminal session, as well as file access using the SCP and SFTP protocols. SSHServiceAddOn SSH 服务器允许您通过终端会话远程访问您的机器,并且可以通过 SCP 及 SFTP 协议来访问文件。 +SSH server SSHServiceAddOn SSH 服务器 diff --git a/data/catalogs/add-ons/network_settings/telnetd/zh_Hans.catkeys b/data/catalogs/add-ons/network_settings/telnetd/zh_Hans.catkeys new file mode 100644 index 0000000000..0f310f74a8 --- /dev/null +++ b/data/catalogs/add-ons/network_settings/telnetd/zh_Hans.catkeys @@ -0,0 +1,3 @@ +1 english x-vnd.Haiku-TelnetService 1209067113 +Telnet server TelnetServiceAddOn Telnet 服务器 +The Telnet server allows you to remotely access your machine with a terminal session using the telnet protocol.\n\nPlease note that it is an insecure and unencrypted connection. TelnetServiceAddOn Telnet 服务器允许您使用终端会话通过 Telnet 协议远程访问您的机器。\n\n请注意这是一种不安全、未加密的连接。 diff --git a/data/catalogs/add-ons/translators/gif/zh_Hans.catkeys b/data/catalogs/add-ons/translators/gif/zh_Hans.catkeys index 83487c04cd..ae46c5c66d 100644 --- a/data/catalogs/add-ons/translators/gif/zh_Hans.catkeys +++ b/data/catalogs/add-ons/translators/gif/zh_Hans.catkeys @@ -1,4 +1,4 @@ -1 english x-vnd.Haiku-GIFTranslator 2626723192 +1 english x-vnd.Haiku-GIFTranslator 2201651797 Websafe GIFView 网络安全色 Write interlaced images GIFView 写入隔行图像 Optimal GIFView 最佳效果 @@ -11,6 +11,7 @@ Palette: GIFView 调色板: GIF image GIFTranslator GIF 图像 Write transparent images GIFView 写入透明图像 GIF images GIFTranslator GIF 图像 +Version %d.%d.%d, %s GIFView 版本 %d.%d.%d %s Use RGB color GIFView 启用 RGB 颜色 Use dithering GIFView 启用抖动 GIF Settings GIFTranslator GIF 设置 diff --git a/data/catalogs/add-ons/translators/jpeg/zh_Hans.catkeys b/data/catalogs/add-ons/translators/jpeg/zh_Hans.catkeys index 4e74b14b44..55e2482c7d 100644 --- a/data/catalogs/add-ons/translators/jpeg/zh_Hans.catkeys +++ b/data/catalogs/add-ons/translators/jpeg/zh_Hans.catkeys @@ -1,4 +1,4 @@ -1 english x-vnd.Haiku-JPEGTranslator 965709535 +1 english x-vnd.Haiku-JPEGTranslator 3788699631 Output quality JPEGTranslator 输出质量 JPEG images JPEGTranslator JPEG 图像 Prevent colors 'washing out' JPEGTranslator 防止颜色 '消退' @@ -15,6 +15,7 @@ Output smoothing strength JPEGTranslator 输出平滑力量 High JPEGTranslator 高 Write JPEGTranslator 写入 Write black-and-white images as RGB24 JPEGTranslator 以 RGB24 写入黑白图像 +Version %d.%d.%d JPEGTranslator 版本 %d.%d.%d Read greyscale images as RGB32 JPEGTranslator 以 RGB32 读取灰度图像 Read JPEGTranslator 读取 JPEG Library Warning: %s\n be_jerror JPEG 二进制警告:%s\n diff --git a/data/catalogs/add-ons/translators/jpeg2000/zh_Hans.catkeys b/data/catalogs/add-ons/translators/jpeg2000/zh_Hans.catkeys index 6e2e56ac81..e015304961 100644 --- a/data/catalogs/add-ons/translators/jpeg2000/zh_Hans.catkeys +++ b/data/catalogs/add-ons/translators/jpeg2000/zh_Hans.catkeys @@ -1,6 +1,7 @@ -1 english x-vnd.Haiku-JPEG2000Translator 547915409 +1 english x-vnd.Haiku-JPEG2000Translator 3265915643 Write JPEG2000Translator 写入 JPEG2000 images JPEG2000Translator JPEG2000 图像 +Version %d.%d.%d JPEG2000Translator 版本 %d.%d.%d Output only codestream (.jpc) JPEG2000Translator 输出仅 (.jpc) Write black-and-white images as RGB24 JPEG2000Translator 以 RGB24 格式写入黑白图像 Output quality JPEG2000Translator 输出质量 diff --git a/data/catalogs/add-ons/translators/ppm/zh_Hans.catkeys b/data/catalogs/add-ons/translators/ppm/zh_Hans.catkeys index 9480f184f1..da58ded200 100644 --- a/data/catalogs/add-ons/translators/ppm/zh_Hans.catkeys +++ b/data/catalogs/add-ons/translators/ppm/zh_Hans.catkeys @@ -1,4 +1,5 @@ -1 english x-vnd.Haiku-PPMTranslator 797856484 +1 english x-vnd.Haiku-PPMTranslator 2233502290 +Version %d.%d.%d, %s PPMTranslator 版本 %d.%d.%d %s PPM Settings PPMMain PPM 设置 Based on PPMTranslator sample code PPMTranslator 基于 PPM转换器 示例代码 OK PPMMain 确定 @@ -8,6 +9,7 @@ PPM image PPMTranslator PPM 图像 RGBA 5:5:5:1 16 bits PPMTranslator RGBA 5:5:5:1 16 bits Be Bitmap Format (PPMTranslator) PPMTranslator Be 位图格式(PPM 转换器) CMYA 8:8:8:8 32 bits PPMTranslator CMYA 8:8:8:8 32 bits +Input color space: PPMTranslator 输入颜色空间: CMYK 8:8:8:8 32 bits PPMTranslator CMYK 8:8:8:8 32 bits PPM image translator PPMTranslator PPM 图像转换器 bits/space PPMTranslator bits/space diff --git a/data/catalogs/add-ons/translators/psd/zh_Hans.catkeys b/data/catalogs/add-ons/translators/psd/zh_Hans.catkeys index 4a5327f396..bc47948b56 100644 --- a/data/catalogs/add-ons/translators/psd/zh_Hans.catkeys +++ b/data/catalogs/add-ons/translators/psd/zh_Hans.catkeys @@ -1,4 +1,4 @@ -1 english x-vnd.Haiku-PSDTranslator 1706619436 +1 english x-vnd.Haiku-PSDTranslator 3654055550 Lab PSDLoader Lab 色彩模式 Uncompressed PSDConfig 未压缩 Indexed PSDLoader 索引色彩模式 @@ -6,8 +6,10 @@ Grayscale PSDLoader 灰度色彩模式 Photoshop image translator PSDConfig Photoshop图像转换器 Photoshop image translator PSDTranslator Photoshop图像转换器 Version %d.%d.%d, %s PSDConfig 版本 %d.%d.%d, %s +Photoshop Document (PSD file) PSDConfig Photoshop文档 (PSD文件) Photoshop image PSDTranslator Photoshop图像 RLE PSDConfig 变长度编码(RLE)压缩 +Photoshop Big Document (PSB file) PSDConfig Photoshop大文档 (PSB文件) RGBA PSDLoader RGBA色彩模式 Photoshop image (%s) PSDTranslator Photoshop图像 (%s) PSDTranslator Settings PSDConfig PSD文件转换器配置 diff --git a/data/catalogs/add-ons/translators/sgi/zh_Hans.catkeys b/data/catalogs/add-ons/translators/sgi/zh_Hans.catkeys index 3e28bc3442..d05a538a49 100644 --- a/data/catalogs/add-ons/translators/sgi/zh_Hans.catkeys +++ b/data/catalogs/add-ons/translators/sgi/zh_Hans.catkeys @@ -1,9 +1,11 @@ -1 english x-vnd.Haiku-SGITranslator 4153400005 +1 english x-vnd.Haiku-SGITranslator 129108011 Use compression: SGIView 使用压缩: SGITranslator Settings SGITranslator SGI转换器设置 None SGIView 无 SGI images SGITranslator SGI 图像 SGI image translator SGITranslator SGI 图像转换器 +\nbased on GIMP SGI plugin v1.5:\n SGIView \n基于 GIMP SGI 插件 v1.5:\n +Version %d.%d.%d, %s SGIView 版本 %d.%d.%d, %s SGI image SGITranslator SGI 图像 RLE SGIView RLE SGI Settings SGIMain SGI 设置 diff --git a/data/catalogs/add-ons/translators/tga/zh_Hans.catkeys b/data/catalogs/add-ons/translators/tga/zh_Hans.catkeys index 68034c83f9..9173d173c0 100644 --- a/data/catalogs/add-ons/translators/tga/zh_Hans.catkeys +++ b/data/catalogs/add-ons/translators/tga/zh_Hans.catkeys @@ -1,4 +1,5 @@ -1 english x-vnd.Haiku-TGATranslator 77519970 +1 english x-vnd.Haiku-TGATranslator 3075011211 +Save with RLE compression TGAView 以 RLE 压缩保存 Targa image (%d bits truecolor) TGATranslator Targa 图像(%d 位真彩) Ignore TGA alpha channel TGAView 忽略 TGA 测试频道 Targa image (%d bits colormap) TGATranslator Targa 图像(%d 位色图) @@ -8,6 +9,7 @@ Targa image (%d bits gray) TGATranslator Targa 图像(%d 位灰度) Written by the Haiku Translation Kit Team TGAView 由 Haiku Translation Kit Team 编写 Targa image (%d bits RLE truecolor) TGATranslator Targa 图像(%d 位 RLE 真彩) TGA images TGATranslator TGA 图像 +Version %d.%d.%d, %s TGAView 版本 %d.%d.%d, %s TGATranslator Settings TGATranslator TGA转换器设置 TGA image translator TGATranslator TGA 图像转换器 Targa image (%d bits RLE gray) TGATranslator Targa 图像(%d 位 RLE 灰度) diff --git a/data/catalogs/add-ons/translators/tiff/zh_Hans.catkeys b/data/catalogs/add-ons/translators/tiff/zh_Hans.catkeys index 4ed46b1442..538e73f324 100644 --- a/data/catalogs/add-ons/translators/tiff/zh_Hans.catkeys +++ b/data/catalogs/add-ons/translators/tiff/zh_Hans.catkeys @@ -1,5 +1,6 @@ -1 english x-vnd.Haiku-TIFFTranslator 40018330 +1 english x-vnd.Haiku-TIFFTranslator 2234713102 LZW TIFFView LZW +Version %d.%d.%d, %s TIFFView 版本 %d.%d.%d, %s identify_tiff_header: couldn't set directory\n TIFFTranslator identify_tiff_header:无法设置目录\n TIFF image TIFFTranslator TIFF 图像 TIFF Library: TIFFView TIFF 库: diff --git a/data/catalogs/add-ons/translators/wonderbrush/zh_Hans.catkeys b/data/catalogs/add-ons/translators/wonderbrush/zh_Hans.catkeys index c7594539db..da4fd0ab74 100644 --- a/data/catalogs/add-ons/translators/wonderbrush/zh_Hans.catkeys +++ b/data/catalogs/add-ons/translators/wonderbrush/zh_Hans.catkeys @@ -1,4 +1,5 @@ -1 english x-vnd.Haiku-WonderBrushTranslator 820358316 +1 english x-vnd.Haiku-WonderBrushTranslator 1289038178 +Version %d.%d.%d, %s WonderBrushView 版本 %d.%d.%d, %s WonderBrush image translator WonderBrushTranslator WonderBrush 图像转换器 WBI Settings WonderBrushTranslator WBI 设置 WBI Settings WonderBrushMain WBI 设置 diff --git a/data/catalogs/apps/aboutsystem/zh_Hans.catkeys b/data/catalogs/apps/aboutsystem/zh_Hans.catkeys index 965210441d..912af0182a 100644 --- a/data/catalogs/apps/aboutsystem/zh_Hans.catkeys +++ b/data/catalogs/apps/aboutsystem/zh_Hans.catkeys @@ -1,12 +1,14 @@ -1 english x-vnd.Haiku-About 1848587744 +1 english x-vnd.Haiku-About 3251436090 Copyright © 1999-2010 by the authors of Gutenprint. All rights reserved. AboutView 版权所有 © 1999-2010 Gutenprint 的所有编写者,保留所有权利。 Copyright © 1996-2002, 2006 David Turner, Robert Wilhelm and Werner Lemberg. AboutView 版权所有 © 1996-2002, 2006 David Turner, Robert Wilhelm and Werner Lemberg. +Past website & marketing:\n AboutView 早先网站及市场:\n Travis Geiselbrecht (and his NewOS kernel)\n AboutView Travis Geiselbrecht(和他的 NewOS 内核)\n Ralink (firmware) AboutWindow Ralink(固件) Copyright © 1996-2005 Julian R Seward. All rights reserved. AboutView 版权所有 © 1996-2005 Julian R Seward,保留所有权利。 %d MiB total AboutView 总计%d MiB Michael Phipps (project founder)\n\n AboutView Michael Phipps (项目创始人)\n\n %d MiB used (%d%%) AboutView 已用 %d MiB (%d%%) +Contains software from the GNU Project, released under the GPL and LGPL licenses:\nGNU C Library, GNU coretools, diffutils, findutils, sharutils, gawk, bison, m4, make, wget, ncurses, termcap, Bourne Again Shell.\nCopyright © The Free Software Foundation. AboutView 基于GPL、LGPL许可证发布的包含在GNU工程的自由软件:\nGNU C Library, GNU coretools, diffutils, findutils, sharutils, gawk, bison, m4, make, wget, ncurses, termcap, Bourne Again Shell.\n版权所有 © 自由软件基金会(The Free Software Foundation)。 AboutSystem System name 关于系统 Copyright © 2003 Peter Hanappe and others. AboutView 版权所有 © 2003 Peter Hanappe 及其他人员。 Copyright © 1994-1997 Mark Kilgard. All rights reserved. AboutView 版权所有 © 1994-1997 Mark Kilgard。保留所有权利。 @@ -58,12 +60,14 @@ Google and their Google Summer of Code and Google Code In programs\n AboutView The Haikuware team and their bounty program\n AboutView Haikuware 组织及其捐赠程序\n Copyright © 1995, 1998-2001 Jef Poskanzer. All rights reserved. AboutView 版权所有 © 1995, 1998-2001 Jef Poskanzer,保留所有权利。 Copyright © 2010-2011 Google Inc. All rights reserved. AboutView 版权所有 © 2010-2011 Google Inc,保留所有权利。 +Website & marketing:\n AboutView 网站及市场:\n About this system AboutWindow 关于系统 Version: AboutView 版本: Copyright © 1994-2008 Xiph.Org. All rights reserved. AboutView 版权所有 © 1994-2008 Xiph.Org,保留所有权利。 Copyright © 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper. AboutView 版权所有 © 1998-2000 Thai Open Source Software Center Ltd 与 Clark Cooper。 Copyright © 2004-2005 Intel Corporation. All rights reserved. AboutView 版权所有 © 2004-2005 Intel Corporation,保留所有权利。 Copyright © 2002-2006 Maxim Shemanarev (McSeem). AboutView 版权所有 © 2002-2006 Maxim Shemanarev(McSeem)。 +Copyright © 2000-2014 Fabrice Bellard, et al. AboutView 版权所有 © 2000-20014 Fabrice Bellard,及其他参与者。 Copyright © 1999-2007 Michael C. Ring. All rights reserved. AboutView 版权所有 © 1999-2007 Michael C. Ring,保留所有权利。 The BeGeistert team\n AboutView BeGeistert 组织\n The University of Auckland and Christof Lutteroth\n\n AboutView 奥克兰大学与 Christof Lutteroth 研究院\n\n diff --git a/data/catalogs/apps/bootmanager/ru.catkeys b/data/catalogs/apps/bootmanager/ru.catkeys index bf1016716a..eb379e21ac 100644 --- a/data/catalogs/apps/bootmanager/ru.catkeys +++ b/data/catalogs/apps/bootmanager/ru.catkeys @@ -47,7 +47,7 @@ Update DrivesPage Button Обновить Please locate the Master Boot Record (MBR) save file to restore from. This is the file that was created when the boot manager was first installed. UninstallPage Пожалуйста, выберите файл, содержащий главную загрузочную запись (MBR) для восстановления. Этот файл был создан при первой установке менеджера загрузки. Drives DrivesPage Title Диски No space available! DrivesPage Cannot install Нет места для MBR! -Never DefaultPartitionPage бесконечно +Never DefaultPartitionPage Бесконечно Partition table not compatible BootManagerController Title Несовместимая таблица разделов Old Master Boot Record saved BootManagerController Title Предыдущая загрузочная запись (MBR) сохранена Old Master Boot Record backup failure BootManagerController Title Предыдущая загрузочная запись (MBR) не сохранена diff --git a/data/catalogs/apps/haikudepot/zh_Hans.catkeys b/data/catalogs/apps/haikudepot/zh_Hans.catkeys index 22da5a7622..e9bde5408f 100644 --- a/data/catalogs/apps/haikudepot/zh_Hans.catkeys +++ b/data/catalogs/apps/haikudepot/zh_Hans.catkeys @@ -1,4 +1,4 @@ -1 english x-vnd.Haiku-HaikuDepot 4261904725 +1 english x-vnd.Haiku-HaikuDepot 2365524674 Name PackageListView 名称 Available packages MainWindow 可用软件包 Open %DeskbarLink% PackageManager 打开 %DeskbarLink% @@ -84,7 +84,9 @@ Productivity Model 生产力 No, quit HaikuDepot App 否,强制退出 HaikuDepot Authentication failed UserLoginWindow 认证失败 Logged in as %User% MainWindow 登录 as %User% +9999.99 KiB PackageListView 9999.99 KiB Language RatePackageWindow 语言 +Size PackageListView 大小 Failed to create or update rating: %s\n RatePackageWindow 无法创建或更新评分: %s\n You need to be logged into an account before you can rate packages. MainWindow 在对软件包进行评级之前,您需要进行账户登录。 It responded with: RatePackageWindow 回复内容为: @@ -135,6 +137,7 @@ Cancel RatePackageWindow 取消 Package action failed PackageInfoView 软件包操作失败 OK UserLoginWindow 确定 Send RatePackageWindow 发送 +- no package size - Category: FilterView 分类: Failed to create account UserLoginWindow 账户创建失败 There are problems with the data you entered:\n\n UserLoginWindow 您所输入的数据存在问题:\n\n diff --git a/data/catalogs/apps/icon-o-matic/fr.catkeys b/data/catalogs/apps/icon-o-matic/fr.catkeys index 59a576a828..b0ee3f4be3 100644 --- a/data/catalogs/apps/icon-o-matic/fr.catkeys +++ b/data/catalogs/apps/icon-o-matic/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.haiku-icon_o_matic 4112423386 +1 french x-vnd.haiku-icon_o_matic 2781670565 Select All Icon-O-Matic-PathManipulator Sélectionner tout Add Style Icon-O-Matic-AddStylesCmd Ajouter un style Color (#%02x%02x%02x) Style name after dropping a color Couleur (#%02x%02x%02x) @@ -109,17 +109,21 @@ Radial Icon-O-Matic-StyleTypes Radial Perspective Icon-O-Matic-TransformersList Perspective Add shape with path & style Icon-O-Matic-Menu-Shape Ajoute une forme avec le chemin & le style Gradient Icon-O-Matic-StyleTypes Dégradé +Min LOD Icon-O-Matic-PropertyNames Niveau de détail minimal BEOS:ICON Attribute Icon-O-Matic-SavePanel Attribut BEOS:ICON Invert selection Icon-O-Matic-Properties Inverser la sélection +Drop shapes Icon-O-Matic-ShapesList Supprimer les formes Export as… Icon-O-Matic-Menu-File Exporter sous… Transformation Transformation Transformation Move Transformers Icon-O-Matic-MoveTransformersCmd Déplacer les transformations Move Styles Icon-O-Matic-MoveStylesCmd Déplacer les styles Reset transformation Icon-O-Matic-StylesList Réinitialiser la transformation +Max LOD Icon-O-Matic-PropertyNames Niveau de détail maximal Flip Icon-O-Matic-PathManipulator Retourner Conic Icon-O-Matic-StyleTypes Conique Split Control Points Icon-O-Matic-SplitPointsCmd Diviser les points de contrôle Save Icon-O-Matic-Menu-Settings Sauvegarder +Add empty Icon-O-Matic-ShapesList Ajouter une forme vide Close Icon-O-Matic-Menu-File Fermer Cancel Icon-O-Matic-ColorPicker Annuler Paste Icon-O-Matic-Properties Coller diff --git a/data/catalogs/apps/mail/zh_Hans.catkeys b/data/catalogs/apps/mail/zh_Hans.catkeys index aa9e58aeaa..2c0498c586 100644 --- a/data/catalogs/apps/mail/zh_Hans.catkeys +++ b/data/catalogs/apps/mail/zh_Hans.catkeys @@ -1,7 +1,8 @@ -1 english x-vnd.Be-MAIL 3209807243 +1 english x-vnd.Be-MAIL 1865394837 View Mail 查看 %d - Date Mail %d - 日期 Attach attributes: Mail 附加属性: +Unknown Mail 未知 Inconsistency occurred in the undo/redo buffer. Mail 缓冲区发生错误,撤销/重复操作无法执行。 An error occurred trying to save the attachment. Mail 出现错误,保存为副件。 Copy to new Mail 转发 @@ -144,7 +145,9 @@ Open attachment Mail 打开附件 sent B_USER_DIRECTORY/mail/sent 已发送 (Date unavailable) Mail (日期不可用) Put your favorite e-mail queries and query templates in this folder. Mail 放置您最喜爱的邮件查询和查询模板到该文件夹。 +Spam Mail 垃圾邮件 Reply Mail 回复 +Encoding Mail 编码 From: Mail 从: Couldn't open this signature. Sorry. Mail 署名无法打开,对不起。 Open draft Mail 打开草稿 diff --git a/data/catalogs/apps/mediaplayer/zh_Hans.catkeys b/data/catalogs/apps/mediaplayer/zh_Hans.catkeys index b8459f7efa..686bafd7a3 100644 --- a/data/catalogs/apps/mediaplayer/zh_Hans.catkeys +++ b/data/catalogs/apps/mediaplayer/zh_Hans.catkeys @@ -1,4 +1,4 @@ -1 english x-vnd.Haiku-MediaPlayer 3890917719 +1 english x-vnd.Haiku-MediaPlayer 2711018042 raw audio MediaPlayer-InfoWin 原生音频 Location MediaPlayer-InfoWin 位置 1.85 : 1 (American) MediaPlayer-Main 1.85 : 1(美式) @@ -120,6 +120,7 @@ raw video MediaPlayer-InfoWin 原生视频 Volume of background clips MediaPlayer-SettingsWindow 视频墙纸体积: Internal error (out of memory). Saving the playlist failed. MediaPlayer-PlaylistWindow 内部错误(内存不足)。保存播放列表失败。 Hide interface MediaPlayer-Main 隐藏界面 +Open clips MediaPlayer-Main 打开片段 Copy Entry MediaPlayer-CopyPLItemsCmd 复制条目 none Subtitles menu 无 Move file to Trash MediaPlayer-PlaylistWindow 移动文件到垃圾箱 diff --git a/data/catalogs/apps/terminal/zh_Hans.catkeys b/data/catalogs/apps/terminal/zh_Hans.catkeys index 972ced31ed..c83b0da53d 100644 --- a/data/catalogs/apps/terminal/zh_Hans.catkeys +++ b/data/catalogs/apps/terminal/zh_Hans.catkeys @@ -1,4 +1,4 @@ -1 english x-vnd.Haiku-Terminal 2696855708 +1 english x-vnd.Haiku-Terminal 2093402207 Not found. Terminal TermWindow 未找到。 Switch Terminals Terminal TermWindow 切换终端 Change directory Terminal TermView 更改目录 @@ -86,10 +86,12 @@ Text encoding Terminal TermWindow 文字编码 size Terminal TermView 大小 Close window Terminal TermWindow 关闭窗口 Copy absolute path Terminal TermView 复制绝对路径 +Save as default Terminal TermWindow 默认保存 Set tab title Terminal TermWindow 设置标签标题 Settings… Terminal TermWindow 设置… Abort Terminal Shell 放弃 Open link Terminal TermView 打开链接 +Solarized Light Terminal colors scheme 浅色的 Solarized Edit Terminal TermWindow 编辑 Color: Terminal AppearancePrefView 颜色: The pattern specifying the window title. The following placeholders\ncan be used:\n Terminal TermWindow 该图案指定了窗口标题。可以使用下述的\n占位符:\n @@ -109,6 +111,7 @@ Find next Terminal TermWindow 查找下一个 Close active tab Terminal TermWindow 关闭活动标签 \t%%\t-\tThe character '%'.\n\t%<\t-\tStarts a section that will only be shown if a placeholder\n\t\t\tafterwards is not empty.\n\t%>\t-\tStarts a section that will only be shown if a placeholder\n\t\t\tbetween a previous %< section and this one is not empty.\n\t%-\t-\tEnds a %< or %> section.\n\nAny non alpha numeric character between '%' and the format letter will insert a space only\nif the placeholder value is not empty. It will add to the %< section. Terminal ToolTips \t%%\t-\t字符 '%' 。\n\t%<\t-\t开始新区块,仅当其后的占位符不为空时显示。\n\t%>\t-\t开始新区块,仅当之前的 %< 和该区块不为空时显示。\n\t%-\t-\t结束一个 %< 或者 %> 区块。\n\n仅当占位符的值不为空时,任何位于 '%' 和格式化字符之间的非字母数字字符都\n将会插入一个空格。它将会添加到 %< 区块。 Paste Terminal TermWindow 粘贴 +Solarized Dark Terminal colors scheme 深色的 Solarized Shell Terminal TermWindow Shell Cancel Terminal TermView 取消 Use default Terminal SetTitleWindow 使用默认 diff --git a/data/catalogs/bin/dstcheck/zh_Hans.catkeys b/data/catalogs/bin/dstcheck/zh_Hans.catkeys index b80b2669b4..f6a0ff5716 100644 --- a/data/catalogs/bin/dstcheck/zh_Hans.catkeys +++ b/data/catalogs/bin/dstcheck/zh_Hans.catkeys @@ -1,4 +1,5 @@ -1 english x-vnd.Haiku-cmd-dstconfig 2690010039 +1 english x-vnd.Haiku-cmd-dstconfig 684321431 Ask me later dstcheck 稍后询问 Manually adjust time… dstcheck 手动调整时间... +Keep this time dstcheck 使用当前时间 Attention!\n\nBecause of the switch from daylight saving time, your computer's clock may be an hour off.\nYour computer thinks it is %current time%.\n\nIs this the correct time? dstcheck 注意!\n\n由于夏令时切换,您的计算机时钟会有一个小时的偏移。\n您的计算机当前时间是 %current time% 。\n\n当前时间是否正确? diff --git a/data/catalogs/kits/tracker/zh_Hans.catkeys b/data/catalogs/kits/tracker/zh_Hans.catkeys index 617a049626..edfc946c49 100644 --- a/data/catalogs/kits/tracker/zh_Hans.catkeys +++ b/data/catalogs/kits/tracker/zh_Hans.catkeys @@ -1,4 +1,4 @@ -1 english x-vnd.Haiku-libtracker 1313160091 +1 english x-vnd.Haiku-libtracker 2004221275 OK WidgetAttributeText 确定 Add-ons FilePanelPriv 附加组件 Mount settings… ContainerWindow 挂载设置... @@ -19,6 +19,7 @@ Modified QueryPoseView 修改 Created ContainerWindow 创建 Error %error loading add-On %name. ContainerWindow 载入附加组件 %name 出错:%error 。 If you %ifYouDoAction the settings folder, %osName may not behave properly!\n\nAre you sure you want to do this? FSUtils 如果您 %ifYouDoAction settings 目录, %osName 可能无法正常工作!\n\n您是否确认执行此操作? +Skip all FSUtils 跳过所有 contains SelectionWindow 包含 Sorry, you can't save things at the root of your system. FilePanelPriv 对不起,您不能够在系统根目录保存内容。 Show shared volumes on Desktop SettingsView 在桌面显示共享卷。 @@ -179,6 +180,7 @@ Error in regular expression:\n\n'%errstring' PoseView 正则表达式错误:\ Mount all MountMenu 挂载所有 calculating… InfoWindow 计算... Mount all disks now AutoMounterSettings 挂载所有磁盘 +Hide dotfiles SettingsView 隐藏 dotfiles Untitled bitmap PoseView 未命名位图 of %items StatusWindow of %items Description: InfoWindow 描述: diff --git a/data/catalogs/kits/zh_Hans.catkeys b/data/catalogs/kits/zh_Hans.catkeys index f7f0acdd74..4749269912 100644 --- a/data/catalogs/kits/zh_Hans.catkeys +++ b/data/catalogs/kits/zh_Hans.catkeys @@ -1,4 +1,4 @@ -1 english x-vnd.Haiku-libbe 436685149 +1 english x-vnd.Haiku-libbe 3337473349 gamma AboutWindow 伽马 beta AboutWindow beta %3.2f GiB StringForSize %3.2f GiB @@ -20,6 +20,7 @@ OK PrintJob 确定 Green: ColorControl 绿色: Version history: AboutWindow 版本历史: Remove replicant Dragger 删除克隆控件 +Select all TextView 全选 OK AboutWindow 确定 OK ZombieReplicantView 确定 Print Server is not responding. PrintJob 打印服务未响应。 diff --git a/data/catalogs/preferences/media/zh_Hans.catkeys b/data/catalogs/preferences/media/zh_Hans.catkeys index 188ffcc6e8..f4d05e28be 100644 --- a/data/catalogs/preferences/media/zh_Hans.catkeys +++ b/data/catalogs/preferences/media/zh_Hans.catkeys @@ -1,6 +1,8 @@ -1 english x-vnd.Haiku-Media 862832618 +1 english x-vnd.Haiku-Media 4205337498 Couldn't add volume control in Deskbar: %s\n Media views 无法添加音量控件到桌面栏:%s\n Video input: Media views 视频输入: +Warning! Media Window 警告! +Quit anyway Media Window 强制退出 Defaults Media views 默认 MIDI Settings Media Window MIDI 设置 Quit Media Window 退出 @@ -10,6 +12,7 @@ Could not connect to the media server.\nWould you like to start it ? Media Windo Restart media services Media views 重启多媒体服务 Couldn't remove volume control in Deskbar: %s\n Media views 无法移除桌面栏中的音量控件:%s\n Media System name 多媒体 +Quitting Media now will stop the restarting of the media services. Flaky or unavailable media functionality is the likely result. Media Window 退出媒体播放器将会中止媒体服务重新启动。将会出现未知情况或者媒体功能不可用。 Audio mixer Media Window 音频混合器 This hardware has no controls. Media Window 硬件控制失败。 Audio output: Media views 音频输出: diff --git a/data/catalogs/preferences/network/zh_Hans.catkeys b/data/catalogs/preferences/network/zh_Hans.catkeys index ebb3b80ed8..c4c0143486 100644 --- a/data/catalogs/preferences/network/zh_Hans.catkeys +++ b/data/catalogs/preferences/network/zh_Hans.catkeys @@ -1,16 +1,33 @@ -1 english x-vnd.Haiku-Network 400858399 +1 english x-vnd.Haiku-Network 950262959 +Static IntefaceAddressView 静态 EAP EAP protected network EAP +Services NetworkWindow 服务 WPA2 WPA2 protected network WPA2 +The netmask defines your local network IntefaceAddressView 子网掩码定义您的本地网络 %name% (%authenticationMode%) WirelessNetworkMenuItem %name% (%authenticationMode%) Network NetworkWindow 网络 Show network status in Deskbar NetworkWindow 在桌面栏显示网络状态 +The method for obtaining an IP address IntefaceAddressView 获取 IP 地址的方式 +Dial Up NetworkWindow 拨号 Apply IntefaceAddressView 应用 Installing NetworkStatus in Deskbar failed: %s NetworkWindow 在桌面栏安装网络状态失败: %s +Disabled IntefaceAddressView 禁用 Ok NetworkWindow 确定 launch error NetworkWindow 启动错误 +Other NetworkWindow 其他 +Automatic IntefaceAddressView 自动 +Gateway: IntefaceAddressView 网关: Revert NetworkWindow 恢复 +Enable ServiceView 启用 +Your gateway to the internet IntefaceAddressView 您的互联网网关 New… NetworkWindow 新建... +DHCP IntefaceAddressView DHCP +Mode: IntefaceAddressView 模式: WPA WPA protected network WPA open Open network 打开 +IP Address: IntefaceAddressView IP 地址: +Netmask: IntefaceAddressView 子网掩码: +Disable ServiceView 禁用 +Your IP address IntefaceAddressView 您的 IP 地址 Manage… NetworkWindow 管理... WEP WEP protected network WEP diff --git a/data/catalogs/preferences/printers/zh_Hans.catkeys b/data/catalogs/preferences/printers/zh_Hans.catkeys index 88af30297f..f261ebf484 100644 --- a/data/catalogs/preferences/printers/zh_Hans.catkeys +++ b/data/catalogs/preferences/printers/zh_Hans.catkeys @@ -1,4 +1,4 @@ -1 english x-vnd.Be-PRNT 200447094 +1 english x-vnd.Be-PRNT 2163275033 Printer: %printer_name%\nDriver: %driver%\n TestPageView 打印机:%printer_name%\n驱动:%driver%\n Waiting JobListView 等待 Print test page PrintersWindow 打印测试页面 @@ -9,6 +9,7 @@ Cancel AddPrinterDialog 取消 Add printer AddPrinterDialog 添加打印机 Green TestPageView 红 Printers PrintersWindow 打印机 +Add… PrintersWindow 添加… Default Printer PrinterListView 默认打印机 Transport: %transport% %transport_address% PrinterListView 传输: %transport% %transport_address% No pending jobs. PrinterListView 无挂起任务。 diff --git a/data/catalogs/preferences/screen/zh_Hans.catkeys b/data/catalogs/preferences/screen/zh_Hans.catkeys index 523c91b3d8..3f05b02f6d 100644 --- a/data/catalogs/preferences/screen/zh_Hans.catkeys +++ b/data/catalogs/preferences/screen/zh_Hans.catkeys @@ -1,4 +1,4 @@ -1 english x-vnd.Haiku-Screen 2339556848 +1 english x-vnd.Haiku-Screen 4090394050 yes Screen 是 Use laptop panel: Screen 使用笔记本面板: 15 bits/pixel, 32768 colors Screen 15 位/像素l,32768 色 @@ -39,6 +39,7 @@ bits/pixel Screen 位/像素 Refresh rate: Screen 刷新频率: Hz Screen Hz Do you wish to keep these settings? Screen 是否保存设置? +Confirm changes Screen 确认修改 Rows: Screen 行: vertically Screen 垂直 Resolution: Screen 分辨率 From 4e9575976ee0a576da04b1c81eda290945baa12a Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Sat, 31 Oct 2015 08:56:38 +0100 Subject: [PATCH 058/370] HaikuWebkit 1.4.13 package. * There is a small API change, and only the x86_gcc2 package was updated. This means the x86 and x86_64 builds are broken until someone updates the packages. * Fix several small bugs, the most important one being that cookies are written to disk again. --- build/jam/repositories/HaikuPorts/x86_gcc2 | 4 ++-- src/apps/webpositive/BrowserWindow.cpp | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/build/jam/repositories/HaikuPorts/x86_gcc2 b/build/jam/repositories/HaikuPorts/x86_gcc2 index 98e692e903..571afa53de 100644 --- a/build/jam/repositories/HaikuPorts/x86_gcc2 +++ b/build/jam/repositories/HaikuPorts/x86_gcc2 @@ -638,8 +638,8 @@ RemotePackageRepository HaikuPorts graphite2_x86_devel-1.2.4-1 guilib_x86-1.2.1-1 guilib_x86_devel-1.2.1-1 - haikuwebkit_x86-1.4.12-1 - haikuwebkit_x86_devel-1.4.12-1 + haikuwebkit_x86-1.4.13-1 + haikuwebkit_x86_devel-1.4.13-1 harfbuzz_x86-0.9.39-1 harfbuzz_x86_devel-0.9.39-1 icu_x86-55.1-1 diff --git a/src/apps/webpositive/BrowserWindow.cpp b/src/apps/webpositive/BrowserWindow.cpp index 23af03740a..d548e524dc 100644 --- a/src/apps/webpositive/BrowserWindow.cpp +++ b/src/apps/webpositive/BrowserWindow.cpp @@ -1336,9 +1336,7 @@ BrowserWindow::CreateNewTab(const BString& _url, bool select, bool applyNewPagePolicy = webView == NULL; // Executed in app thread (new BWebPage needs to be created in app thread). if (webView == NULL) - webView = new BWebView("web view"); - - webView->SetContext(fContext); + webView = new BWebView("web view", fContext); bool isNewWindow = fTabManager->CountTabs() == 0; From 9059d52817b5996a652e506819367a6f87cacf84 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Sat, 31 Oct 2015 13:25:57 +0100 Subject: [PATCH 059/370] HaikuWebkit 1.4.13 package for x86_64 --- build/jam/repositories/HaikuPorts/x86_64 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/jam/repositories/HaikuPorts/x86_64 b/build/jam/repositories/HaikuPorts/x86_64 index 7052fa6fe2..e03cb34d6e 100644 --- a/build/jam/repositories/HaikuPorts/x86_64 +++ b/build/jam/repositories/HaikuPorts/x86_64 @@ -143,8 +143,8 @@ RemotePackageRepository HaikuPorts gutenprint-5.2.10-1 gutenprint_devel-5.2.10-1 gzip-1.6-2 - haikuwebkit-1.4.12-1 - haikuwebkit_devel-1.4.12-1 + haikuwebkit-1.4.13-1 + haikuwebkit_devel-1.4.13-1 handbrake-0.10.1-1 harfbuzz-1.0.5-1 harfbuzz_devel-1.0.5-1 From 5b2d4597124da13349f3a31e883f334d5d67fcf2 Mon Sep 17 00:00:00 2001 From: Yourself Date: Sat, 31 Oct 2015 16:27:48 +0100 Subject: [PATCH 060/370] HaikuWebkit 1.4.13 package for gcc4 --- build/jam/repositories/HaikuPorts/x86 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/jam/repositories/HaikuPorts/x86 b/build/jam/repositories/HaikuPorts/x86 index 1d02227495..71ad86b884 100644 --- a/build/jam/repositories/HaikuPorts/x86 +++ b/build/jam/repositories/HaikuPorts/x86 @@ -127,8 +127,8 @@ RemotePackageRepository HaikuPorts gutenprint-5.2.10-1 gutenprint_devel-5.2.10-1 gzip-1.6-2 - haikuwebkit-1.4.12-1 - haikuwebkit_devel-1.4.12-1 + haikuwebkit-1.4.13-1 + haikuwebkit_devel-1.4.13-1 help2man-1.46.6-1 htmldoc-1.8.27-3 icu-55.1-5 From f2d2a6b51f7e46df5266536beef4b4fbce92e87e Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 31 Oct 2015 16:07:23 +0000 Subject: [PATCH 061/370] Update fifechan package to include non 32 bit screen mode fixes. --- build/jam/repositories/HaikuPorts/x86 | 4 ++-- build/jam/repositories/HaikuPorts/x86_64 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/jam/repositories/HaikuPorts/x86 b/build/jam/repositories/HaikuPorts/x86 index 71ad86b884..01e13a3fc8 100644 --- a/build/jam/repositories/HaikuPorts/x86 +++ b/build/jam/repositories/HaikuPorts/x86 @@ -82,8 +82,8 @@ RemotePackageRepository HaikuPorts expat-2.1.0-1 expat_devel-2.1.0-1 fife-0.4.0~20150801-1 - fifechan-0.1.2-1 - fifechan_devel-0.1.2-1 + fifechan-0.1.2-2 + fifechan_devel-0.1.2-2 file-5.15-1 file_devel-5.15-1 findutils-4.4.2-3 diff --git a/build/jam/repositories/HaikuPorts/x86_64 b/build/jam/repositories/HaikuPorts/x86_64 index e03cb34d6e..691109b1ae 100644 --- a/build/jam/repositories/HaikuPorts/x86_64 +++ b/build/jam/repositories/HaikuPorts/x86_64 @@ -87,8 +87,8 @@ RemotePackageRepository HaikuPorts expat-2.1.0-1 expat_devel-2.1.0-1 fife-0.4.0~20150801-1 - fifechan-0.1.2-1 - fifechan_devel-0.1.2-1 + fifechan-0.1.2-2 + fifechan_devel-0.1.2-2 file-5.25-1 file_devel-5.25-1 findutils-4.4.2-1 From ec4b80371c381528ac439bc7578c72757f25d4c8 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Sat, 31 Oct 2015 17:20:46 +0100 Subject: [PATCH 062/370] Add packages for colormake and python_imaging. --- build/jam/repositories/HaikuPorts/x86_gcc2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/jam/repositories/HaikuPorts/x86_gcc2 b/build/jam/repositories/HaikuPorts/x86_gcc2 index 571afa53de..ecadf162ca 100644 --- a/build/jam/repositories/HaikuPorts/x86_gcc2 +++ b/build/jam/repositories/HaikuPorts/x86_gcc2 @@ -8,6 +8,7 @@ RemotePackageRepository HaikuPorts ca_root_certificates-2014_08_13-1 caladea-20130214-3 carlito-20130920-1 + colormake-0.9.20140503-1 dejavu-2.34-2 docbook_xml_dtd-4.5-2 docbook_xsl_stylesheets-1.78.1-1 @@ -404,6 +405,7 @@ RemotePackageRepository HaikuPorts psqlodbc_devel-09.03.0400-1 python-2.7.9-1 python_dateutil-1.5-2 + python_imaging-1.1.7-1 python_lxml-3.3.5-2 python_mechanize-0.2.5-2 python_requests-2.3.0-2 @@ -1269,6 +1271,7 @@ RemotePackageRepository HaikuPorts psqlodbc python python_dateutil + python_imaging python_lxml python_mechanize python_requests From 896ed702e6c5d5693f91bf1f7b7ae4185a8a9940 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Sat, 31 Oct 2015 17:43:36 +0100 Subject: [PATCH 063/370] Remove HaikuWebkit source package. Having to upload the 650+ MiB source package with every new version is a drag. People interested in the code can get it directly at https://github.com/haiku/webkit/releases --- build/jam/repositories/HaikuPorts/x86 | 2 +- build/jam/repositories/HaikuPorts/x86_64 | 2 +- build/jam/repositories/HaikuPorts/x86_gcc2 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/jam/repositories/HaikuPorts/x86 b/build/jam/repositories/HaikuPorts/x86 index 01e13a3fc8..bf2273df1c 100644 --- a/build/jam/repositories/HaikuPorts/x86 +++ b/build/jam/repositories/HaikuPorts/x86 @@ -461,7 +461,7 @@ RemotePackageRepository HaikuPorts jam jasper jpeg - haikuwebkit +# haikuwebkit help2man keymapswitcher less diff --git a/build/jam/repositories/HaikuPorts/x86_64 b/build/jam/repositories/HaikuPorts/x86_64 index 691109b1ae..75266080a6 100644 --- a/build/jam/repositories/HaikuPorts/x86_64 +++ b/build/jam/repositories/HaikuPorts/x86_64 @@ -444,7 +444,7 @@ RemotePackageRepository HaikuPorts gtk_doc gutenprint gzip - haikuwebkit +# haikuwebkit handbrake harfbuzz htmldoc diff --git a/build/jam/repositories/HaikuPorts/x86_gcc2 b/build/jam/repositories/HaikuPorts/x86_gcc2 index ecadf162ca..8adcca4367 100644 --- a/build/jam/repositories/HaikuPorts/x86_gcc2 +++ b/build/jam/repositories/HaikuPorts/x86_gcc2 @@ -1063,7 +1063,7 @@ RemotePackageRepository HaikuPorts gyp gzip haikuporter - haikuwebkit_x86 +# haikuwebkit_x86 harfbuzz_x86 help2man htmldoc From 2a9ee98bf0749560c9a1a6b11d692a44924a77b6 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Sat, 31 Oct 2015 22:23:18 +0100 Subject: [PATCH 064/370] Add package for scummvm and depdendencies. --- build/jam/repositories/HaikuPorts/x86_gcc2 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build/jam/repositories/HaikuPorts/x86_gcc2 b/build/jam/repositories/HaikuPorts/x86_gcc2 index 8adcca4367..4bc54c2352 100644 --- a/build/jam/repositories/HaikuPorts/x86_gcc2 +++ b/build/jam/repositories/HaikuPorts/x86_gcc2 @@ -718,6 +718,8 @@ RemotePackageRepository HaikuPorts libmodplug_x86_devel-0.8.8.4-2 libmpdclient_x86-2.11_git-1 libmpdclient_x86_devel-2.11_git-1 + libmpeg2_x86-0.5.1-3 + libmpeg2_x86_devel-0.5.1-3 libogg_x86-1.3.0-2 libogg_x86_devel-1.3.0-2 libpaper_x86-1.1.24-1 @@ -849,6 +851,7 @@ RemotePackageRepository HaikuPorts rocksndiamonds_x86-3.3.1.2-2 ruby_x86-2.2.2-1 ruby_x86_devel-2.2.2-1 + scummvm_x86-1.7.0-3 sdcc_x86-3.4.0-1 sdl_gfx_x86-2.0.24-1 sdl_gfx_x86_devel-2.0.24-1 @@ -1136,6 +1139,7 @@ RemotePackageRepository HaikuPorts libmodplug libmpdclient_x86 libmpeg2 + libmpeg2_x86 libogg libpaper libpcap @@ -1299,6 +1303,7 @@ RemotePackageRepository HaikuPorts ruby sawteeth scons + scummvm_x86 sdcc_x86 sdl_gfx sdl_image From 894526b51a3d931c423878fc0eb8da610fa1fb2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 1 Nov 2015 03:05:13 +0100 Subject: [PATCH 065/370] HardwareChecker: try to install the netcat package and do it before trying to use it. --- 3rdparty/mmu_man/scripts/HardwareChecker.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/3rdparty/mmu_man/scripts/HardwareChecker.sh b/3rdparty/mmu_man/scripts/HardwareChecker.sh index 5b7467e112..5034b8c774 100755 --- a/3rdparty/mmu_man/scripts/HardwareChecker.sh +++ b/3rdparty/mmu_man/scripts/HardwareChecker.sh @@ -12,7 +12,7 @@ netcat=netcat report_site=fake.haikuware.com report_cgi=http://haikuware.com/hwreport.php -packages="dmidecode" +packages="dmidecode netcat" do_notify () { @@ -373,12 +373,12 @@ check_all () tf=/tmp/hw_checker_$$.html -do_notify 0.0 "Checking for network..." -detect_network - do_notify 0.0 "Checking for needed packages..." try_install_packages +do_notify 0.0 "Checking for network..." +detect_network + check_all > "$tf" open "$tf" From a02541b9b3d5af7f0e63eb2a6a99b36b8465ceaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 1 Nov 2015 03:08:41 +0100 Subject: [PATCH 066/370] HardwareChecker: of course now netcat is called 'nc' again... --- 3rdparty/mmu_man/scripts/HardwareChecker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/mmu_man/scripts/HardwareChecker.sh b/3rdparty/mmu_man/scripts/HardwareChecker.sh index 5034b8c774..c83783d840 100755 --- a/3rdparty/mmu_man/scripts/HardwareChecker.sh +++ b/3rdparty/mmu_man/scripts/HardwareChecker.sh @@ -9,7 +9,7 @@ # -netcat=netcat +netcat=nc report_site=fake.haikuware.com report_cgi=http://haikuware.com/hwreport.php packages="dmidecode netcat" From 8d314f692b743ab2da953237ebc5d05386bd243f Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Sun, 1 Nov 2015 14:07:42 +0100 Subject: [PATCH 067/370] FireWire: gcc5 compatibility. Fixes #11991. --- src/add-ons/kernel/bus_managers/firewire/fwohci.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/add-ons/kernel/bus_managers/firewire/fwohci.cpp b/src/add-ons/kernel/bus_managers/firewire/fwohci.cpp index e79b1ae84d..8a69683ae8 100644 --- a/src/add-ons/kernel/bus_managers/firewire/fwohci.cpp +++ b/src/add-ons/kernel/bus_managers/firewire/fwohci.cpp @@ -87,7 +87,7 @@ char fwohcicode[32][0x20]={ #define MAX_SPEED 3 extern const char *const linkspeed[]; -uint32_t tagbit[4] = { 1 << 28, 1 << 29, 1 << 30, 1 << 31}; +uint32_t tagbit[4] = { 1u << 28, 1u << 29, 1u << 30, 1u << 31}; static struct tcode_info tinfo[] = { /* hdr_len block flag valid_response */ From 6abbd31061820555a28223756f80122b422ae7a0 Mon Sep 17 00:00:00 2001 From: Simon South Date: Sun, 1 Nov 2015 04:26:22 -0500 Subject: [PATCH 068/370] unittests: Build copied BAppTest files This adds to the "unittests" target a dependency on the "AppTestRunApp3a" (etc.) files meant to be copied as part of the BApplication test suite so they are generated when "jam unittests" is run. * TestsRules: Add "UnitTestDependency" rule. * testapps/Jamfile: Make unit tests depend on copied files. Fixes #12441. Signed-off-by: Adrien Destugues --- build/jam/TestsRules | 10 ++++++++-- src/tests/kits/app/bapplication/testapps/Jamfile | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/build/jam/TestsRules b/build/jam/TestsRules index 68f67eeb6b..fc1c166ccd 100644 --- a/build/jam/TestsRules +++ b/build/jam/TestsRules @@ -1,6 +1,12 @@ # unit test pseudo target NotFile unittests ; +rule UnitTestDependency +{ + Depends unittests : $(1) ; +} + + rule UnitTestLib { # UnitTestLib : : ; @@ -30,7 +36,7 @@ rule UnitTestLib MakeLocate $(lib) : $(TARGET_UNIT_TEST_LIB_DIR) ; SharedLibrary $(lib) : $(sources) : $(libraries) libcppunit.so ; - Depends unittests : $(lib) ; + UnitTestDependency $(lib) ; } @@ -60,7 +66,7 @@ rule UnitTest SimpleTest $(target) : $(sources) : $(libraries) libcppunit.so : $(resources) ; - Depends unittests : $(target) ; + UnitTestDependency $(target) ; } diff --git a/src/tests/kits/app/bapplication/testapps/Jamfile b/src/tests/kits/app/bapplication/testapps/Jamfile index 2f9d3f7be0..fc90743e9a 100644 --- a/src/tests/kits/app/bapplication/testapps/Jamfile +++ b/src/tests/kits/app/bapplication/testapps/Jamfile @@ -42,6 +42,8 @@ rule CopyBAppTestApp File $(target) : $(source) ; MODE on $(target) = $(EXEMODE) ; MimeSet $(target) ; + + UnitTestDependency $(target) ; } # BApplication::BApplication() test apps From 7a05e252c837a987619b184f68ae16c07f12559d Mon Sep 17 00:00:00 2001 From: John Scipione Date: Mon, 2 Nov 2015 15:55:41 -0800 Subject: [PATCH 069/370] configure: Update the case-sensitive FS error text Remove the second line so that it fits in 80 chars and the sentence does not end in a proposition; reads better. --- configure | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/configure b/configure index aa9477d0e8..cab598fe54 100755 --- a/configure +++ b/configure @@ -658,8 +658,7 @@ rmdir haikuCaseTest haikucasetest 2>/dev/null if [ $caseInsensitive != 0 ]; then echo "You need a case-sensitive file-system to build Haiku." if [ $HOST_PLATFORM = "darwin" ]; then - echo "You can create a case-sensitive disk image using Disk Utility and use" - echo "it to store the Haiku sources on." + echo "You can create a case-sensitive disk image using Disk Utility." fi exit 1 fi From 299467d2a31d3d4a92a793914f9b76c10497cce3 Mon Sep 17 00:00:00 2001 From: John Scipione Date: Mon, 2 Nov 2015 15:57:01 -0800 Subject: [PATCH 070/370] configure: remove set -e This was added in hrev47174 but isn't needed. (confirmed with jessicah) the -e flag was causing the script to exit when it encountered an error instead of allowing us to print an error message and exit ourselves. I accidentially tried to compile Haiku on a case-insensitive FS and tripped over this. The configure script should print an error message if you try to configure on a case-insensitive FS once again. --- configure | 3 --- 1 file changed, 3 deletions(-) diff --git a/configure b/configure index cab598fe54..76bd602adb 100755 --- a/configure +++ b/configure @@ -2,9 +2,6 @@ # # configure [ ] -# set flag to exit script when exit command is executed -set -e - # usage # # Prints usage. From f672379ca14c03cc8f4485e0911354ca03489022 Mon Sep 17 00:00:00 2001 From: John Scipione Date: Tue, 3 Nov 2015 11:25:04 -0800 Subject: [PATCH 071/370] Tracker: Redraw info window when file path changes The hard work was already being done, we just had to redraw to get the new path. Fixes #12437 --- src/kits/tracker/InfoWindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kits/tracker/InfoWindow.cpp b/src/kits/tracker/InfoWindow.cpp index 6650cb7894..1a06aaf6de 100644 --- a/src/kits/tracker/InfoWindow.cpp +++ b/src/kits/tracker/InfoWindow.cpp @@ -1123,6 +1123,7 @@ AttributeView::ModelChanged(Model* model, BMessage* message) Window()->SetTitle(title.String()); WidgetAttributeText::AttrAsString(model, &fPathStr, kAttrPath, B_STRING_TYPE, 0, this); + Invalidate(); } break; } From 271f422a922d9127a3de68e9b33ad2911fb9f39e Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Tue, 3 Nov 2015 22:54:31 +0100 Subject: [PATCH 072/370] listsem: Clean up format strings to use format macros. Fixes printing values on x86_64. --- src/bin/listsem.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/bin/listsem.c b/src/bin/listsem.c index d066fcb824..e946f9c7ae 100644 --- a/src/bin/listsem.c +++ b/src/bin/listsem.c @@ -39,14 +39,15 @@ static void print_sem_info(sem_info *info) { - printf("%7ld%31s%7ld\n", info->sem ,info->name , info->count); + printf("%7" B_PRId32 "%31s%7" B_PRId32 "\n", info->sem, info->name, + info->count); } static void print_header(team_info *tinfo) { if (tinfo != NULL) - printf("TEAM %ld (%s):\n", tinfo->team, tinfo->args ); + printf("TEAM %" B_PRId32 " (%s):\n", tinfo->team, tinfo->args); printf(" ID name count\n"); printf("---------------------------------------------\n"); @@ -75,7 +76,9 @@ int main(int argc, char **argv) // show up some stats first... get_system_info(&sysinfo); - printf("sem: total: %5li, used: %5li, left: %5li\n\n", sysinfo.max_sems, sysinfo.used_sems, sysinfo.max_sems - sysinfo.used_sems); + printf("sem: total: %5" B_PRIu32 ", used: %5" B_PRIu32 ", left: %5" B_PRIu32 + "\n\n", sysinfo.max_sems, sysinfo.used_sems, + sysinfo.max_sems - sysinfo.used_sems); if (argc == 1) { while (get_next_team_info( &cookie, &tinfo) == B_OK) @@ -106,7 +109,7 @@ int main(int argc, char **argv) print_header(NULL); print_sem_info(&info); } else - printf("semaphore %ld unknown\n\n", id); + printf("semaphore %" B_PRId32 " unknown\n\n", id); i++; } @@ -116,7 +119,7 @@ int main(int argc, char **argv) if (get_team_info(team, &tinfo) == B_OK) list_sems(&tinfo); else - printf("team %ld unknown\n\n", team); + printf("team %" B_PRId32 " unknown\n\n", team); } } From 1cffe0dc510ff62b37dc009694b256885fdcd6fb Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Tue, 3 Nov 2015 22:59:37 +0100 Subject: [PATCH 073/370] BLocker: Fix recursive count for "unusual" use cases. Since a BLocker can be unlocked from other threads than the one holding the lock, it can also be further unlocked even when already unlocked. This caused the recursive count to become negative. The first lock then needs to reinitialize the count to 1 for the lock balance to work again. Just incrementing the negative recursive count lead to it never counting back down from one to zero in the unlock case, which made the BLocker impossible to unlock. This makes the Haiku BLocker behave exactly like the BeOS one, including the negative recursive count and reinitialization, as evidenced by its debugging features showing the internal counts. Alternatively to reinitializing the recursive count it could be prevented from going below zero in the first place, but I don't see why we should deviate from BeOS there while allowing its awkward unlock behaviour. This makes some more exotic use cases work like the BGLView <-> SDL combination that previously would always just hang. While these abuses should be reviewed/corrected, just hanging the BLocker doesn't seem useful. --- src/kits/support/Locker.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/kits/support/Locker.cpp b/src/kits/support/Locker.cpp index 02a1bd83b5..0d4b672b34 100644 --- a/src/kits/support/Locker.cpp +++ b/src/kits/support/Locker.cpp @@ -279,8 +279,11 @@ BLocker::AcquireLock(bigtime_t timeout, status_t *error) // Set the lock owner to this thread and increment the recursive count // by one. The recursive count is incremented because one more Unlock() // is now required to release the lock (ie, 0 => 1, 1 => 2 etc). - fLockOwner = find_thread(NULL); - fRecursiveCount++; + if (fLockOwner < 0) { + fLockOwner = find_thread(NULL); + fRecursiveCount = 1; + } else + fRecursiveCount++; } if (error != NULL) From 44f5830503f343021ff99ed4554c7e15b968c377 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Wed, 4 Nov 2015 00:07:29 +0100 Subject: [PATCH 074/370] BLocker: Make misuse warning more useful. Also print the locker sem (for manual name lookup) and the involved threads. It was also missing the line terminator which messed up the following output. Also fix a typo in a comment. --- src/kits/support/Locker.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/kits/support/Locker.cpp b/src/kits/support/Locker.cpp index 0d4b672b34..6b42d90a90 100644 --- a/src/kits/support/Locker.cpp +++ b/src/kits/support/Locker.cpp @@ -117,8 +117,12 @@ BLocker::Unlock() // unlock. This is bad practice, but we must allow it for compatibility // reasons. We can at least warn the developer that something is probably // wrong. - if (!IsLocked()) - fprintf(stderr, "Trying to unlock from the wrong thread (#6400)"); + if (!IsLocked()) { + fprintf(stderr, "Unlocking BLocker with sem %" B_PRId32 + " from wrong thread %" B_PRId32 ", current holder %" B_PRId32 + " (see issue #6400).\n", fSemaphoreID, find_thread(NULL), + fLockOwner); + } // Decrement the number of outstanding locks this thread holds // on this BLocker. @@ -135,7 +139,7 @@ BLocker::Unlock() int32 oldBenaphoreCount = atomic_add(&fBenaphoreCount, -1); // If the oldBenaphoreCount is greater than 1, then there is - // at lease one thread waiting for the lock in the case of a + // at least one thread waiting for the lock in the case of a // benaphore. if (oldBenaphoreCount > 1) { // Since there are threads waiting for the lock, it must From 7e45dd105701980bf61ce555029644249689fb49 Mon Sep 17 00:00:00 2001 From: Automatic Committer Date: Thu, 5 Nov 2015 05:20:22 +0100 Subject: [PATCH 075/370] Update pci.ids from pciids.sourceforge.net --- src/data/ids/pci.ids | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/data/ids/pci.ids b/src/data/ids/pci.ids index dab7e3ff84..141d0e2591 100644 --- a/src/data/ids/pci.ids +++ b/src/data/ids/pci.ids @@ -1,8 +1,8 @@ # # List of PCI ID's # -# Version: 2015.10.29 -# Date: 2015-10-29 03:15:02 +# Version: 2015.11.05 +# Date: 2015-11-05 03:15:01 # # Maintained by Albert Pool, Martin Mares, and other volunteers from # the PCI ID Project at http://pci-ids.ucw.cz/. @@ -3961,6 +3961,7 @@ 790f FCH PCI Bridge 7914 FCH USB XHCI Controller 9600 RS780 Host Bridge + 1043 82ee M378A-CM Motherboard 1043 82f1 M3A78-EH Motherboard 9601 RS880 Host Bridge 1019 2120 A785GM-M @@ -5475,7 +5476,6 @@ 6400 MPC190 Security Processor (S1 family, encryption) 6405 MPC184 Security Processor (S1 family) 1058 Electronics & Telecommunications RSH -# Formerly: Teknor Industrial Computers Inc 1059 Kontron 105a Promise Technology, Inc. 0d30 PDC20265 (FastTrak100 Lite/Ultra100) @@ -10583,7 +10583,7 @@ 1043 11f5 A6J-Q008 1043 16d5 U6V/U31J laptop 1043 81aa P5B - 1043 82c6 M3A78-EH Motherboard + 1043 82c6 M3A78 Series Motherboard 1043 83a3 M4A785TD Motherboard 1043 8432 P8P67 and other motherboards 1043 8505 P8 series motherboard @@ -15824,6 +15824,12 @@ 1028 1fbb Express Flash NVMe SM1715 1.6TB SFF 1028 1fbc Express Flash NVMe SM1715 1.6TB AIC a821 NVMe SSD Controller 172X + 1028 1fb7 Express Flash NVMe PM1725 3.2TB SFF + 1028 1fb8 Express Flash NVMe PM1725 3.2TB AIC + 1028 1fb9 Express Flash NVMe PM1725 6.4TB AIC + 1028 1fc1 Express Flash NVMe PM1725 800GB SFF + 1028 1fc2 Express Flash NVMe PM1725 1.6TB SFF + 1028 1fc4 Express Flash NVMe PM1725 1.6TB AIC 144e OLITEC 144f Askey Computer Corp. 1450 Octave Communications Ind. @@ -17080,8 +17086,8 @@ 1320 10bd SURECOM EP-320X-S 100/10M Ethernet PCI Adapter 0891 MTD-8xx 100/10M Ethernet PCI Adapter 1517 ECHOTEK Corp -# nee PEP MODULAR Computers GmbH -1518 Kontron Modular Computers GmbH +# old ID, now 1059 +1518 Kontron 1519 TELEFON AKTIEBOLAGET LM Ericsson 151a Globetek 1002 PCI-1002 @@ -19419,6 +19425,12 @@ 1bb1 6511 Nytro XH6550-2GB DRAM # 8GB variant of Nytro PCIe controller 1bb1 6512 Nytro XH6550-8GB DRAM +# 1.5 TB Nytro PCIe controller + 1bb1 6521 Nytro XP6500-8A1536 1.5TB +# 2TB Nytro PCIe controller + 1bb1 6522 Nytro XP6500-8A2048 +# 4TB Nytro PCIe controller + 1bb1 6523 Nytro XP6500-8A4096 1bb3 Bluecherry 4304 BC-04120A MPEG4 4 port video encoder / decoder 4309 BC-08240A MPEG4 4 port video encoder / decoder @@ -19441,6 +19453,7 @@ 1101 OmniBus II PCIe Multi-Protocol Interface Card 1102 OmniBusBox II Multi-Protocol Interface Core 1103 OmniBus II cPCIe/PXIe Multi-Protocol Interface Card +1bd4 Inspur Electronic Information Industry Co., Ltd. 1bee IXXAT Automation GmbH 0003 CAN-IB200/PCIe 1bf4 VTI Instruments Corporation @@ -21464,6 +21477,7 @@ 1028 1f63 10GbE 2P X520k bNDC 103c 17d2 Ethernet 10Gb 2-port 560M Adapter 103c 18d0 Ethernet 10Gb 2-port 560FLB Adapter + 1059 0111 T4007 10GbE interface 8086 000c Ethernet X520 10GbE Dual Port KX4-KR Mezz 10f9 82599 10 Gigabit Dual Port Network Connection 10fb 82599ES 10-Gigabit SFI/SFP+ Network Connection @@ -21827,6 +21841,9 @@ 8086 0002 Ethernet Server Adapter I210-T1 1536 I210 Gigabit Fiber Network Connection 1537 I210 Gigabit Backplane Connection + 1059 0110 T4005 1GbE interface + 1059 0111 T4007 1GbE interface + 1059 0120 T4008 1GbE interface 1538 I210 Gigabit Network Connection 1539 I211 Gigabit Network Connection 153a Ethernet Connection I217-LM @@ -21860,6 +21877,8 @@ 1563 Ethernet Controller 10G X550T 8086 0001 Ethernet Converged Network Adapter X550-T2 8086 001a Ethernet Converged Network Adapter X550-T2 + 156c DSL5520 Thunderbolt [Falcon Ridge] + 156d DSL5520 Thunderbolt [Falcon Ridge] 156f Ethernet Connection I219-LM 1570 Ethernet Connection I219-V 1571 XL710/X710 Virtual Function @@ -21937,6 +21956,7 @@ 15a5 Ethernet Switch FM10000 Host Virtual Interface 15a8 Ethernet Connection X552 Virtual Function 15aa Ethernet Connection X552 10 GbE Backplane + 1059 0120 T4008 10GbE interface 15ab Ethernet Connection X552 10 GbE Backplane 15ac Ethernet Connection X552 10 GbE SFP+ 15ad Ethernet Connection X552/X557-AT 10GBASE-T From 3282b758b0b9c0f46959b51efbc1f39f47138105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 4 Nov 2015 21:25:08 +0100 Subject: [PATCH 076/370] launch_daemon: Add API to get information on jobs. * Ie. a listing of all targets/jobs, as well as specific (basic) info on each. * Also added a bit of optional debug output. * Moved translating the path to launch time -- we should take the job's environment into account here at some point. --- headers/private/app/LaunchDaemonDefs.h | 4 + headers/private/app/LaunchRoster.h | 7 ++ src/kits/app/LaunchRoster.cpp | 88 +++++++++++++ src/servers/launch/Job.cpp | 8 +- src/servers/launch/LaunchDaemon.cpp | 167 +++++++++++++++++++++++-- 5 files changed, 262 insertions(+), 12 deletions(-) diff --git a/headers/private/app/LaunchDaemonDefs.h b/headers/private/app/LaunchDaemonDefs.h index f0452847c5..ba791aa7ab 100644 --- a/headers/private/app/LaunchDaemonDefs.h +++ b/headers/private/app/LaunchDaemonDefs.h @@ -32,6 +32,10 @@ enum { B_UNREGISTER_LAUNCH_EVENT = 'lnue', B_NOTIFY_LAUNCH_EVENT = 'lnne', B_RESET_STICKY_LAUNCH_EVENT = 'lnRe', + B_GET_LAUNCH_TARGETS = 'lngt', + B_GET_LAUNCH_JOBS = 'lngj', + B_GET_LAUNCH_TARGET_INFO = 'lntI', + B_GET_LAUNCH_JOB_INFO = 'lnjI', }; diff --git a/headers/private/app/LaunchRoster.h b/headers/private/app/LaunchRoster.h index 970b3120aa..785fe0a846 100644 --- a/headers/private/app/LaunchRoster.h +++ b/headers/private/app/LaunchRoster.h @@ -45,6 +45,11 @@ public: status_t ResetStickyEvent(const BMessenger& source, const char* name); + status_t GetTargets(BStringList& targets); + status_t GetTargetInfo(const char* name, BMessage& info); + status_t GetJobs(const char* target, BStringList& jobs); + status_t GetJobInfo(const char* name, BMessage& info); + class Private; private: @@ -54,6 +59,8 @@ private: status_t _UpdateEvent(uint32 what, const BMessenger& source, const char* name, uint32 flags = 0); + status_t _GetInfo(uint32 what, const char* name, + BMessage& info); private: BMessenger fMessenger; diff --git a/src/kits/app/LaunchRoster.cpp b/src/kits/app/LaunchRoster.cpp index eec0128555..1290b28190 100644 --- a/src/kits/app/LaunchRoster.cpp +++ b/src/kits/app/LaunchRoster.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -234,6 +235,68 @@ BLaunchRoster::ResetStickyEvent(const BMessenger& source, const char* name) } +status_t +BLaunchRoster::GetTargets(BStringList& targets) +{ + BMessage request(B_GET_LAUNCH_TARGETS); + status_t status = request.AddInt32("user", getuid()); + if (status != B_OK) + return status; + + // send the request + BMessage result; + status = fMessenger.SendMessage(&request, &result); + + // evaluate the reply + if (status == B_OK) + status = result.what; + + if (status == B_OK) + status = result.FindStrings("target", &targets); + + return status; +} + + +status_t +BLaunchRoster::GetTargetInfo(const char* name, BMessage& info) +{ + return _GetInfo(B_GET_LAUNCH_TARGET_INFO, name, info); +} + + +status_t +BLaunchRoster::GetJobs(const char* target, BStringList& jobs) +{ + BMessage request(B_GET_LAUNCH_JOBS); + status_t status = request.AddInt32("user", getuid()); + if (status == B_OK && target != NULL) + status = request.AddString("target", target); + if (status != B_OK) + return status; + + // send the request + BMessage result; + status = fMessenger.SendMessage(&request, &result); + + // evaluate the reply + if (status == B_OK) + status = result.what; + + if (status == B_OK) + status = result.FindStrings("job", &jobs); + + return status; +} + + +status_t +BLaunchRoster::GetJobInfo(const char* name, BMessage& info) +{ + return _GetInfo(B_GET_LAUNCH_JOB_INFO, name, info); +} + + void BLaunchRoster::_InitMessenger() { @@ -277,3 +340,28 @@ BLaunchRoster::_UpdateEvent(uint32 what, const BMessenger& source, return status; } + + +status_t +BLaunchRoster::_GetInfo(uint32 what, const char* name, BMessage& info) +{ + if (name == NULL || name[0] == '\0') + return B_BAD_VALUE; + + BMessage request(what); + status_t status = request.AddInt32("user", getuid()); + if (status == B_OK) + status = request.AddString("name", name); + if (status != B_OK) + return status; + + // send the request + BMessage result; + status = fMessenger.SendMessage(&request, &info); + + // evaluate the reply + if (status == B_OK) + status = result.what; + + return status; +} diff --git a/src/servers/launch/Job.cpp b/src/servers/launch/Job.cpp index d34b3f5e3c..d7858116be 100644 --- a/src/servers/launch/Job.cpp +++ b/src/servers/launch/Job.cpp @@ -17,6 +17,7 @@ #include #include "Target.h" +#include "Utility.h" Job::Job(const char* name) @@ -314,18 +315,21 @@ Job::Launch() // Build argument vector entry_ref ref; - status_t status = get_ref_for_path(fArguments.StringAt(0).String(), &ref); + status_t status = get_ref_for_path( + Utility::TranslatePath(fArguments.StringAt(0).String()), &ref); if (status != B_OK) { _SetLaunchStatus(status); return status; } + std::vector strings; std::vector args; size_t count = fArguments.CountStrings() - 1; if (count > 0) { for (int32 i = 1; i < fArguments.CountStrings(); i++) { - args.push_back(fArguments.StringAt(i)); + strings.push_back(Utility::TranslatePath(fArguments.StringAt(i))); + args.push_back(strings.back()); } args.push_back(NULL); } diff --git a/src/servers/launch/LaunchDaemon.cpp b/src/servers/launch/LaunchDaemon.cpp index 71f46189d7..5caf90fd5c 100644 --- a/src/servers/launch/LaunchDaemon.cpp +++ b/src/servers/launch/LaunchDaemon.cpp @@ -44,6 +44,13 @@ #include "Worker.h" +#ifdef DEBUG +# define TRACE(x, ...) debug_printf(x, __VA_ARGS__) +#else +# define TRACE(x, ...) ; +#endif + + using namespace ::BPrivate; using namespace BSupportKit; using BSupportKit::BPrivate::JobQueue; @@ -180,6 +187,8 @@ private: ExternalEventSource* event, const BString& name); void _ResolveExternalEvents(BaseJob* job); + void _GetTargetInfo(Target* target, BMessage& info); + void _GetJobInfo(Job* job, BMessage& info); void _ForwardEventMessage(uid_t user, BMessage* message); @@ -468,6 +477,125 @@ LaunchDaemon::MessageReceived(BMessage* message) _HandleResetStickyLaunchEvent(message); break; + case B_GET_LAUNCH_TARGETS: + { + uid_t user = _GetUserID(message); + if (user < 0) + return; + + BMessage reply; + status_t status = B_OK; + + if (!fUserMode) { + // Request the data from the user's daemon, too + Session* session = FindSession(user); + if (session != NULL) { + BMessage request(B_GET_LAUNCH_TARGETS); + status = request.AddInt32("user", 0); + if (status == B_OK) { + status = session->Daemon().SendMessage(&request, + &reply); + } + if (status == B_OK) + status = reply.what; + } else + status = B_NAME_NOT_FOUND; + } + + if (status == B_OK) { + TargetMap::const_iterator iterator = fTargets.begin(); + for (; iterator != fTargets.end(); iterator++) + reply.AddString("target", iterator->first); + } + + reply.what = status; + message->SendReply(&reply); + break; + } + case B_GET_LAUNCH_TARGET_INFO: + { + uid_t user = _GetUserID(message); + if (user < 0) + return; + + const char* name = message->GetString("name"); + Target* target = FindTarget(name); + if (target == NULL && !fUserMode) { + _ForwardEventMessage(user, message); + break; + } + + BMessage reply(uint32(target != NULL ? B_OK : B_NAME_NOT_FOUND)); + if (target != NULL) + _GetTargetInfo(target, reply); + message->SendReply(&reply); + break; + } + case B_GET_LAUNCH_JOBS: + { + uid_t user = _GetUserID(message); + if (user < 0) + return; + + const char* targetName = message->GetString("target"); + + BMessage reply; + status_t status = B_OK; + + if (!fUserMode) { + // Request the data from the user's daemon, too + Session* session = FindSession(user); + if (session != NULL) { + BMessage request(B_GET_LAUNCH_JOBS); + status = request.AddInt32("user", 0); + if (status == B_OK && targetName != NULL) + status = request.AddString("target", targetName); + if (status == B_OK) { + status = session->Daemon().SendMessage(&request, + &reply); + } + if (status == B_OK) + status = reply.what; + } else + status = B_NAME_NOT_FOUND; + } + + if (status == B_OK) { + JobMap::const_iterator iterator = fJobs.begin(); + for (; iterator != fJobs.end(); iterator++) { + Job* job = iterator->second; + if (targetName != NULL && (job->Target() == NULL + || job->Target()->Title() != targetName)) { + continue; + } + reply.AddString("job", iterator->first); + } + } + + reply.what = status; + message->SendReply(&reply); + break; + } + case B_GET_LAUNCH_JOB_INFO: + { + uid_t user = _GetUserID(message); + if (user < 0) + return; + + const char* name = message->GetString("name"); + Job* job = FindJob(name); + if (job == NULL && !fUserMode) { + _ForwardEventMessage(user, message); + break; + } + + BMessage reply(uint32(job != NULL ? B_OK : B_NAME_NOT_FOUND)); + if (job != NULL) + _GetJobInfo(job, reply); + message->SendReply(&reply); + break; + } + case kMsgEventTriggered: { // An internal event has been triggered. @@ -854,6 +982,7 @@ LaunchDaemon::_ReadFile(const char* context, BEntry& entry) BMessage message; status = parser.ParseFile(path.Path(), message); if (status == B_OK) { + TRACE("launch_daemon: read file %s\n", path.Path()); _AddJobs(NULL, message); _AddTargets(message); _AddRunTargets(message); @@ -977,6 +1106,8 @@ LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message) Job* job = FindJob(name); if (job == NULL) { + TRACE(" add job \"%s\"\n", name.String()); + job = new (std::nothrow) Job(name); if (job == NULL) return; @@ -984,7 +1115,8 @@ LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message) job->SetService(service); job->SetCreateDefaultPort(service); job->SetTarget(target); - } + } else + TRACE(" amend job \"%s\"\n", name.String()); if (message.HasBool("disabled")) job->SetEnabled(!message.GetBool("disabled", !job->IsEnabled())); @@ -1002,15 +1134,8 @@ LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message) job->AddPort(portMessage); } - if (message.HasString("launch")) { - job->Arguments().MakeEmpty(); - - const char* argument; - for (int32 index = 0; message.FindString("launch", index, &argument) - == B_OK; index++) { - job->AddArgument(Utility::TranslatePath(argument)); - } - } + if (message.HasString("launch")) + message.FindStrings("launch", &job->Arguments()); const char* requirement; for (int32 index = 0; @@ -1182,6 +1307,7 @@ LaunchDaemon::_SetEvent(BaseJob* job, const BMessage& message) } if (updated) { + TRACE(" event: %s\n", event->ToString().String()); job->SetEvent(event); _ResolveExternalEvents(job); } @@ -1253,6 +1379,27 @@ LaunchDaemon::_ResolveExternalEvents(BaseJob* job) } +void +LaunchDaemon::_GetTargetInfo(Target* target, BMessage& info) +{ + info.SetString("name", target->Name()); +} + + +void +LaunchDaemon::_GetJobInfo(Job* job, BMessage& info) +{ + info.SetString("name", job->Name()); + info.SetInt32("team", job->Team()); + info.SetBool("running", job->IsRunning()); + info.SetBool("launched", job->IsLaunched()); + + PortMap::const_iterator iterator = job->Ports().begin(); + for (; iterator != job->Ports().end(); iterator++) + info.AddMessage("port", &iterator->second); +} + + void LaunchDaemon::_ForwardEventMessage(uid_t user, BMessage* message) { From c2f71fa688916bfdb9beab7b80f7f14b871753da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 5 Nov 2015 19:58:19 +0100 Subject: [PATCH 077/370] launch_daemon: give the main worker thread a different name. * It's now called "main worker" instead of just worker. --- src/servers/launch/Worker.cpp | 16 +++++++++++++++- src/servers/launch/Worker.h | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/servers/launch/Worker.cpp b/src/servers/launch/Worker.cpp index 1d2fc86a91..f7797d4d86 100644 --- a/src/servers/launch/Worker.cpp +++ b/src/servers/launch/Worker.cpp @@ -31,7 +31,7 @@ Worker::~Worker() status_t Worker::Init() { - fThread = spawn_thread(&Worker::_Process, "worker", B_NORMAL_PRIORITY, + fThread = spawn_thread(&Worker::_Process, Name(), B_NORMAL_PRIORITY, this); if (fThread < 0) return fThread; @@ -70,6 +70,13 @@ Worker::Timeout() const } +const char* +Worker::Name() const +{ + return "worker"; +} + + status_t Worker::Run(BJob* job) { @@ -110,6 +117,13 @@ MainWorker::Timeout() const } +const char* +MainWorker::Name() const +{ + return "main worker"; +} + + status_t MainWorker::Run(BJob* job) { diff --git a/src/servers/launch/Worker.h b/src/servers/launch/Worker.h index 636ad4bee9..0b2aa52d02 100644 --- a/src/servers/launch/Worker.h +++ b/src/servers/launch/Worker.h @@ -24,6 +24,7 @@ public: protected: virtual status_t Process(); virtual bigtime_t Timeout() const; + virtual const char* Name() const; virtual status_t Run(BJob* job); private: @@ -41,6 +42,7 @@ public: protected: virtual bigtime_t Timeout() const; + virtual const char* Name() const; virtual status_t Run(BJob* job); private: From d8c0972a8173469cd574d657070ec6549ba587a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 6 Nov 2015 18:13:31 +0100 Subject: [PATCH 078/370] launch_daemon: Added "setting" condition. * Moved the mail_daemon to the user startup, and start it only if enabled in the settings. --- data/launch/system | 6 --- data/launch/user | 7 +++ src/servers/launch/Conditions.cpp | 82 +++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 6 deletions(-) diff --git a/data/launch/system b/data/launch/system index 9d834979dc..0b762be16e 100644 --- a/data/launch/system +++ b/data/launch/system @@ -43,12 +43,6 @@ service x-vnd.Haiku-midi_server { on_demand } -service x-vnd.Haiku-mail_daemon { - launch /system/servers/mail_daemon -E - no_safemode - legacy -} - service x-vnd.Haiku-net_server { launch /system/servers/net_server no_safemode diff --git a/data/launch/user b/data/launch/user index 023fed38fa..c53d9a5074 100644 --- a/data/launch/user +++ b/data/launch/user @@ -16,6 +16,13 @@ target desktop { } } + service x-vnd.Haiku-mail_daemon { + launch /system/servers/mail_daemon -E + if setting ~/config/settings/Mail/new_mail_daemon DaemonAutoStarts + no_safemode + legacy + } + job user-bootscript { launch /bin/sh ~/config/settings/boot/UserBootscript } diff --git a/src/servers/launch/Conditions.cpp b/src/servers/launch/Conditions.cpp index 66816197ca..e879d06c11 100644 --- a/src/servers/launch/Conditions.cpp +++ b/src/servers/launch/Conditions.cpp @@ -9,8 +9,10 @@ #include #include +#include #include #include +#include #include #include "NetworkWatcher.h" @@ -112,6 +114,21 @@ public: }; +class SettingCondition : public Condition { +public: + SettingCondition(const BMessage& args); + + virtual bool Test(ConditionContext& context) const; + + virtual BString ToString() const; + +private: + BPath fPath; + BString fField; + BString fValue; +}; + + static Condition* create_condition(const char* name, const BMessage& args) { @@ -130,6 +147,8 @@ create_condition(const char* name, const BMessage& args) return new FileExistsCondition(args); if (strcmp(name, "network_available") == 0) return new NetworkAvailableCondition(); + if (strcmp(name, "setting") == 0) + return new SettingCondition(args); return NULL; } @@ -481,6 +500,69 @@ NetworkAvailableCondition::ToString() const } +// #pragma mark - setting + + +SettingCondition::SettingCondition(const BMessage& args) +{ + fPath.SetTo(Utility::TranslatePath(args.GetString("args", 0, NULL))); + fField = args.GetString("args", 1, NULL); + fValue = args.GetString("args", 2, NULL); +} + + +bool +SettingCondition::Test(ConditionContext& context) const +{ + BFile file(fPath.Path(), B_READ_ONLY); + if (file.InitCheck() != B_OK) + return false; + + BMessage settings; + if (settings.Unflatten(&file) == B_OK) { + type_code type; + int32 count; + if (settings.GetInfo(fField, &type, &count) == B_OK) { + switch (type) { + case B_BOOL_TYPE: + { + bool value = settings.GetBool(fField); + bool expect = fValue.IsEmpty(); + if (!expect) { + expect = fValue == "true" || fValue == "yes" + || fValue == "on" || fValue == "1"; + } + return value == expect; + } + case B_STRING_TYPE: + { + BString value = settings.GetString(fField); + if (fValue.IsEmpty() && !value.IsEmpty()) + return true; + + return fValue == value; + } + } + } + } + // TODO: check for driver settings, too? + + return false; +} + + +BString +SettingCondition::ToString() const +{ + BString string = "setting file "; + string << fPath.Path() << ", field " << fField; + if (!fValue.IsEmpty()) + string << ", value " << fValue; + + return string; +} + + // #pragma mark - From e2f83cbd6b2a52abb62fef4407c2a97023055648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 6 Nov 2015 22:40:04 +0100 Subject: [PATCH 079/370] launch_daemon: Monitor teams, and restart services. * Services that end are now automatically restarted. * However, this is very basic at the moment, there is no throttling, and no support for shutting down the system. --- src/servers/launch/Job.cpp | 43 +++++++++++++++++-- src/servers/launch/Job.h | 14 +++++++ src/servers/launch/LaunchDaemon.cpp | 65 +++++++++++++++++++++++++++-- 3 files changed, 115 insertions(+), 7 deletions(-) diff --git a/src/servers/launch/Job.cpp b/src/servers/launch/Job.cpp index d7858116be..5cdeeab428 100644 --- a/src/servers/launch/Job.cpp +++ b/src/servers/launch/Job.cpp @@ -81,6 +81,20 @@ Job::~Job() } +::TeamRegistrator* +Job::TeamRegistrator() const +{ + return fTeamRegistrator; +} + + +void +Job::SetTeamRegistrator(::TeamRegistrator* registrator) +{ + fTeamRegistrator = registrator; +} + + bool Job::IsEnabled() const { @@ -349,8 +363,24 @@ Job::IsLaunched() const bool Job::IsRunning() const { - // TODO: monitor team status; should jobs be allowed to run multiple times? - return State() == B_JOB_STATE_SUCCEEDED && IsLaunched() && IsService(); + return fTeam >= 0; +} + + +void +Job::TeamDeleted() +{ + fTeam = -1; + if (IsService()) + SetState(B_JOB_STATE_WAITING_TO_RUN); +} + + +bool +Job::CanBeLaunched() const +{ + // Services cannot be launched while they are running + return !IsLaunching() && (!IsService() || !IsRunning()); } @@ -384,7 +414,7 @@ Job::Run() { status_t status = BJob::Run(); - // TODO: monitor team, don't just do this + // Jobs can be relaunched at any time if (!IsService()) SetState(B_JOB_STATE_WAITING_TO_RUN); @@ -396,8 +426,10 @@ status_t Job::Execute() { status_t status = B_OK; - if (!IsLaunched() || !IsService()) + if (!IsRunning() || !IsService()) status = Launch(); + else + debug_printf("Ignore launching %s\n", Name()); fLaunching = false; return status; @@ -460,6 +492,9 @@ Job::_SetLaunchStatus(status_t launchStatus) fLaunchStatus = launchStatus != B_NO_INIT ? launchStatus : B_ERROR; launchLocker.Unlock(); + if (fTeamRegistrator != NULL) + fTeamRegistrator->RegisterTeam(this); + _SendPendingLaunchDataReplies(); } diff --git a/src/servers/launch/Job.h b/src/servers/launch/Job.h index 73d1ce19b2..b18dbd1099 100644 --- a/src/servers/launch/Job.h +++ b/src/servers/launch/Job.h @@ -22,6 +22,7 @@ using namespace BSupportKit; class BMessage; class Finder; +class Job; class Target; struct entry_ref; @@ -30,12 +31,22 @@ struct entry_ref; typedef std::map PortMap; +class TeamRegistrator { +public: + virtual void RegisterTeam(Job* job) = 0; +}; + + class Job : public BaseJob { public: Job(const char* name); Job(const Job& other); virtual ~Job(); + ::TeamRegistrator* TeamRegistrator() const; + void SetTeamRegistrator( + ::TeamRegistrator* registrator); + bool IsEnabled() const; void SetEnabled(bool enable); @@ -72,6 +83,8 @@ public: status_t Launch(); bool IsLaunched() const; bool IsRunning() const; + void TeamDeleted(); + bool CanBeLaunched() const; bool IsLaunching() const; void SetLaunching(bool launching); @@ -117,6 +130,7 @@ private: ::Condition* fCondition; BObjectList fPendingLaunchDataReplies; + ::TeamRegistrator* fTeamRegistrator; }; diff --git a/src/servers/launch/LaunchDaemon.cpp b/src/servers/launch/LaunchDaemon.cpp index 5caf90fd5c..3ac3c62713 100644 --- a/src/servers/launch/LaunchDaemon.cpp +++ b/src/servers/launch/LaunchDaemon.cpp @@ -27,8 +27,11 @@ #include #include #include +#include +#include #include #include +#include #include "multiuser_utils.h" @@ -116,10 +119,11 @@ typedef std::map JobMap; typedef std::map SessionMap; typedef std::map TargetMap; typedef std::map EventMap; +typedef std::map TeamMap; class LaunchDaemon : public BServer, public Finder, public ConditionContext, - public EventRegistrator { + public EventRegistrator, public TeamRegistrator { public: LaunchDaemon(bool userMode, const EventMap& events, status_t& error); @@ -140,6 +144,9 @@ public: virtual void UnregisterExternalEvent(Event* event, const char* name); + // TeamRegistrator + virtual void RegisterTeam(Job* job); + virtual void ReadyToRun(); virtual void MessageReceived(BMessage* message); @@ -208,6 +215,8 @@ private: SessionMap fSessions; MainWorker* fMainWorker; Target* fInitTarget; + TeamMap fTeams; + mutex fTeamsLock; bool fSafeMode; bool fReadOnlyBootVolume; bool fUserMode; @@ -305,6 +314,8 @@ LaunchDaemon::LaunchDaemon(bool userMode, const EventMap& events, fInitTarget(userMode ? NULL : new Target("init")), fUserMode(userMode) { + mutex_init(&fTeamsLock, "teams lock"); + fMainWorker = new MainWorker(fJobQueue); fMainWorker->Init(); @@ -391,6 +402,14 @@ LaunchDaemon::UnregisterExternalEvent(Event* event, const char* name) } +void +LaunchDaemon::RegisterTeam(Job* job) +{ + MutexLocker locker(fTeamsLock); + fTeams.insert(std::make_pair(job->Team(), job)); +} + + void LaunchDaemon::ReadyToRun() { @@ -429,6 +448,12 @@ LaunchDaemon::ReadyToRun() fUserMode ? B_FIND_PATHS_USER_ONLY : B_FIND_PATHS_SYSTEM_ONLY, paths); _ReadPaths(paths); + BMessenger target(this); + BMessenger::Private messengerPrivate(target); + port_id port = messengerPrivate.Port(); + int32 token = messengerPrivate.Token(); + __start_watching_system(-1, B_WATCH_SYSTEM_TEAM_DELETION, port, token); + _InitJobs(NULL); _LaunchJobs(NULL); @@ -445,6 +470,30 @@ void LaunchDaemon::MessageReceived(BMessage* message) { switch (message->what) { + case B_SYSTEM_OBJECT_UPDATE: + { + int32 opcode = message->GetInt32("opcode", 0); + team_id team = (team_id)message->GetInt32("team", -1); + if (opcode != B_TEAM_DELETED || team < 0) + break; + + MutexLocker locker(fTeamsLock); + + TeamMap::iterator found = fTeams.find(team); + if (found != fTeams.end()) { + Job* job = found->second; + TRACE("Job %s ended!\n", job->Name()); + job->TeamDeleted(); + + if (job->IsService()) { + // TODO: take restart throttle into account + // TODO: don't restart on shutdown + _LaunchJob(job); + } + } + break; + } + case B_GET_LAUNCH_DATA: _HandleGetLaunchData(message); break; @@ -1112,6 +1161,7 @@ LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message) if (job == NULL) return; + job->SetTeamRegistrator(this); job->SetService(service); job->SetCreateDefaultPort(service); job->SetTarget(target); @@ -1232,7 +1282,7 @@ LaunchDaemon::_LaunchJobs(Target* target, bool forceNow) void LaunchDaemon::_LaunchJob(Job* job, uint32 options) { - if (job == NULL || job->IsLaunching() || job->IsRunning() + if (job == NULL || !job->CanBeLaunched() || ((options & FORCE_NOW) == 0 && (!job->EventHasTriggered() || !job->CheckCondition(*this) || ((options & TRIGGER_DEMAND) != 0 @@ -1256,7 +1306,12 @@ LaunchDaemon::_LaunchJob(Job* job, uint32 options) job->Event()->ResetTrigger(); job->SetLaunching(true); - fJobQueue.AddJob(job); + + status_t status = fJobQueue.AddJob(job); + if (status != B_OK) { + debug_printf("Adding job %s to queue failed: %s\n", job->Name(), + strerror(status)); + } } @@ -1532,7 +1587,11 @@ LaunchDaemon::_AddInitJob(BJob* job) static void open_stdio(int targetFD, int openMode) { +#ifdef DEBUG + int fd = open("/dev/dprintf", openMode); +#else int fd = open("/dev/null", openMode); +#endif if (fd != targetFD) { dup2(fd, targetFD); close(fd); From e3616ca108fee51c674cd315e2aacd2102f75a9e Mon Sep 17 00:00:00 2001 From: Simon South Date: Mon, 26 Oct 2015 12:42:30 -0400 Subject: [PATCH 080/370] system: Provide elf.h to applications Make a version of elf.h (assembled from the private header files elf_common.h, elf32.h and elf64.h, and including Haiku's extensions for C++) available to applications ported from UNIX. Signed-off-by: Jessica Hamilton --- headers/os/kernel/elf.h | 707 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 707 insertions(+) create mode 100644 headers/os/kernel/elf.h diff --git a/headers/os/kernel/elf.h b/headers/os/kernel/elf.h new file mode 100644 index 0000000000..6f486f6774 --- /dev/null +++ b/headers/os/kernel/elf.h @@ -0,0 +1,707 @@ +/* + * Copyright 2002-2015 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _ELF_H +#define _ELF_H + + +#include +#include + + +typedef uint32 Elf32_Addr; +typedef uint16 Elf32_Half; +typedef uint32 Elf32_Off; +typedef int32 Elf32_Sword; +typedef uint32 Elf32_Word; + +typedef Elf32_Half Elf32_Versym; + +typedef uint64 Elf64_Addr; +typedef uint64 Elf64_Off; +typedef uint16 Elf64_Half; +typedef uint32 Elf64_Word; +typedef int32 Elf64_Sword; +typedef uint64 Elf64_Xword; +typedef int64 Elf64_Sxword; + +typedef Elf64_Half Elf64_Versym; + + +/*** ELF header ***/ + +#define EI_NIDENT 16 + +typedef struct { + uint8 e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; + +#ifdef __cplusplus + bool IsHostEndian() const; +#endif +} Elf32_Ehdr; + +typedef struct { + uint8 e_ident[EI_NIDENT]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; + +#ifdef __cplusplus + bool IsHostEndian() const; +#endif +} Elf64_Ehdr; + +#define ELF_MAGIC "\x7f""ELF" + +/* e_ident[] indices */ +#define EI_MAG0 0 +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_PAD 7 + +/* e_type (Object file type) */ +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* Relocatable file */ +#define ET_EXEC 2 /* Executable file */ +#define ET_DYN 3 /* Shared-object file */ +#define ET_CORE 4 /* Core file */ +#define ET_LOOS 0xfe00 /* OS-specific range start */ +#define ET_HIOS 0xfeff /* OS-specific range end */ +#define ET_LOPROC 0xff00 /* Processor-specific range start */ +#define ET_HIPROC 0xffff /* Processor-specific range end */ + +/* e_machine (Architecture) */ +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* Sparc */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola m68k family */ +#define EM_88K 5 /* Motorola m88k family */ +#define EM_486 6 /* Intel 80486, Reserved for future use */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */ +#define EM_S370 9 /* IBM System/370 */ +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian, Deprecated */ +#define EM_PARISC 15 /* HPPA */ +#define EM_VPP550 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Sun "v8plus" */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* 64-bit PowerPC */ +#define EM_S390 22 /* IBM S/390 */ +#define EM_V800 36 /* NEC V800 series */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH32 */ +#define EM_MCORE 39 /* Motorola M*Core */ +#define EM_RCE 39 /* Old name for MCore */ +#define EM_ARM 40 /* ARM */ +#define EM_OLD_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Renesas / SuperH SH */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_TRICORE 44 /* Siemens Tricore embedded processor */ +#define EM_ARC 45 /* ARC Cores */ +#define EM_H8_300 46 /* Renesas H8/300 */ +#define EM_H8_300H 47 /* Renesas H8/300H */ +#define EM_H8S 48 /* Renesas H8S */ +#define EM_H8_500 49 /* Renesas H8/500 */ +#define EM_IA_64 50 /* Intel IA-64 Processor */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu Multimedia Accelerator */ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embedded RISC processor */ +#define EM_NDR1 57 /* Denso NDR1 microprocesspr */ +#define EM_STARCORE 58 /* Motorola Star*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronics ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ embedded processor */ +#define EM_X86_64 62 /* Advanced Micro Devices X86-64 processor */ + +/* architecture class (EI_CLASS) */ +#define ELFCLASS32 1 +#define ELFCLASS64 2 +/* endian (EI_DATA) */ +#define ELFDATA2LSB 1 /* little endian */ +#define ELFDATA2MSB 2 /* big endian */ + + +/*** section header ***/ + +typedef struct { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +} Elf32_Shdr; + +typedef struct { + Elf64_Word sh_name; + Elf64_Word sh_type; + Elf64_Xword sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + Elf64_Xword sh_size; + Elf64_Word sh_link; + Elf64_Word sh_info; + Elf64_Xword sh_addralign; + Elf64_Xword sh_entsize; +} Elf64_Shdr; + +/* special section indices */ +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xff00 +#define SHN_LOPROC 0xff00 +#define SHN_HIPROC 0xff1f +#define SHN_ABS 0xfff1 +#define SHN_COMMON 0xfff2 +#define SHN_HIRESERVE 0xffff + +/* section header type */ +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 + +#define SHT_GNU_verdef 0x6ffffffd /* version definition section */ +#define SHT_GNU_verneed 0x6ffffffe /* version needs section */ +#define SHT_GNU_versym 0x6fffffff /* version symbol table */ + +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7fffffff +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xffffffff + +/* section header flags */ +#define SHF_WRITE 1 +#define SHF_ALLOC 2 +#define SHF_EXECINSTR 4 + +#define SHF_MASKPROC 0xf0000000 + + +/*** program header ***/ + +typedef struct { + Elf32_Word p_type; + Elf32_Off p_offset; /* offset from the beginning of the file of the segment */ + Elf32_Addr p_vaddr; /* virtual address for the segment in memory */ + Elf32_Addr p_paddr; + Elf32_Word p_filesz; /* the size of the segment in the file */ + Elf32_Word p_memsz; /* the size of the segment in memory */ + Elf32_Word p_flags; + Elf32_Word p_align; + +#ifdef __cplusplus + bool IsReadWrite() const; + bool IsExecutable() const; +#endif +} Elf32_Phdr; + +typedef struct { + Elf64_Word p_type; + Elf64_Word p_flags; + Elf64_Off p_offset; /* offset from the beginning of the file of the segment */ + Elf64_Addr p_vaddr; /* virtual address for the segment in memory */ + Elf64_Addr p_paddr; + Elf64_Xword p_filesz; /* the size of the segment in the file */ + Elf64_Xword p_memsz; /* the size of the segment in memory */ + Elf64_Xword p_align; + +#ifdef __cplusplus + bool IsReadWrite() const; + bool IsExecutable() const; +#endif +} Elf64_Phdr; + +/* program header segment types */ +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_TLS 7 +#define PT_STACK 0x6474e551 +#define PT_RELRO 0x6474e552 + +#define PT_LOPROC 0x70000000 +#define PT_ARM_UNWIND 0x70000001 +#define PT_HIPROC 0x7fffffff + +/* program header segment flags */ +#define PF_EXECUTE 0x1 +#define PF_WRITE 0x2 +#define PF_READ 0x4 +#define PF_PROTECTION_MASK (PF_EXECUTE | PF_WRITE | PF_READ) + +#define PF_MASKPROC 0xf0000000 + + +/* symbol table entry */ + +typedef struct { + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + uint8 st_info; + uint8 st_other; + Elf32_Half st_shndx; + +#ifdef __cplusplus + uint8 Bind() const; + uint8 Type() const; + void SetInfo(uint8 bind, uint8 type); +#endif +} Elf32_Sym; + +typedef struct { + Elf64_Word st_name; + uint8 st_info; + uint8 st_other; + Elf64_Half st_shndx; + Elf64_Addr st_value; + Elf64_Xword st_size; + +#ifdef __cplusplus + uint8 Bind() const; + uint8 Type() const; + void SetInfo(uint8 bind, uint8 type); +#endif +} Elf64_Sym; + +#define ELF32_ST_BIND(i) ((i) >> 4) +#define ELF32_ST_TYPE(i) ((i) & 0xf) +#define ELF32_ST_INFO(b, t) (((b) << 4) + ((t) & 0xf)) + +#define ELF64_ST_BIND(i) ((i) >> 4) +#define ELF64_ST_TYPE(i) ((i) & 0xf) +#define ELF64_ST_INFO(b, t) (((b) << 4) + ((t) & 0xf)) + +/* symbol types */ +#define STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 +#define STT_SECTION 3 +#define STT_FILE 4 +#define STT_TLS 6 +#define STT_LOPROC 13 +#define STT_HIPROC 15 + +/* symbol binding */ +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 +#define STB_LOPROC 13 +#define STB_HIPROC 15 + +/* special symbol indices */ +#define STN_UNDEF 0 + + +/* relocation table entry */ + +typedef struct { + Elf32_Addr r_offset; + Elf32_Word r_info; + +#ifdef __cplusplus + uint8 SymbolIndex() const; + uint8 Type() const; +#endif +} Elf32_Rel; + +typedef struct { + Elf64_Addr r_offset; + Elf64_Xword r_info; + +#ifdef __cplusplus + uint8 SymbolIndex() const; + uint8 Type() const; +#endif +} Elf64_Rel; + +#ifdef __cplusplus +typedef struct Elf32_Rela : public Elf32_Rel { +#else +typedef struct { + Elf32_Addr r_offset; + Elf32_Word r_info; +#endif + Elf32_Sword r_addend; +} Elf32_Rela; + +#ifdef __cplusplus +typedef struct Elf64_Rela : public Elf64_Rel { +#else +typedef struct { + Elf64_Addr r_offset; + Elf64_Xword r_info; +#endif + Elf64_Sxword r_addend; +} Elf64_Rela; + +#define ELF32_R_SYM(i) ((i) >> 8) +#define ELF32_R_TYPE(i) ((unsigned char)(i)) +#define ELF32_R_INFO(s, t) (((s) << 8) + (unsigned char)(t)) + +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((i) & 0xffffffffL) +#define ELF64_R_INFO(s, t) ((((Elf64_Xword)(s)) << 32) + ((t) & 0xffffffffL)) + + +/* dynamic section entry */ + +typedef struct { + Elf32_Sword d_tag; + union { + Elf32_Word d_val; + Elf32_Addr d_ptr; + } d_un; +} Elf32_Dyn; + +typedef struct { + Elf64_Sxword d_tag; + union { + Elf64_Xword d_val; + Elf64_Addr d_ptr; + } d_un; +} Elf64_Dyn; + +/* dynamic entry type */ +#define DT_NULL 0 +#define DT_NEEDED 1 +#define DT_PLTRELSZ 2 +#define DT_PLTGOT 3 +#define DT_HASH 4 +#define DT_STRTAB 5 +#define DT_SYMTAB 6 +#define DT_RELA 7 +#define DT_RELASZ 8 +#define DT_RELAENT 9 +#define DT_STRSZ 10 +#define DT_SYMENT 11 +#define DT_INIT 12 +#define DT_FINI 13 +#define DT_SONAME 14 +#define DT_RPATH 15 +#define DT_SYMBOLIC 16 +#define DT_REL 17 +#define DT_RELSZ 18 +#define DT_RELENT 19 +#define DT_PLTREL 20 +#define DT_DEBUG 21 +#define DT_TEXTREL 22 +#define DT_JMPREL 23 +#define DT_BIND_NOW 24 /* no lazy binding */ +#define DT_INIT_ARRAY 25 /* init function array */ +#define DT_FINI_ARRAY 26 /* termination function array */ +#define DT_INIT_ARRAYSZ 27 /* init function array size */ +#define DT_FINI_ARRAYSZ 28 /* termination function array size */ +#define DT_RUNPATH 29 /* library search path (supersedes DT_RPATH) */ +#define DT_FLAGS 30 /* flags (see below) */ +#define DT_ENCODING 32 +#define DT_PREINIT_ARRAY 32 /* preinitialization array */ +#define DT_PREINIT_ARRAYSZ 33 /* preinitialization array size */ + +#define DT_VERSYM 0x6ffffff0 /* symbol version table */ +#define DT_VERDEF 0x6ffffffc /* version definition table */ +#define DT_VERDEFNUM 0x6ffffffd /* number of version definitions */ +#define DT_VERNEED 0x6ffffffe /* table with needed versions */ +#define DT_VERNEEDNUM 0x6fffffff /* number of needed versions */ + +#define DT_LOPROC 0x70000000 +#define DT_HIPROC 0x7fffffff + +/* DT_FLAGS values */ +#define DF_ORIGIN 0x01 +#define DF_SYMBOLIC 0x02 +#define DF_TEXTREL 0x04 +#define DF_BIND_NOW 0x08 +#define DF_STATIC_TLS 0x10 + + +/* version definition section */ + +typedef struct { + Elf32_Half vd_version; /* version revision */ + Elf32_Half vd_flags; /* version information flags */ + Elf32_Half vd_ndx; /* version index as specified in the + symbol version table */ + Elf32_Half vd_cnt; /* number of associated verdaux entries */ + Elf32_Word vd_hash; /* version name hash value */ + Elf32_Word vd_aux; /* byte offset to verdaux array */ + Elf32_Word vd_next; /* byte offset to next verdef entry */ +} Elf32_Verdef; + +typedef struct { + Elf64_Half vd_version; /* version revision */ + Elf64_Half vd_flags; /* version information flags */ + Elf64_Half vd_ndx; /* version index as specified in the + symbol version table */ + Elf64_Half vd_cnt; /* number of associated verdaux entries */ + Elf64_Word vd_hash; /* version name hash value */ + Elf64_Word vd_aux; /* byte offset to verdaux array */ + Elf64_Word vd_next; /* byte offset to next verdef entry */ +} Elf64_Verdef; + +/* values for vd_version (version revision) */ +#define VER_DEF_NONE 0 /* no version */ +#define VER_DEF_CURRENT 1 /* current version */ +#define VER_DEF_NUM 2 /* given version number */ + +/* values for vd_flags (version information flags) */ +#define VER_FLG_BASE 0x1 /* version definition of file itself */ +#define VER_FLG_WEAK 0x2 /* weak version identifier */ + +/* values for versym symbol index */ +#define VER_NDX_LOCAL 0 /* symbol is local */ +#define VER_NDX_GLOBAL 1 /* symbol is global/unversioned */ +#define VER_NDX_INITIAL 2 /* initial version -- that's the one given + to symbols when a library becomes + versioned; handled by the linker (and + runtime loader) similar to + VER_NDX_GLOBAL */ +#define VER_NDX_LORESERVE 0xff00 /* beginning of reserved entries */ +#define VER_NDX_ELIMINATE 0xff01 /* symbol is to be eliminated */ + +#define VER_NDX_FLAG_HIDDEN 0x8000 /* flag: version is hidden */ +#define VER_NDX_MASK 0x7fff /* mask to get the actual version index */ +#define VER_NDX(x) ((x) & VER_NDX_MASK) + + +/* auxiliary version information */ + +typedef struct { + Elf32_Word vda_name; /* string table offset to version or dependency + name */ + Elf32_Word vda_next; /* byte offset to next verdaux entry */ +} Elf32_Verdaux; + +typedef struct { + Elf64_Word vda_name; /* string table offset to version or dependency + name */ + Elf64_Word vda_next; /* byte offset to next verdaux entry */ +} Elf64_Verdaux; + + +/* version dependency section */ + +typedef struct { + Elf32_Half vn_version; /* version of structure */ + Elf32_Half vn_cnt; /* number of associated vernaux entries */ + Elf32_Word vn_file; /* byte offset to file name for this + dependency */ + Elf32_Word vn_aux; /* byte offset to vernaux array */ + Elf32_Word vn_next; /* byte offset to next verneed entry */ +} Elf32_Verneed; + +typedef struct { + Elf64_Half vn_version; /* version of structure */ + Elf64_Half vn_cnt; /* number of associated vernaux entries */ + Elf64_Word vn_file; /* byte offset to file name for this + dependency */ + Elf64_Word vn_aux; /* byte offset to vernaux array */ + Elf64_Word vn_next; /* byte offset to next verneed entry */ +} Elf64_Verneed; + +/* values for vn_version (version revision) */ +#define VER_NEED_NONE 0 /* no version */ +#define VER_NEED_CURRENT 1 /* current version */ +#define VER_NEED_NUM 2 /* given version number */ + + +/* auxiliary needed version information */ + +typedef struct { + Elf32_Word vna_hash; /* dependency name hash value */ + Elf32_Half vna_flags; /* dependency specific information flags */ + Elf32_Half vna_other; /* version index as specified in the symbol + version table */ + Elf32_Word vna_name; /* string table offset to dependency name */ + Elf32_Word vna_next; /* byte offset to next vernaux entry */ +} Elf32_Vernaux; + +typedef struct { + Elf64_Word vna_hash; /* dependency name hash value */ + Elf64_Half vna_flags; /* dependency specific information flags */ + Elf64_Half vna_other; /* version index as specified in the symbol + version table */ + Elf64_Word vna_name; /* string table offset to dependency name */ + Elf64_Word vna_next; /* byte offset to next vernaux entry */ +} Elf64_Vernaux; + +/* values for vna_flags */ +#define VER_FLG_WEAK 0x2 /* weak version identifier */ + + +/*** inline functions ***/ + +#ifdef __cplusplus + +inline bool +Elf32_Ehdr::IsHostEndian() const +{ +#if B_HOST_IS_LENDIAN + return e_ident[EI_DATA] == ELFDATA2LSB; +#elif B_HOST_IS_BENDIAN + return e_ident[EI_DATA] == ELFDATA2MSB; +#endif +} + + +inline bool +Elf64_Ehdr::IsHostEndian() const +{ +#if B_HOST_IS_LENDIAN + return e_ident[EI_DATA] == ELFDATA2LSB; +#elif B_HOST_IS_BENDIAN + return e_ident[EI_DATA] == ELFDATA2MSB; +#endif +} + + +inline bool +Elf32_Phdr::IsReadWrite() const +{ + return !(~p_flags & (PF_READ | PF_WRITE)); +} + + +inline bool +Elf32_Phdr::IsExecutable() const +{ + return (p_flags & PF_EXECUTE) != 0; +} + + +inline bool +Elf64_Phdr::IsReadWrite() const +{ + return !(~p_flags & (PF_READ | PF_WRITE)); +} + + +inline bool +Elf64_Phdr::IsExecutable() const +{ + return (p_flags & PF_EXECUTE) != 0; +} + + +inline uint8 +Elf32_Sym::Bind() const +{ + return ELF32_ST_BIND(st_info); +} + + +inline uint8 +Elf32_Sym::Type() const +{ + return ELF32_ST_TYPE(st_info); +} + + +inline void +Elf32_Sym::SetInfo(uint8 bind, uint8 type) +{ + st_info = ELF32_ST_INFO(bind, type); +} + + +inline uint8 +Elf64_Sym::Bind() const +{ + return ELF64_ST_BIND(st_info); +} + + +inline uint8 +Elf64_Sym::Type() const +{ + return ELF64_ST_TYPE(st_info); +} + + +inline void +Elf64_Sym::SetInfo(uint8 bind, uint8 type) +{ + st_info = ELF64_ST_INFO(bind, type); +} + + +inline uint8 +Elf32_Rel::SymbolIndex() const +{ + return ELF32_R_SYM(r_info); +} + + +inline uint8 +Elf32_Rel::Type() const +{ + return ELF32_R_TYPE(r_info); +} + + +inline uint8 +Elf64_Rel::SymbolIndex() const +{ + return ELF64_R_SYM(r_info); +} + + +inline uint8 +Elf64_Rel::Type() const +{ + return ELF64_R_TYPE(r_info); +} + +#endif /* __cplusplus */ + + +#endif /* _ELF_H */ From 75c31ae28dda6ee80b0c3b96becda8f6d1eb28ac Mon Sep 17 00:00:00 2001 From: Simon South Date: Mon, 26 Oct 2015 13:43:44 -0400 Subject: [PATCH 081/370] system: Build using public elf.h header Reduce duplication of code by * Removing from elf_common.h definitions available in os/kernel/elf.h * Deleting elf32.h and elf64.h * Renaming elf_common.h to elf_private.h * Updating source to build using public and private ELF header files together Signed-off-by: Jessica Hamilton --- headers/private/kernel/arch/elf.h | 2 +- headers/private/kernel/boot/arch.h | 8 +- headers/private/kernel/boot/elf.h | 4 +- headers/private/kernel/elf.h | 2 +- headers/private/kernel/elf_priv.h | 4 +- .../private/runtime_loader/runtime_loader.h | 4 +- headers/private/system/elf32.h | 243 -------------- headers/private/system/elf64.h | 247 -------------- headers/private/system/elf_common.h | 317 ------------------ headers/private/system/elf_private.h | 53 +++ headers/private/system/syscalls.h | 2 +- src/apps/debugger/elf/ElfFile.cpp | 8 +- src/apps/debugger/elf/ElfFile.h | 3 +- src/kits/debug/Image.h | 2 +- src/system/boot/loader/elf.cpp | 6 +- src/system/kernel/arch/arm/arch_elf.cpp | 18 +- src/system/kernel/arch/m68k/arch_elf.cpp | 14 +- src/system/kernel/arch/ppc/arch_elf.cpp | 14 +- src/system/kernel/arch/x86/arch_elf.cpp | 14 +- .../arch/m68k/arch_relocate.cpp | 10 +- .../runtime_loader/arch/ppc/arch_relocate.cpp | 6 +- .../runtime_loader/arch/x86/arch_relocate.cpp | 8 +- .../system/boot/loader/platform_misc.cpp | 8 +- 23 files changed, 121 insertions(+), 876 deletions(-) delete mode 100644 headers/private/system/elf32.h delete mode 100644 headers/private/system/elf64.h delete mode 100644 headers/private/system/elf_common.h create mode 100644 headers/private/system/elf_private.h diff --git a/headers/private/kernel/arch/elf.h b/headers/private/kernel/arch/elf.h index d2dc5d8588..d2b10f442a 100644 --- a/headers/private/kernel/arch/elf.h +++ b/headers/private/kernel/arch/elf.h @@ -6,7 +6,7 @@ #define _KERNEL_ARCH_ELF_H -#include +#include struct elf_image_info; diff --git a/headers/private/kernel/boot/arch.h b/headers/private/kernel/boot/arch.h index 2f4be42982..41a850268b 100644 --- a/headers/private/kernel/boot/arch.h +++ b/headers/private/kernel/boot/arch.h @@ -13,13 +13,13 @@ /* ELF support */ extern status_t boot_arch_elf_relocate_rel(preloaded_elf32_image* image, - struct Elf32_Rel* rel, int rel_len); + Elf32_Rel* rel, int rel_len); extern status_t boot_arch_elf_relocate_rel(preloaded_elf64_image* image, - struct Elf64_Rel* rel, int rel_len); + Elf64_Rel* rel, int rel_len); extern status_t boot_arch_elf_relocate_rela(preloaded_elf32_image* image, - struct Elf32_Rela* rel, int rel_len); + Elf32_Rela* rel, int rel_len); extern status_t boot_arch_elf_relocate_rela(preloaded_elf64_image* image, - struct Elf64_Rela* rel, int rel_len); + Elf64_Rela* rel, int rel_len); #endif /* KERNEL_BOOT_ARCH_H */ diff --git a/headers/private/kernel/boot/elf.h b/headers/private/kernel/boot/elf.h index 2f38836472..97d15d59c4 100644 --- a/headers/private/kernel/boot/elf.h +++ b/headers/private/kernel/boot/elf.h @@ -87,9 +87,9 @@ typedef preloaded_elf32_image preloaded_elf_image; #ifdef _BOOT_MODE extern status_t boot_elf_resolve_symbol(preloaded_elf32_image* image, - struct Elf32_Sym* symbol, Elf32_Addr* symbolAddress); + Elf32_Sym* symbol, Elf32_Addr* symbolAddress); extern status_t boot_elf_resolve_symbol(preloaded_elf64_image* image, - struct Elf64_Sym* symbol, Elf64_Addr* symbolAddress); + Elf64_Sym* symbol, Elf64_Addr* symbolAddress); extern void boot_elf64_set_relocation(Elf64_Addr resolveAddress, Elf64_Addr finalAddress); #endif diff --git a/headers/private/kernel/elf.h b/headers/private/kernel/elf.h index 3851504db4..8922336ddc 100644 --- a/headers/private/kernel/elf.h +++ b/headers/private/kernel/elf.h @@ -9,7 +9,7 @@ #define _KERNEL_ELF_H -#include +#include #include #include diff --git a/headers/private/kernel/elf_priv.h b/headers/private/kernel/elf_priv.h index 0b6341fbaf..69e675f191 100644 --- a/headers/private/kernel/elf_priv.h +++ b/headers/private/kernel/elf_priv.h @@ -9,8 +9,8 @@ #define _KERNEL_ELF_PRIV_H -#include -#include +#include + #include diff --git a/headers/private/runtime_loader/runtime_loader.h b/headers/private/runtime_loader/runtime_loader.h index ab4c3b2030..6a754f2330 100644 --- a/headers/private/runtime_loader/runtime_loader.h +++ b/headers/private/runtime_loader/runtime_loader.h @@ -11,11 +11,11 @@ #ifndef _RUNTIME_LOADER_H #define _RUNTIME_LOADER_H + #include #include -#include -#include +#include // #pragma mark - runtime loader libroot interface diff --git a/headers/private/system/elf32.h b/headers/private/system/elf32.h deleted file mode 100644 index c1bf7e245d..0000000000 --- a/headers/private/system/elf32.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright 2001, Travis Geiselbrecht. All rights reserved. - * Distributed under the terms of the NewOS License. - * - * Copyright 2002-2011, Haiku Inc. All Rights Reserved. - * Distributed under the terms of the MIT license. - */ -#ifndef _ELF32_H -#define _ELF32_H - - -#include - - -typedef uint32 Elf32_Addr; -typedef uint16 Elf32_Half; -typedef uint32 Elf32_Off; -typedef int32 Elf32_Sword; -typedef uint32 Elf32_Word; - -typedef Elf32_Half Elf32_Versym; - -/*** ELF header ***/ - -struct Elf32_Ehdr { - uint8 e_ident[EI_NIDENT]; - Elf32_Half e_type; - Elf32_Half e_machine; - Elf32_Word e_version; - Elf32_Addr e_entry; - Elf32_Off e_phoff; - Elf32_Off e_shoff; - Elf32_Word e_flags; - Elf32_Half e_ehsize; - Elf32_Half e_phentsize; - Elf32_Half e_phnum; - Elf32_Half e_shentsize; - Elf32_Half e_shnum; - Elf32_Half e_shstrndx; - -#ifdef __cplusplus - bool IsHostEndian() const; -#endif -}; - - -/*** section header ***/ - -struct Elf32_Shdr { - Elf32_Word sh_name; - Elf32_Word sh_type; - Elf32_Word sh_flags; - Elf32_Addr sh_addr; - Elf32_Off sh_offset; - Elf32_Word sh_size; - Elf32_Word sh_link; - Elf32_Word sh_info; - Elf32_Word sh_addralign; - Elf32_Word sh_entsize; -}; - - -/*** program header ***/ - -struct Elf32_Phdr { - Elf32_Word p_type; - Elf32_Off p_offset; /* offset from the beginning of the file of the segment */ - Elf32_Addr p_vaddr; /* virtual address for the segment in memory */ - Elf32_Addr p_paddr; - Elf32_Word p_filesz; /* the size of the segment in the file */ - Elf32_Word p_memsz; /* the size of the segment in memory */ - Elf32_Word p_flags; - Elf32_Word p_align; - -#ifdef __cplusplus - bool IsReadWrite() const; - bool IsExecutable() const; -#endif -}; - -struct Elf32_Sym { - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; - uint8 st_info; - uint8 st_other; - Elf32_Half st_shndx; - -#ifdef __cplusplus - uint8 Bind() const; - uint8 Type() const; - void SetInfo(uint8 bind, uint8 type); -#endif -}; - -#define ELF32_ST_BIND(i) ((i) >> 4) -#define ELF32_ST_TYPE(i) ((i) & 0xf) -#define ELF32_ST_INFO(b, t) (((b) << 4) + ((t) & 0xf)) - -struct Elf32_Rel { - Elf32_Addr r_offset; - Elf32_Word r_info; - -#ifdef __cplusplus - uint8 SymbolIndex() const; - uint8 Type() const; -#endif -}; - -#ifdef __cplusplus -struct Elf32_Rela : public Elf32_Rel { -#else -struct Elf32_Rela { - Elf32_Addr r_offset; - Elf32_Word r_info; -#endif - Elf32_Sword r_addend; -}; - -#define ELF32_R_SYM(i) ((i) >> 8) -#define ELF32_R_TYPE(i) ((unsigned char)(i)) -#define ELF32_R_INFO(s, t) (((s) << 8) + (unsigned char)(t)) - -struct Elf32_Dyn { - Elf32_Sword d_tag; - union { - Elf32_Word d_val; - Elf32_Addr d_ptr; - } d_un; -}; - - -/* version definition section */ - -struct Elf32_Verdef { - Elf32_Half vd_version; /* version revision */ - Elf32_Half vd_flags; /* version information flags */ - Elf32_Half vd_ndx; /* version index as specified in the - symbol version table */ - Elf32_Half vd_cnt; /* number of associated verdaux entries */ - Elf32_Word vd_hash; /* version name hash value */ - Elf32_Word vd_aux; /* byte offset to verdaux array */ - Elf32_Word vd_next; /* byte offset to next verdef entry */ -}; - - -/* auxiliary version information */ - -struct Elf32_Verdaux { - Elf32_Word vda_name; /* string table offset to version or dependency - name */ - Elf32_Word vda_next; /* byte offset to next verdaux entry */ -}; - - -/* version dependency section */ - -struct Elf32_Verneed { - Elf32_Half vn_version; /* version of structure */ - Elf32_Half vn_cnt; /* number of associated vernaux entries */ - Elf32_Word vn_file; /* byte offset to file name for this - dependency */ - Elf32_Word vn_aux; /* byte offset to vernaux array */ - Elf32_Word vn_next; /* byte offset to next verneed entry */ -}; - - -/* auxiliary needed version information */ - -struct Elf32_Vernaux { - Elf32_Word vna_hash; /* dependency name hash value */ - Elf32_Half vna_flags; /* dependency specific information flags */ - Elf32_Half vna_other; /* version index as specified in the symbol - version table */ - Elf32_Word vna_name; /* string table offset to dependency name */ - Elf32_Word vna_next; /* byte offset to next vernaux entry */ -}; - - -/*** inline functions ***/ - -#ifdef __cplusplus - -inline bool -Elf32_Ehdr::IsHostEndian() const -{ -#if B_HOST_IS_LENDIAN - return e_ident[EI_DATA] == ELFDATA2LSB; -#elif B_HOST_IS_BENDIAN - return e_ident[EI_DATA] == ELFDATA2MSB; -#endif -} - - -inline bool -Elf32_Phdr::IsReadWrite() const -{ - return !(~p_flags & (PF_READ | PF_WRITE)); -} - - -inline bool -Elf32_Phdr::IsExecutable() const -{ - return (p_flags & PF_EXECUTE) != 0; -} - - -inline uint8 -Elf32_Sym::Bind() const -{ - return ELF32_ST_BIND(st_info); -} - - -inline uint8 -Elf32_Sym::Type() const -{ - return ELF32_ST_TYPE(st_info); -} - -inline void -Elf32_Sym::SetInfo(uint8 bind, uint8 type) -{ - st_info = ELF32_ST_INFO(bind, type); -} - -inline uint8 -Elf32_Rel::SymbolIndex() const -{ - return ELF32_R_SYM(r_info); -} - - -inline uint8 -Elf32_Rel::Type() const -{ - return ELF32_R_TYPE(r_info); -} - -#endif /* __cplusplus */ - -#endif /* _ELF32_H_ */ diff --git a/headers/private/system/elf64.h b/headers/private/system/elf64.h deleted file mode 100644 index 3efd48b32a..0000000000 --- a/headers/private/system/elf64.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2001, Travis Geiselbrecht. All rights reserved. - * Distributed under the terms of the NewOS License. - * - * Copyright 2002-2011, Haiku Inc. All Rights Reserved. - * Distributed under the terms of the MIT license. - */ -#ifndef _ELF64_H -#define _ELF64_H - - -#include - - -typedef uint64 Elf64_Addr; -typedef uint64 Elf64_Off; -typedef uint16 Elf64_Half; -typedef uint32 Elf64_Word; -typedef int32 Elf64_Sword; -typedef uint64 Elf64_Xword; -typedef int64 Elf64_Sxword; - -typedef Elf64_Half Elf64_Versym; - -/*** ELF header ***/ - -struct Elf64_Ehdr { - uint8 e_ident[EI_NIDENT]; - Elf64_Half e_type; - Elf64_Half e_machine; - Elf64_Word e_version; - Elf64_Addr e_entry; - Elf64_Off e_phoff; - Elf64_Off e_shoff; - Elf64_Word e_flags; - Elf64_Half e_ehsize; - Elf64_Half e_phentsize; - Elf64_Half e_phnum; - Elf64_Half e_shentsize; - Elf64_Half e_shnum; - Elf64_Half e_shstrndx; - -#ifdef __cplusplus - bool IsHostEndian() const; -#endif -}; - - -/*** section header ***/ - -struct Elf64_Shdr { - Elf64_Word sh_name; - Elf64_Word sh_type; - Elf64_Xword sh_flags; - Elf64_Addr sh_addr; - Elf64_Off sh_offset; - Elf64_Xword sh_size; - Elf64_Word sh_link; - Elf64_Word sh_info; - Elf64_Xword sh_addralign; - Elf64_Xword sh_entsize; -}; - - -/*** program header ***/ - -struct Elf64_Phdr { - Elf64_Word p_type; - Elf64_Word p_flags; - Elf64_Off p_offset; /* offset from the beginning of the file of the segment */ - Elf64_Addr p_vaddr; /* virtual address for the segment in memory */ - Elf64_Addr p_paddr; - Elf64_Xword p_filesz; /* the size of the segment in the file */ - Elf64_Xword p_memsz; /* the size of the segment in memory */ - Elf64_Xword p_align; - -#ifdef __cplusplus - bool IsReadWrite() const; - bool IsExecutable() const; -#endif -}; - -struct Elf64_Sym { - Elf64_Word st_name; - uint8 st_info; - uint8 st_other; - Elf64_Half st_shndx; - Elf64_Addr st_value; - Elf64_Xword st_size; - -#ifdef __cplusplus - uint8 Bind() const; - uint8 Type() const; - void SetInfo(uint8 bind, uint8 type); -#endif -}; - -#define ELF64_ST_BIND(i) ((i) >> 4) -#define ELF64_ST_TYPE(i) ((i) & 0xf) -#define ELF64_ST_INFO(b, t) (((b) << 4) + ((t) & 0xf)) - -struct Elf64_Rel { - Elf64_Addr r_offset; - Elf64_Xword r_info; - -#ifdef __cplusplus - uint8 SymbolIndex() const; - uint8 Type() const; -#endif -}; - -#ifdef __cplusplus -struct Elf64_Rela : public Elf64_Rel { -#else -struct Elf64_Rela { - Elf64_Addr r_offset; - Elf64_Xword r_info; -#endif - Elf64_Sxword r_addend; -}; - -#define ELF64_R_SYM(i) ((i) >> 32) -#define ELF64_R_TYPE(i) ((i) & 0xffffffffL) -#define ELF64_R_INFO(s, t) ((((Elf64_Xword)(s)) << 32) + ((t) & 0xffffffffL)) - -struct Elf64_Dyn { - Elf64_Sxword d_tag; - union { - Elf64_Xword d_val; - Elf64_Addr d_ptr; - } d_un; -}; - - -/* version definition section */ - -struct Elf64_Verdef { - Elf64_Half vd_version; /* version revision */ - Elf64_Half vd_flags; /* version information flags */ - Elf64_Half vd_ndx; /* version index as specified in the - symbol version table */ - Elf64_Half vd_cnt; /* number of associated verdaux entries */ - Elf64_Word vd_hash; /* version name hash value */ - Elf64_Word vd_aux; /* byte offset to verdaux array */ - Elf64_Word vd_next; /* byte offset to next verdef entry */ -}; - - -/* auxiliary version information */ - -struct Elf64_Verdaux { - Elf64_Word vda_name; /* string table offset to version or dependency - name */ - Elf64_Word vda_next; /* byte offset to next verdaux entry */ -}; - - -/* version dependency section */ - -struct Elf64_Verneed { - Elf64_Half vn_version; /* version of structure */ - Elf64_Half vn_cnt; /* number of associated vernaux entries */ - Elf64_Word vn_file; /* byte offset to file name for this - dependency */ - Elf64_Word vn_aux; /* byte offset to vernaux array */ - Elf64_Word vn_next; /* byte offset to next verneed entry */ -}; - - -/* auxiliary needed version information */ - -struct Elf64_Vernaux { - Elf64_Word vna_hash; /* dependency name hash value */ - Elf64_Half vna_flags; /* dependency specific information flags */ - Elf64_Half vna_other; /* version index as specified in the symbol - version table */ - Elf64_Word vna_name; /* string table offset to dependency name */ - Elf64_Word vna_next; /* byte offset to next vernaux entry */ -}; - - -/*** inline functions ***/ - -#ifdef __cplusplus - -inline bool -Elf64_Ehdr::IsHostEndian() const -{ -#if B_HOST_IS_LENDIAN - return e_ident[EI_DATA] == ELFDATA2LSB; -#elif B_HOST_IS_BENDIAN - return e_ident[EI_DATA] == ELFDATA2MSB; -#endif -} - - -inline bool -Elf64_Phdr::IsReadWrite() const -{ - return !(~p_flags & (PF_READ | PF_WRITE)); -} - - -inline bool -Elf64_Phdr::IsExecutable() const -{ - return (p_flags & PF_EXECUTE) != 0; -} - - -inline uint8 -Elf64_Sym::Bind() const -{ - return ELF64_ST_BIND(st_info); -} - - -inline uint8 -Elf64_Sym::Type() const -{ - return ELF64_ST_TYPE(st_info); -} - - -inline void -Elf64_Sym::SetInfo(uint8 bind, uint8 type) -{ - st_info = ELF64_ST_INFO(bind, type); -} - - -inline uint8 -Elf64_Rel::SymbolIndex() const -{ - return ELF64_R_SYM(r_info); -} - - -inline uint8 -Elf64_Rel::Type() const -{ - return ELF64_R_TYPE(r_info); -} - -#endif /* __cplusplus */ - -#endif /* _ELF64_H_ */ diff --git a/headers/private/system/elf_common.h b/headers/private/system/elf_common.h deleted file mode 100644 index 23ab555032..0000000000 --- a/headers/private/system/elf_common.h +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright 2001, Travis Geiselbrecht. All rights reserved. - * Distributed under the terms of the NewOS License. - * - * Copyright 2002-2011, Haiku Inc. All Rights Reserved. - * Distributed under the terms of the MIT license. - */ -#ifndef _ELF_COMMON_H -#define _ELF_COMMON_H - - -#include -#include - -#include - - -/*** ELF header ***/ - -#define EI_NIDENT 16 - -#define ELF_MAGIC "\x7f""ELF" - -// e_ident[] indices -#define EI_MAG0 0 -#define EI_MAG1 1 -#define EI_MAG2 2 -#define EI_MAG3 3 -#define EI_CLASS 4 -#define EI_DATA 5 -#define EI_VERSION 6 -#define EI_PAD 7 - -// e_type (Object file type) -#define ET_NONE 0 // No file type -#define ET_REL 1 // Relocatable file -#define ET_EXEC 2 // Executable file -#define ET_DYN 3 // Shared object file -#define ET_CORE 4 // Core file -#define ET_LOOS 0xfe00 // OS-specific range start -#define ET_HIOS 0xfeff // OS-specific range end -#define ET_LOPROC 0xff00 // Processor-specific range start -#define ET_HIPROC 0xffff // Processor-specific range end - -// e_machine (Architecture) -#define EM_NONE 0 // No machine -#define EM_M32 1 // AT&T WE 32100 -#define EM_SPARC 2 // Sparc -#define EM_386 3 // Intel 80386 -#define EM_68K 4 // Motorola m68k family -#define EM_88K 5 // Motorola m88k family -#define EM_486 6 // Intel 80486, Reserved for future use -#define EM_860 7 // Intel 80860 -#define EM_MIPS 8 // MIPS R3000 (officially, big-endian only) -#define EM_S370 9 // IBM System/370 -#define EM_MIPS_RS3_LE 10 // MIPS R3000 little-endian, Deprecated -#define EM_PARISC 15 // HPPA -#define EM_VPP550 17 // Fujitsu VPP500 -#define EM_SPARC32PLUS 18 // Sun "v8plus" -#define EM_960 19 // Intel 80960 -#define EM_PPC 20 // PowerPC -#define EM_PPC64 21 // 64-bit PowerPC -#define EM_S390 22 // IBM S/390 -#define EM_V800 36 // NEC V800 series -#define EM_FR20 37 // Fujitsu FR20 -#define EM_RH32 38 // TRW RH32 -#define EM_MCORE 39 // Motorola M*Core -#define EM_RCE 39 // Old name for MCore -#define EM_ARM 40 // ARM -#define EM_OLD_ALPHA 41 // Digital Alpha -#define EM_SH 42 // Renesas / SuperH SH -#define EM_SPARCV9 43 // SPARC v9 64-bit -#define EM_TRICORE 44 // Siemens Tricore embedded processor -#define EM_ARC 45 // ARC Cores -#define EM_H8_300 46 // Renesas H8/300 -#define EM_H8_300H 47 // Renesas H8/300H -#define EM_H8S 48 // Renesas H8S -#define EM_H8_500 49 // Renesas H8/500 -#define EM_IA_64 50 // Intel IA-64 Processor -#define EM_MIPS_X 51 // Stanford MIPS-X -#define EM_COLDFIRE 52 // Motorola Coldfire -#define EM_68HC12 53 // Motorola M68HC12 -#define EM_MMA 54 // Fujitsu Multimedia Accelerator -#define EM_PCP 55 // Siemens PCP -#define EM_NCPU 56 // Sony nCPU embedded RISC processor -#define EM_NDR1 57 // Denso NDR1 microprocesspr -#define EM_STARCORE 58 // Motorola Star*Core processor -#define EM_ME16 59 // Toyota ME16 processor -#define EM_ST100 60 // STMicroelectronics ST100 processor -#define EM_TINYJ 61 // Advanced Logic Corp. TinyJ embedded processor -#define EM_X86_64 62 // Advanced Micro Devices X86-64 processor - -// architecture class (EI_CLASS) -#define ELFCLASS32 1 -#define ELFCLASS64 2 -// endian (EI_DATA) -#define ELFDATA2LSB 1 /* little endian */ -#define ELFDATA2MSB 2 /* big endian */ - - -/*** section header ***/ - -// special section indices -#define SHN_UNDEF 0 -#define SHN_LORESERVE 0xff00 -#define SHN_LOPROC 0xff00 -#define SHN_HIPROC 0xff1f -#define SHN_ABS 0xfff1 -#define SHN_COMMON 0xfff2 -#define SHN_HIRESERVE 0xffff - -// section header type -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 - -#define SHT_GNU_verdef 0x6ffffffd /* version definition section */ -#define SHT_GNU_verneed 0x6ffffffe /* version needs section */ -#define SHT_GNU_versym 0x6fffffff /* version symbol table */ - -#define SHT_LOPROC 0x70000000 -#define SHT_HIPROC 0x7fffffff -#define SHT_LOUSER 0x80000000 -#define SHT_HIUSER 0xffffffff - -// section header flags -#define SHF_WRITE 1 -#define SHF_ALLOC 2 -#define SHF_EXECINSTR 4 - -#define SHF_MASKPROC 0xf0000000 - - -/*** program header ***/ - -// program header segment types -#define PT_NULL 0 -#define PT_LOAD 1 -#define PT_DYNAMIC 2 -#define PT_INTERP 3 -#define PT_NOTE 4 -#define PT_SHLIB 5 -#define PT_PHDR 6 -#define PT_TLS 7 -#define PT_STACK 0x6474e551 -#define PT_RELRO 0x6474e552 - -#define PT_LOPROC 0x70000000 -#define PT_ARM_UNWIND 0x70000001 -#define PT_HIPROC 0x7fffffff - - -// program header segment flags -#define PF_EXECUTE 0x1 -#define PF_WRITE 0x2 -#define PF_READ 0x4 -#define PF_PROTECTION_MASK (PF_EXECUTE | PF_WRITE | PF_READ) - -#define PF_MASKPROC 0xf0000000 - -#define STT_NOTYPE 0 -#define STT_OBJECT 1 -#define STT_FUNC 2 -#define STT_SECTION 3 -#define STT_FILE 4 -#define STT_TLS 6 -#define STT_LOPROC 13 -#define STT_HIPROC 15 - -#define STB_LOCAL 0 -#define STB_GLOBAL 1 -#define STB_WEAK 2 -#define STB_LOPROC 13 -#define STB_HIPROC 15 - -#define STN_UNDEF 0 - - -#define DT_NULL 0 -#define DT_NEEDED 1 -#define DT_PLTRELSZ 2 -#define DT_PLTGOT 3 -#define DT_HASH 4 -#define DT_STRTAB 5 -#define DT_SYMTAB 6 -#define DT_RELA 7 -#define DT_RELASZ 8 -#define DT_RELAENT 9 -#define DT_STRSZ 10 -#define DT_SYMENT 11 -#define DT_INIT 12 -#define DT_FINI 13 -#define DT_SONAME 14 -#define DT_RPATH 15 -#define DT_SYMBOLIC 16 -#define DT_REL 17 -#define DT_RELSZ 18 -#define DT_RELENT 19 -#define DT_PLTREL 20 -#define DT_DEBUG 21 -#define DT_TEXTREL 22 -#define DT_JMPREL 23 -#define DT_BIND_NOW 24 /* no lazy binding */ -#define DT_INIT_ARRAY 25 /* init function array */ -#define DT_FINI_ARRAY 26 /* termination function array */ -#define DT_INIT_ARRAYSZ 27 /* init function array size */ -#define DT_FINI_ARRAYSZ 28 /* termination function array size */ -#define DT_RUNPATH 29 /* library search path (supersedes DT_RPATH) */ -#define DT_FLAGS 30 /* flags (see below) */ -#define DT_ENCODING 32 -#define DT_PREINIT_ARRAY 32 /* preinitialization array */ -#define DT_PREINIT_ARRAYSZ 33 /* preinitialization array size */ - -#define DT_VERSYM 0x6ffffff0 /* symbol version table */ -#define DT_VERDEF 0x6ffffffc /* version definition table */ -#define DT_VERDEFNUM 0x6ffffffd /* number of version definitions */ -#define DT_VERNEED 0x6ffffffe /* table with needed versions */ -#define DT_VERNEEDNUM 0x6fffffff /* number of needed versions */ - -#define DT_LOPROC 0x70000000 -#define DT_HIPROC 0x7fffffff - - -/* DT_FLAGS values */ -#define DF_ORIGIN 0x01 -#define DF_SYMBOLIC 0x02 -#define DF_TEXTREL 0x04 -#define DF_BIND_NOW 0x08 -#define DF_STATIC_TLS 0x10 - - -/* version definition section */ - -/* values for vd_version (version revision) */ -#define VER_DEF_NONE 0 /* no version */ -#define VER_DEF_CURRENT 1 /* current version */ -#define VER_DEF_NUM 2 /* given version number */ - -/* values for vd_flags (version information flags) */ -#define VER_FLG_BASE 0x1 /* version definition of file itself */ -#define VER_FLG_WEAK 0x2 /* weak version identifier */ - -/* values for versym symbol index */ -#define VER_NDX_LOCAL 0 /* symbol is local */ -#define VER_NDX_GLOBAL 1 /* symbol is global/unversioned */ -#define VER_NDX_INITIAL 2 /* initial version -- that's the one given - to symbols when a library becomes - versioned; handled by the linker (and - runtime loader) similar to - VER_NDX_GLOBAL */ -#define VER_NDX_LORESERVE 0xff00 /* beginning of reserved entries */ -#define VER_NDX_ELIMINATE 0xff01 /* symbol is to be eliminated */ - -#define VER_NDX_FLAG_HIDDEN 0x8000 /* flag: version is hidden */ -#define VER_NDX_MASK 0x7fff /* mask to get the actual version index */ -#define VER_NDX(x) ((x) & VER_NDX_MASK) - - -/* version dependency section */ - -/* values for vn_version (version revision) */ -#define VER_NEED_NONE 0 /* no version */ -#define VER_NEED_CURRENT 1 /* current version */ -#define VER_NEED_NUM 2 /* given version number */ - - -/* auxiliary needed version information */ - -/* values for vna_flags */ -#define VER_FLG_WEAK 0x2 /* weak version identifier */ - - -// Determine the correct ELF types to use for the architecture - -#if B_HAIKU_64_BIT -# define _ELF_TYPE(type) Elf64_##type -#else -# define _ELF_TYPE(type) Elf32_##type -#endif -#define DEFINE_ELF_TYPE(type, name) \ - struct _ELF_TYPE(type); \ - typedef struct _ELF_TYPE(type) name - -DEFINE_ELF_TYPE(Ehdr, elf_ehdr); -DEFINE_ELF_TYPE(Phdr, elf_phdr); -DEFINE_ELF_TYPE(Shdr, elf_shdr); -DEFINE_ELF_TYPE(Sym, elf_sym); -DEFINE_ELF_TYPE(Dyn, elf_dyn); -DEFINE_ELF_TYPE(Rel, elf_rel); -DEFINE_ELF_TYPE(Rela, elf_rela); -DEFINE_ELF_TYPE(Verdef, elf_verdef); -DEFINE_ELF_TYPE(Verdaux, elf_verdaux); -DEFINE_ELF_TYPE(Verneed, elf_verneed); -DEFINE_ELF_TYPE(Vernaux, elf_vernaux); - -#undef DEFINE_ELF_TYPE -#undef _ELF_TYPE - -typedef uint16 elf_versym; - -#if B_HAIKU_64_BIT -# define ELF_CLASS ELFCLASS64 -#else -# define ELF_CLASS ELFCLASS32 -#endif - - -#endif /* _ELF_COMMON_H_ */ diff --git a/headers/private/system/elf_private.h b/headers/private/system/elf_private.h new file mode 100644 index 0000000000..ce2f6e2f20 --- /dev/null +++ b/headers/private/system/elf_private.h @@ -0,0 +1,53 @@ +/* + * Copyright 2002-2015 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Copyright 2001 Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ +#ifndef _ELF_PRIVATE_H +#define _ELF_PRIVATE_H + + +#include + +#include + +#include + + +// Determine the correct ELF types to use for the architecture + +#if B_HAIKU_64_BIT +# define _ELF_TYPE(type) Elf64_##type +#else +# define _ELF_TYPE(type) Elf32_##type +#endif +#define DEFINE_ELF_TYPE(type, name) \ + typedef _ELF_TYPE(type) name + +DEFINE_ELF_TYPE(Ehdr, elf_ehdr); +DEFINE_ELF_TYPE(Phdr, elf_phdr); +DEFINE_ELF_TYPE(Shdr, elf_shdr); +DEFINE_ELF_TYPE(Sym, elf_sym); +DEFINE_ELF_TYPE(Dyn, elf_dyn); +DEFINE_ELF_TYPE(Rel, elf_rel); +DEFINE_ELF_TYPE(Rela, elf_rela); +DEFINE_ELF_TYPE(Verdef, elf_verdef); +DEFINE_ELF_TYPE(Verdaux, elf_verdaux); +DEFINE_ELF_TYPE(Verneed, elf_verneed); +DEFINE_ELF_TYPE(Vernaux, elf_vernaux); + +#undef DEFINE_ELF_TYPE +#undef _ELF_TYPE + +typedef uint16 elf_versym; + +#if B_HAIKU_64_BIT +# define ELF_CLASS ELFCLASS64 +#else +# define ELF_CLASS ELFCLASS32 +#endif + + +#endif /* _ELF_PRIVATE_H_ */ diff --git a/headers/private/system/syscalls.h b/headers/private/system/syscalls.h index d89dff7d9e..f71fb3d013 100644 --- a/headers/private/system/syscalls.h +++ b/headers/private/system/syscalls.h @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/src/apps/debugger/elf/ElfFile.cpp b/src/apps/debugger/elf/ElfFile.cpp index bbe6d1ce68..d950f4513f 100644 --- a/src/apps/debugger/elf/ElfFile.cpp +++ b/src/apps/debugger/elf/ElfFile.cpp @@ -356,12 +356,12 @@ ElfFile::_CheckElfHeader(Elf32_Ehdr& elfHeader) && elfHeader.e_ident[4] == ELFCLASS32 && elfHeader.e_shoff > 0 && elfHeader.e_shnum > 0 - && elfHeader.e_shentsize >= sizeof(struct Elf32_Shdr) + && elfHeader.e_shentsize >= sizeof(Elf32_Shdr) && elfHeader.e_shstrndx != SHN_UNDEF && elfHeader.e_shstrndx < elfHeader.e_shnum && elfHeader.e_phoff > 0 && elfHeader.e_phnum > 0 - && elfHeader.e_phentsize >= sizeof(struct Elf32_Phdr); + && elfHeader.e_phentsize >= sizeof(Elf32_Phdr); } @@ -372,10 +372,10 @@ ElfFile::_CheckElfHeader(Elf64_Ehdr& elfHeader) && elfHeader.e_ident[4] == ELFCLASS64 && elfHeader.e_shoff > 0 && elfHeader.e_shnum > 0 - && elfHeader.e_shentsize >= sizeof(struct Elf64_Shdr) + && elfHeader.e_shentsize >= sizeof(Elf64_Shdr) && elfHeader.e_shstrndx != SHN_UNDEF && elfHeader.e_shstrndx < elfHeader.e_shnum && elfHeader.e_phoff > 0 && elfHeader.e_phnum > 0 - && elfHeader.e_phentsize >= sizeof(struct Elf64_Phdr); + && elfHeader.e_phentsize >= sizeof(Elf64_Phdr); } diff --git a/src/apps/debugger/elf/ElfFile.h b/src/apps/debugger/elf/ElfFile.h index b5069437c4..e4c6ab01d4 100644 --- a/src/apps/debugger/elf/ElfFile.h +++ b/src/apps/debugger/elf/ElfFile.h @@ -9,8 +9,7 @@ #include -#include -#include +#include #include #include "Types.h" diff --git a/src/kits/debug/Image.h b/src/kits/debug/Image.h index 2d5cbbef8d..1472bcb0cd 100644 --- a/src/kits/debug/Image.h +++ b/src/kits/debug/Image.h @@ -8,7 +8,7 @@ #include -#include +#include #include #include diff --git a/src/system/boot/loader/elf.cpp b/src/system/boot/loader/elf.cpp index 266fec8657..f77ebe28f0 100644 --- a/src/system/boot/loader/elf.cpp +++ b/src/system/boot/loader/elf.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include @@ -710,7 +710,7 @@ elf_relocate_image(preloaded_image* image) status_t -boot_elf_resolve_symbol(preloaded_elf32_image* image, struct Elf32_Sym* symbol, +boot_elf_resolve_symbol(preloaded_elf32_image* image, Elf32_Sym* symbol, Elf32_Addr* symbolAddress) { return ELF32Loader::Resolve(image, symbol, symbolAddress); @@ -719,7 +719,7 @@ boot_elf_resolve_symbol(preloaded_elf32_image* image, struct Elf32_Sym* symbol, #ifdef BOOT_SUPPORT_ELF64 status_t -boot_elf_resolve_symbol(preloaded_elf64_image* image, struct Elf64_Sym* symbol, +boot_elf_resolve_symbol(preloaded_elf64_image* image, Elf64_Sym* symbol, Elf64_Addr* symbolAddress) { return ELF64Loader::Resolve(image, symbol, symbolAddress); diff --git a/src/system/kernel/arch/arm/arch_elf.cpp b/src/system/kernel/arch/arm/arch_elf.cpp index 62fc17efd5..f19ab0e0cb 100644 --- a/src/system/kernel/arch/arm/arch_elf.cpp +++ b/src/system/kernel/arch/arm/arch_elf.cpp @@ -164,12 +164,12 @@ is_in_image(struct elf_image_info *image, addr_t address) #ifdef _BOOT_MODE status_t -boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image, - struct Elf32_Rel *rel, int relLength) +boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image, Elf32_Rel *rel, + int relLength) #else int arch_elf_relocate_rel(struct elf_image_info *image, - struct elf_image_info *resolveImage, struct Elf32_Rel *rel, int relLength) + struct elf_image_info *resolveImage, Elf32_Rel *rel, int relLength) #endif { addr_t S; @@ -181,7 +181,7 @@ arch_elf_relocate_rel(struct elf_image_info *image, S = A = P = 0; - for (i = 0; i * (int)sizeof(struct Elf32_Rel) < relLength; i++) { + for (i = 0; i * (int)sizeof(Elf32_Rel) < relLength; i++) { TRACE(("looking at rel type %s, offset 0x%lx\n", kRelocations[ELF32_R_TYPE(rel[i].r_info)], rel[i].r_offset)); @@ -191,7 +191,7 @@ arch_elf_relocate_rel(struct elf_image_info *image, case R_ARM_GLOB_DAT: case R_ARM_ABS32: { - struct Elf32_Sym *symbol; + Elf32_Sym *symbol; status_t status; symbol = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); @@ -309,15 +309,15 @@ write_8_check(addr_t P, Elf32_Word value) #ifdef _BOOT_MODE status_t boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image, - struct Elf32_Rela *rel, int rel_len) + Elf32_Rela *rel, int rel_len) #else int arch_elf_relocate_rela(struct elf_image_info *image, - struct elf_image_info *resolve_image, struct Elf32_Rela *rel, int rel_len) + struct elf_image_info *resolve_image, Elf32_Rela *rel, int rel_len) #endif { int i; - struct Elf32_Sym *sym; + Elf32_Sym *sym; int vlErr; addr_t S = 0; // symbol address addr_t R = 0; // section relative symbol address @@ -345,7 +345,7 @@ arch_elf_relocate_rela(struct elf_image_info *image, return B_ERROR; \ } - for (i = 0; i * (int)sizeof(struct Elf32_Rela) < rel_len; i++) { + for (i = 0; i * (int)sizeof(Elf32_Rela) < rel_len; i++) { #if CHATTY dprintf("looking at rel type %d, offset 0x%lx, " "sym 0x%lx, addend 0x%lx\n", ELF32_R_TYPE(rel[i].r_info), diff --git a/src/system/kernel/arch/m68k/arch_elf.cpp b/src/system/kernel/arch/m68k/arch_elf.cpp index 2251f030dd..2a53554622 100644 --- a/src/system/kernel/arch/m68k/arch_elf.cpp +++ b/src/system/kernel/arch/m68k/arch_elf.cpp @@ -76,12 +76,12 @@ static const char *kRelocations[] = { #ifdef _BOOT_MODE status_t -boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image, - struct Elf32_Rel *rel, int rel_len) +boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image, Elf32_Rel *rel, + int rel_len) #else int arch_elf_relocate_rel(struct elf_image_info *image, - struct elf_image_info *resolve_image, struct Elf32_Rel *rel, int rel_len) + struct elf_image_info *resolve_image, Elf32_Rel *rel, int rel_len) #endif { // there are no rel entries in M68K elf @@ -138,15 +138,15 @@ write_8_check(addr_t P, Elf32_Word value) #ifdef _BOOT_MODE status_t boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image, - struct Elf32_Rela *rel, int rel_len) + Elf32_Rela *rel, int rel_len) #else int arch_elf_relocate_rela(struct elf_image_info *image, - struct elf_image_info *resolve_image, struct Elf32_Rela *rel, int rel_len) + struct elf_image_info *resolve_image, Elf32_Rela *rel, int rel_len) #endif { int i; - struct Elf32_Sym *sym; + Elf32_Sym *sym; int vlErr; addr_t S = 0; // symbol address addr_t R = 0; // section relative symbol address @@ -172,7 +172,7 @@ arch_elf_relocate_rela(struct elf_image_info *image, return B_ERROR; \ } - for (i = 0; i * (int)sizeof(struct Elf32_Rela) < rel_len; i++) { + for (i = 0; i * (int)sizeof(Elf32_Rela) < rel_len; i++) { #if CHATTY dprintf("looking at rel type %d, offset 0x%lx, sym 0x%lx, addend 0x%lx\n", ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), rel[i].r_addend); diff --git a/src/system/kernel/arch/ppc/arch_elf.cpp b/src/system/kernel/arch/ppc/arch_elf.cpp index 75f6728f5b..47c25a2fe8 100644 --- a/src/system/kernel/arch/ppc/arch_elf.cpp +++ b/src/system/kernel/arch/ppc/arch_elf.cpp @@ -21,12 +21,12 @@ #ifdef _BOOT_MODE status_t -boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image, - struct Elf32_Rel *rel, int rel_len) +boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image, Elf32_Rel *rel, + int rel_len) #else int arch_elf_relocate_rel(struct elf_image_info *image, - struct elf_image_info *resolve_image, struct Elf32_Rel *rel, int rel_len) + struct elf_image_info *resolve_image, Elf32_Rel *rel, int rel_len) #endif { // there are no rel entries in PPC elf @@ -116,15 +116,15 @@ ha(Elf32_Word value) #ifdef _BOOT_MODE status_t boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image, - struct Elf32_Rela *rel, int rel_len) + Elf32_Rela *rel, int rel_len) #else int arch_elf_relocate_rela(struct elf_image_info *image, - struct elf_image_info *resolve_image, struct Elf32_Rela *rel, int rel_len) + struct elf_image_info *resolve_image, Elf32_Rela *rel, int rel_len) #endif { int i; - struct Elf32_Sym *sym; + Elf32_Sym *sym; int vlErr; addr_t S = 0; // symbol address addr_t R = 0; // section relative symbol address @@ -150,7 +150,7 @@ arch_elf_relocate_rela(struct elf_image_info *image, return B_ERROR; \ } - for (i = 0; i * (int)sizeof(struct Elf32_Rela) < rel_len; i++) { + for (i = 0; i * (int)sizeof(Elf32_Rela) < rel_len; i++) { #if CHATTY dprintf("looking at rel type %d, offset 0x%lx, sym 0x%lx, addend 0x%lx\n", ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), rel[i].r_addend); diff --git a/src/system/kernel/arch/x86/arch_elf.cpp b/src/system/kernel/arch/x86/arch_elf.cpp index 111329a3c2..eef0c8c71e 100644 --- a/src/system/kernel/arch/x86/arch_elf.cpp +++ b/src/system/kernel/arch/x86/arch_elf.cpp @@ -59,12 +59,12 @@ static const char *kRelocations[] = { #ifdef _BOOT_MODE status_t -boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image, - struct Elf32_Rel *rel, int relLength) +boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image, Elf32_Rel *rel, + int relLength) #else int arch_elf_relocate_rel(struct elf_image_info *image, - struct elf_image_info *resolveImage, struct Elf32_Rel *rel, int relLength) + struct elf_image_info *resolveImage, Elf32_Rel *rel, int relLength) #endif { addr_t S; @@ -76,7 +76,7 @@ arch_elf_relocate_rel(struct elf_image_info *image, S = A = P = 0; - for (i = 0; i * (int)sizeof(struct Elf32_Rel) < relLength; i++) { + for (i = 0; i * (int)sizeof(Elf32_Rel) < relLength; i++) { TRACE(("looking at rel type %s, offset 0x%lx\n", kRelocations[ELF32_R_TYPE(rel[i].r_info)], rel[i].r_offset)); @@ -88,7 +88,7 @@ arch_elf_relocate_rel(struct elf_image_info *image, case R_386_JMP_SLOT: case R_386_GOTOFF: { - struct Elf32_Sym *symbol; + Elf32_Sym *symbol; status_t status; symbol = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); @@ -171,11 +171,11 @@ arch_elf_relocate_rel(struct elf_image_info *image, #ifdef _BOOT_MODE status_t boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image, - struct Elf32_Rela *rel, int relLength) + Elf32_Rela *rel, int relLength) #else int arch_elf_relocate_rela(struct elf_image_info *image, - struct elf_image_info *resolveImage, struct Elf32_Rela *rel, int relLength) + struct elf_image_info *resolveImage, Elf32_Rela *rel, int relLength) #endif { dprintf("arch_elf_relocate_rela: not supported on x86\n"); diff --git a/src/system/runtime_loader/arch/m68k/arch_relocate.cpp b/src/system/runtime_loader/arch/m68k/arch_relocate.cpp index 7b24c6dcd6..ae8510ee29 100644 --- a/src/system/runtime_loader/arch/m68k/arch_relocate.cpp +++ b/src/system/runtime_loader/arch/m68k/arch_relocate.cpp @@ -72,8 +72,8 @@ write_8_check(addr_t *P, Elf32_Word value) static int -relocate_rela(image_t *rootImage, image_t *image, struct Elf32_Rela *rel, - int rel_len, SymbolLookupCache* cache) +relocate_rela(image_t *rootImage, image_t *image, Elf32_Rela *rel, int rel_len, + SymbolLookupCache* cache) { int i; addr_t S; @@ -84,7 +84,7 @@ relocate_rela(image_t *rootImage, image_t *image, struct Elf32_Rela *rel, #define A ((addr_t)rel[i].r_addend) # define B (image->regions[0].delta) - for (i = 0; i * (int)sizeof(struct Elf32_Rel) < rel_len; i++) { + for (i = 0; i * (int)sizeof(Elf32_Rel) < rel_len; i++) { unsigned type = ELF32_R_TYPE(rel[i].r_info); switch (type) { @@ -97,7 +97,7 @@ relocate_rela(image_t *rootImage, image_t *image, struct Elf32_Rela *rel, case R_68K_GLOB_DAT: case R_68K_JMP_SLOT: { - struct Elf32_Sym *sym; + Elf32_Sym *sym; status_t status; sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); @@ -303,7 +303,7 @@ arch_relocate_image(image_t *rootImage, image_t *image, //TRACE(("RELA relocations not supported\n")); //return EOPNOTSUPP; - //for (i = 1; i * (int)sizeof(struct Elf32_Rela) < image->rela_len; i++) { + //for (i = 1; i * (int)sizeof(Elf32_Rela) < image->rela_len; i++) { // printf("rela: type %d\n", ELF32_R_TYPE(image->rela[i].r_info)); //} } diff --git a/src/system/runtime_loader/arch/ppc/arch_relocate.cpp b/src/system/runtime_loader/arch/ppc/arch_relocate.cpp index 6803697213..c6cf79888b 100644 --- a/src/system/runtime_loader/arch/ppc/arch_relocate.cpp +++ b/src/system/runtime_loader/arch/ppc/arch_relocate.cpp @@ -21,8 +21,8 @@ static int -relocate_rel(image_t *rootImage, image_t *image, struct Elf32_Rel *rel, - int rel_len, SymbolLookupCache* cache) +relocate_rel(image_t *rootImage, image_t *image, Elf32_Rel *rel, int rel_len, + SymbolLookupCache* cache) { // ToDo: implement me! @@ -56,7 +56,7 @@ arch_relocate_image(image_t *rootImage, image_t *image, printf("RELA relocations not supported\n"); return EOPNOTSUPP; - //for (i = 1; i * (int)sizeof(struct Elf32_Rela) < image->rela_len; i++) { + //for (i = 1; i * (int)sizeof(Elf32_Rela) < image->rela_len; i++) { // printf("rela: type %d\n", ELF32_R_TYPE(image->rela[i].r_info)); //} } diff --git a/src/system/runtime_loader/arch/x86/arch_relocate.cpp b/src/system/runtime_loader/arch/x86/arch_relocate.cpp index d47f3af629..1e6ac1f0b4 100644 --- a/src/system/runtime_loader/arch/x86/arch_relocate.cpp +++ b/src/system/runtime_loader/arch/x86/arch_relocate.cpp @@ -18,8 +18,8 @@ static int -relocate_rel(image_t *rootImage, image_t *image, struct Elf32_Rel *rel, - int rel_len, SymbolLookupCache* cache) +relocate_rel(image_t *rootImage, image_t *image, Elf32_Rel *rel, int rel_len, + SymbolLookupCache* cache) { int i; addr_t S; @@ -29,7 +29,7 @@ relocate_rel(image_t *rootImage, image_t *image, struct Elf32_Rel *rel, # define A (*(P)) # define B (image->regions[0].delta) - for (i = 0; i * (int)sizeof(struct Elf32_Rel) < rel_len; i++) { + for (i = 0; i * (int)sizeof(Elf32_Rel) < rel_len; i++) { unsigned type = ELF32_R_TYPE(rel[i].r_info); unsigned symbolIndex = ELF32_R_SYM(rel[i].r_info); @@ -133,7 +133,7 @@ arch_relocate_image(image_t* rootImage, image_t* image, TRACE(("RELA relocations not supported\n")); return EOPNOTSUPP; - //for (i = 1; i * (int)sizeof(struct Elf32_Rela) < image->rela_len; i++) { + //for (i = 1; i * (int)sizeof(Elf32_Rela) < image->rela_len; i++) { // printf("rela: type %d\n", ELF32_R_TYPE(image->rela[i].r_info)); //} } diff --git a/src/tests/system/boot/loader/platform_misc.cpp b/src/tests/system/boot/loader/platform_misc.cpp index d4b6699454..7a48116fc4 100644 --- a/src/tests/system/boot/loader/platform_misc.cpp +++ b/src/tests/system/boot/loader/platform_misc.cpp @@ -40,16 +40,16 @@ platform_switch_to_text_mode(void) extern "C" status_t -boot_arch_elf_relocate_rel(struct preloaded_image *image, - struct Elf32_Rel *rel, int rel_len) +boot_arch_elf_relocate_rel(struct preloaded_image *image, Elf32_Rel *rel, + int rel_len) { return B_ERROR; } extern "C" status_t -boot_arch_elf_relocate_rela(struct preloaded_image *image, - struct Elf32_Rela *rel, int rel_len) +boot_arch_elf_relocate_rela(struct preloaded_image *image, Elf32_Rela *rel, + int rel_len) { return B_ERROR; } From f22bfa7665ad66196e05dd87b4b608ee14e8453d Mon Sep 17 00:00:00 2001 From: autonielx Date: Sat, 7 Nov 2015 06:31:43 +0100 Subject: [PATCH 082/370] Update translations from Pootle --- data/catalogs/apps/aboutsystem/ru.catkeys | 2 +- data/catalogs/apps/pairs/ru.catkeys | 5 +++-- data/catalogs/apps/webpositive/ru.catkeys | 3 ++- data/catalogs/apps/webwatch/ru.catkeys | 2 +- data/catalogs/kits/bluetooth/ru.catkeys | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/data/catalogs/apps/aboutsystem/ru.catkeys b/data/catalogs/apps/aboutsystem/ru.catkeys index ed6e539ff3..38498d9492 100644 --- a/data/catalogs/apps/aboutsystem/ru.catkeys +++ b/data/catalogs/apps/aboutsystem/ru.catkeys @@ -8,7 +8,7 @@ Copyright © 1996-2005 Julian R Seward. All rights reserved. AboutView Все %d MiB total AboutView Всего %d МБ Michael Phipps (project founder)\n\n AboutView Michael Phipps (основателю проекта)\n\n %d MiB used (%d%%) AboutView %d МБ использовано (%d%%) -Contains software from the GNU Project, released under the GPL and LGPL licenses:\nGNU C Library, GNU coretools, diffutils, findutils, sharutils, gawk, bison, m4, make, wget, ncurses, termcap, Bourne Again Shell.\nCopyright © The Free Software Foundation. AboutView Содержит программное обеспечение из проекта GNU, выпущен под лицензиями GPL и LGPL:\nGNU библиотека, GNU coretools, diffutils, findutils, sharutils, gawk, bison, m4, make, wget, ncurses, termcap, Bourne Again Shell.\n\nВсе права защищены © Фонд свободного программного обеспечения. +Contains software from the GNU Project, released under the GPL and LGPL licenses:\nGNU C Library, GNU coretools, diffutils, findutils, sharutils, gawk, bison, m4, make, wget, ncurses, termcap, Bourne Again Shell.\nCopyright © The Free Software Foundation. AboutView Содержит программное обеспечение из проекта GNU, выпущен под лицензиями GPL и LGPL:\nGNU библиотека, GNU coretools, diffutils, findutils, sharutils, gawk, bison, m4, make, wget, ncurses, termcap, Bourne Again Shell.\nВсе права защищены © Фонд свободного программного обеспечения. AboutSystem System name О системе Copyright © 2003 Peter Hanappe and others. AboutView Все права защищены © 2003 Peter Hanappe и другие. Copyright © 1994-1997 Mark Kilgard. All rights reserved. AboutView Все права защищены © 1994-1997 Mark Kilgard. diff --git a/data/catalogs/apps/pairs/ru.catkeys b/data/catalogs/apps/pairs/ru.catkeys index 12fe432eb6..88cae547bf 100644 --- a/data/catalogs/apps/pairs/ru.catkeys +++ b/data/catalogs/apps/pairs/ru.catkeys @@ -1,5 +1,6 @@ -1 russian x-vnd.Haiku-Pairs 3324688924 -Pairs did not find enough vector icons to start; it needs at least %zu, found %zu.\n Pairs Don't translate \"%zu\", but make sure to keep them. %app%\n\tразработал Ralf Schülke\n\tВсе права защищены (с) 2008-2010, Haiku Inc.\n\n +1 russian x-vnd.Haiku-Pairs 818003250 +Pairs did not find enough vector icons to start; it needs at least %zu, found %zu.\n Pairs Don't translate \"%zu\", but make sure to keep them. Не найдено достаточно векторных значков для начала игры; необходимо по крайней мере %zu, найдено %zu.\n +%app%\n\twritten by Ralf Schülke\n\tCopyright 2008-2010, Haiku Inc.\n\n PairsWindow %app%\n\tразработал Ralf Schülke\n\tВсе права защищены (с) 2008-2010, Haiku Inc.\n\n Expert (8x8) PairsWindow Эксперт (8x8) Beginner (4x4) PairsWindow Новичок (4x4) You completed the game in {0, plural, one{# click} other{# clicks}}.\n PairsWindow Вы завершили игру в {0, plural, one{# клик} few{# клика} other{# кликов}}.\n diff --git a/data/catalogs/apps/webpositive/ru.catkeys b/data/catalogs/apps/webpositive/ru.catkeys index 1c8926eb6c..c33c97e2a3 100644 --- a/data/catalogs/apps/webpositive/ru.catkeys +++ b/data/catalogs/apps/webpositive/ru.catkeys @@ -1,4 +1,4 @@ -1 russian x-vnd.Haiku-WebPositive 98059607 +1 russian x-vnd.Haiku-WebPositive 3678460971 Show home button Settings Window Показывать кнопку Домой Username: Authentication Panel Имя пользователя: Copy URL to clipboard Download Window Копировать ссылку на загрузку @@ -48,6 +48,7 @@ Restart Download Window Перезапустить Proxy server Settings Window Прокси-сервер Open containing folder Download Window Открыть папку с файлом New window WebPositive Window Новое окно +WebPositive Download Window WebPositive Open Download Window Открыть Reload WebPositive Window Обновить Downloads Download Window Загрузки diff --git a/data/catalogs/apps/webwatch/ru.catkeys b/data/catalogs/apps/webwatch/ru.catkeys index e54f9e599e..51067c02eb 100644 --- a/data/catalogs/apps/webwatch/ru.catkeys +++ b/data/catalogs/apps/webwatch/ru.catkeys @@ -3,4 +3,4 @@ WebWatch System name Веб часы OK WatchView ОК Quit WatchView Выход About WatchView О программе -WebWatch %1\nAn internet time clock for your Deskbar\n\nCreated by Matthijs Hollemans\nmahlzeit@users.sourceforge.net\n\nThanks to Jason Parks for his help.\n WatchView WebWatch %1\nИнтернет-часы для Deskbar\n\Разработал Matthijs Hollemans\nmahlzeit@users.sourceforge.net\n\nСпасибо Jason Parks за его помощь.\n +WebWatch %1\nAn internet time clock for your Deskbar\n\nCreated by Matthijs Hollemans\nmahlzeit@users.sourceforge.net\n\nThanks to Jason Parks for his help.\n WatchView WebWatch %1\nИнтернет-часы для Deskbar\n\nРазработал Matthijs Hollemans\nmahlzeit@users.sourceforge.net\n\nСпасибо Jason Parks за его помощь.\n diff --git a/data/catalogs/kits/bluetooth/ru.catkeys b/data/catalogs/kits/bluetooth/ru.catkeys index 3696074c66..f67da58e37 100644 --- a/data/catalogs/kits/bluetooth/ru.catkeys +++ b/data/catalogs/kits/bluetooth/ru.catkeys @@ -9,7 +9,7 @@ Rendering DeviceClass Рендеринг Phone DeviceClass Телефон 17-33% utilized DeviceClass Использовано 17-33% #ServerNotReady#Not Valid name RemoteDevice #ServerNotReady# Неправильное имя -Combo keyboard/pointing device DeviceClass Клавиатура\указывающее устройство +Combo keyboard/pointing device DeviceClass Комбинированная клавиатура/указывающее устройство Controller DeviceClass Контроллер No service available DeviceClass Сервисы не найдены Wearable DeviceClass A wearable computer Переносной From 8599f4b3308bf9c981e7005e2945c7acef458b1a Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 7 Nov 2015 09:21:45 +0100 Subject: [PATCH 083/370] BPathMonitor: Lock on incoming node monitor messages. The lock was only acquired when paths to watch were added or removed, protecting the data structures against concurrent modification due to addition/removal of entries by the API user. Locking is also required for node monitor messages since these can trigger the data structures to be modified (due to recursive watching and new directories becoming available or due to resyncing of modified ancestor chains). Previously it was possible to corrupt the data structures when node monitor messages were received while still starting to watch a directory structure. This was especially likely in the case of watching devfs directories, as accessing these can trigger device scanning which in turn could possibly add new device entries. Either the path monitor looper or the API user would then trip over the corrupted data structures. Probably fixes #11280. Although I was only able to reproduce crashes on the API side, corruption of the hash tables and corresponding endless loops are quite plausible. Possibly also fixes #12412 if the input_server was in the process of starting to watch entries. It's hard to tell due to the lack of a back trace but would fit the crashes I was able to reproduce with a synthetic test case. --- src/kits/storage/PathMonitor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kits/storage/PathMonitor.cpp b/src/kits/storage/PathMonitor.cpp index 324270ffe2..0a2481a2d1 100644 --- a/src/kits/storage/PathMonitor.cpp +++ b/src/kits/storage/PathMonitor.cpp @@ -903,6 +903,7 @@ PathHandler::MessageReceived(BMessage* message) if (message->FindInt32("opcode", &opcode) != B_OK) return; + BAutolock _(sLocker); switch (opcode) { case B_ENTRY_CREATED: _EntryCreated(message); From c869b2bb07924eef2861b205d19ddafecf27c5e0 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 7 Nov 2015 09:48:26 +0100 Subject: [PATCH 084/370] BPathMonitor: Remove unused headers, some whitespace cleanup. --- src/kits/storage/PathMonitor.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/kits/storage/PathMonitor.cpp b/src/kits/storage/PathMonitor.cpp index 0a2481a2d1..bb6db839ef 100644 --- a/src/kits/storage/PathMonitor.cpp +++ b/src/kits/storage/PathMonitor.cpp @@ -14,10 +14,6 @@ #include #include -#include -#include -#include - #include #include #include @@ -185,7 +181,7 @@ public: fIsDirectory = S_ISDIR(st.st_mode); // start watching - uint32 flags = fChild == NULL ? pathFlags : B_WATCH_DIRECTORY; + uint32 flags = fChild == NULL ? pathFlags : B_WATCH_DIRECTORY; // In theory B_WATCH_NAME would suffice for all existing ancestors, // plus B_WATCH_DIRECTORY for the parent of the first not existing // ancestor. In practice this complicates the transitions when an @@ -582,7 +578,7 @@ private: status_t _AddNode(const node_ref& nodeRef, bool isDirectory, bool notify, - Entry* entry = NULL, Node** _node = NULL); + Entry* entry = NULL, Node** _node = NULL); void _DeleteNode(Node* node, bool notify); Node* _GetNode(const node_ref& nodeRef) const; @@ -605,7 +601,7 @@ private: void _NotifyEntryMoved(const entry_ref& fromEntryRef, const entry_ref& toEntryRef, const node_ref& nodeRef, - const char* fromPath, const char* path, + const char* fromPath, const char* path, bool isDirectory, bool wasAdded, bool wasRemoved) const; void _NotifyTarget(BMessage& message, From 702f1b2e8838b31023b35903f74e3b57c3200a83 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Sat, 7 Nov 2015 14:37:15 +0100 Subject: [PATCH 085/370] Added flag for the Catalan language. Currently used in the user guide and welcome pages. --- data/artwork/icons/flags/CA Catalan | Bin 0 -> 4462 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/artwork/icons/flags/CA Catalan diff --git a/data/artwork/icons/flags/CA Catalan b/data/artwork/icons/flags/CA Catalan new file mode 100644 index 0000000000000000000000000000000000000000..3b079c621e9dd64adb4d86bb4f8263876196680c GIT binary patch literal 4462 zcmeHK&r20i6h5z)X(}a!QG_rpvZ75cB50BNDlO2g6e@ZI({s$p_hw{f`b8x!A|$YO z(Xwb4v}(~V!A<=U(Z7%pxhZ&k-<@~IndxbR5(RniI&;5!?m6e3bMCokP7eO7Kx(t146Uk$}A;p8K+Lx0}(%(NkNEw&O2%@N*G)DOL4I(Di@W7rWyx1ag7lO$@ zX$IrITmV-VtG+`NHEOH0R!Sn}utKY-agqN(#HmGYVP_U4FR^J8hE_rW6hy`0Pic_z zBg4lzZ{`As9>`96Z70Cebhk)bugJZ^(zA$n;>CjEGHfR!qkH4`B1^90Sf#)k zl^lpJH%evK=lnl&J)9~%aQ!sgt)DZPlV*Bjt|y=w^fS#Ex_)KO6sgsEpCw=aj@UO`T;<{2Jk1)%kWe50RP~9U&X*|dJh&6(bM4U&g|IE+; z74vAc)^K$MXp$dD$t}B{ylUTB{p;2^qcv;3%t>_?=4J8CF7RdbjV?d+e51=xsyu}5 znVOoa`s3y#GUFnuaTdFNK$*@A>Vuhy?9iFP(z#eOjC@Ls%wlU6EibT}5oduUQ3Ace z;OgQS&j9k!Di+x|z6BU9NoUe-V3e6hc|JK%IKjP#F!o`DMY$p9dAr`ibkF}A5c(ww2;&(A z1l1!I5amPpH6Zozh4p}}=7i9he1?0$jK>n!{GTpnDfOOzi&T^@D z;Ra7%>fxom{H310yxCFkQfD)eL*u7EJ|9C+2e5jV`dh5kyVMtfhy2M)9ernAd?%EW zf9X=E6{*H5x;ZRQ9zhTtGvNh3Ue#s_NYg{CHDS<5@=+{_b9Nc=?ged{B6dRQZU-Oh zHN%?|UC@$aS`zp{@YBKUr*#)ZJB~(jS`+xG2;Y{#i@+J!Jbp!7&dnOXauFGZ1J9kX zq-;BuQ8FiiNI1EUuT?d(@$u*xYD!PsvPbdB9@0X0#SXAow(+cCZ9U Date: Sat, 7 Nov 2015 15:15:35 +0100 Subject: [PATCH 086/370] Updated fish package. Thanks to miqlas! --- build/jam/repositories/HaikuPorts/x86_gcc2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/jam/repositories/HaikuPorts/x86_gcc2 b/build/jam/repositories/HaikuPorts/x86_gcc2 index 4bc54c2352..25fb270472 100644 --- a/build/jam/repositories/HaikuPorts/x86_gcc2 +++ b/build/jam/repositories/HaikuPorts/x86_gcc2 @@ -596,7 +596,7 @@ RemotePackageRepository HaikuPorts faad2_x86_devel-2.7-1 file_x86-5.15-1 file_x86_devel-5.15-1 - fish_x86-1.23.1_git-1 + fish_x86-2.2.0-2 ffmpeg_x86-0.11.5-2 ffmpeg_x86_devel-0.11.5-2 fftw_x86-3.3.4-6 From 4b53c7b1cf1b81bc1f1ca409b4f22290aaf7c137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 7 Nov 2015 16:17:47 +0100 Subject: [PATCH 087/370] automake: update package to 1.15.0-1 I thought it would help fixing the current ARAnyM build, but no. --- build/jam/repositories/HaikuPorts/x86_gcc2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/jam/repositories/HaikuPorts/x86_gcc2 b/build/jam/repositories/HaikuPorts/x86_gcc2 index 25fb270472..3f8c3c6ea5 100644 --- a/build/jam/repositories/HaikuPorts/x86_gcc2 +++ b/build/jam/repositories/HaikuPorts/x86_gcc2 @@ -44,7 +44,7 @@ RemotePackageRepository HaikuPorts armyknife-4.3.0-3 asciidoc-8.6.8-2 autoconf-2.69-5 - automake-1.13.1-4 + automake-1.15.0-1 avra-1.3.0-1 bash-4.3.42-1 beae-1.2-3 From 2e14f933e549e2c03b3d75ad5c8a5fa354b61a1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 21 Oct 2015 20:51:04 +0200 Subject: [PATCH 088/370] Sudoku: minor cleanup. --- src/apps/sudoku/CenteredViewContainer.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/apps/sudoku/CenteredViewContainer.cpp b/src/apps/sudoku/CenteredViewContainer.cpp index 3ce38673f3..3cd278d2dc 100644 --- a/src/apps/sudoku/CenteredViewContainer.cpp +++ b/src/apps/sudoku/CenteredViewContainer.cpp @@ -1,12 +1,16 @@ /* - * Copyright 2007, Michael Pfeiffer, laplace@users.sourceforge.net. All rights reserved. - * Distributed under the terms of the MIT License. + * Copyright 2007, Michael Pfeiffer, laplace@users.sourceforge.net. + * All rights reserved. Distributed under the terms of the MIT License. */ + + #include "CenteredViewContainer.h" -CenteredViewContainer::CenteredViewContainer(BView *target, BRect frame, const char* name, uint32 resizingMode) - : BView(frame, name, resizingMode, B_WILL_DRAW | B_FRAME_EVENTS) - , fTarget(target) + +CenteredViewContainer::CenteredViewContainer(BView* target, const char* name) + : + BView(name, B_WILL_DRAW | B_FRAME_EVENTS), + fTarget(target) { SetViewColor(B_TRANSPARENT_COLOR); // to avoid flickering @@ -18,13 +22,13 @@ CenteredViewContainer::~CenteredViewContainer() { } -void +void CenteredViewContainer::Draw(BRect updateRect) { FillRect(updateRect); } -void +void CenteredViewContainer::FrameResized(float width, float height) { BView::FrameResized(width, height); @@ -40,5 +44,5 @@ void CenteredViewContainer::_CenterTarget(float width, float height) fTarget->ResizeTo(size, size); fTarget->FrameResized(size, size); // in BeOS R5 BView::FrameResized is not (always) called automatically - // after ResizeTo() + // after ResizeTo() } From 5ab027fdc960b9233d9b9c16ee10046b8b93414a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 21 Oct 2015 20:52:20 +0200 Subject: [PATCH 089/370] Sudoku: use the layout API. * This removes the CenteredViewContainer class, as it is no longer being used. * However, it also removes its functionality, ie. the Sudoku view now fills the complete window (even without any borders), again. --- src/apps/sudoku/CenteredViewContainer.cpp | 48 ----------------------- src/apps/sudoku/CenteredViewContainer.h | 27 ------------- src/apps/sudoku/Jamfile | 1 - src/apps/sudoku/SudokuView.cpp | 9 +++++ src/apps/sudoku/SudokuView.h | 2 + src/apps/sudoku/SudokuWindow.cpp | 27 ++++--------- 6 files changed, 19 insertions(+), 95 deletions(-) delete mode 100644 src/apps/sudoku/CenteredViewContainer.cpp delete mode 100644 src/apps/sudoku/CenteredViewContainer.h diff --git a/src/apps/sudoku/CenteredViewContainer.cpp b/src/apps/sudoku/CenteredViewContainer.cpp deleted file mode 100644 index 3cd278d2dc..0000000000 --- a/src/apps/sudoku/CenteredViewContainer.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2007, Michael Pfeiffer, laplace@users.sourceforge.net. - * All rights reserved. Distributed under the terms of the MIT License. - */ - - -#include "CenteredViewContainer.h" - - -CenteredViewContainer::CenteredViewContainer(BView* target, const char* name) - : - BView(name, B_WILL_DRAW | B_FRAME_EVENTS), - fTarget(target) -{ - SetViewColor(B_TRANSPARENT_COLOR); - // to avoid flickering - AddChild(fTarget); - _CenterTarget(frame.Width(), frame.Height()); -} - -CenteredViewContainer::~CenteredViewContainer() -{ -} - -void -CenteredViewContainer::Draw(BRect updateRect) -{ - FillRect(updateRect); -} - -void -CenteredViewContainer::FrameResized(float width, float height) -{ - BView::FrameResized(width, height); - _CenterTarget(width, height); -} - -void CenteredViewContainer::_CenterTarget(float width, float height) -{ - float size = width < height ? width : height; - float left = floor((width - size) / 2); - float top = floor((height - size) / 2); - fTarget->MoveTo(left, top); - fTarget->ResizeTo(size, size); - fTarget->FrameResized(size, size); - // in BeOS R5 BView::FrameResized is not (always) called automatically - // after ResizeTo() -} diff --git a/src/apps/sudoku/CenteredViewContainer.h b/src/apps/sudoku/CenteredViewContainer.h deleted file mode 100644 index 3c3b04df0b..0000000000 --- a/src/apps/sudoku/CenteredViewContainer.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2007, Michael Pfeiffer, laplace@users.sourceforge.net. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef CENTERED_VIEW_CONTAINER_H -#define CENTERED_VIEW_CONTAINER_H - - -#include - - - -class CenteredViewContainer : public BView { -public: - CenteredViewContainer(BView *target, BRect frame, const char* name, uint32 resizingMode); - virtual ~CenteredViewContainer(); - - void Draw(BRect updateRect); - void FrameResized(float width, float height); - -private: - void _CenterTarget(float width, float height); - - BView *fTarget; -}; - -#endif // CENTERED_VIEW_CONTAINER_H diff --git a/src/apps/sudoku/Jamfile b/src/apps/sudoku/Jamfile index 5724d0a6f9..7f7176eb6d 100644 --- a/src/apps/sudoku/Jamfile +++ b/src/apps/sudoku/Jamfile @@ -3,7 +3,6 @@ SubDir HAIKU_TOP src apps sudoku ; UsePrivateHeaders shared ; Application Sudoku : - CenteredViewContainer.cpp ProgressWindow.cpp Sudoku.cpp SudokuField.cpp diff --git a/src/apps/sudoku/SudokuView.cpp b/src/apps/sudoku/SudokuView.cpp index ae12cc39fc..d2a1324abd 100644 --- a/src/apps/sudoku/SudokuView.cpp +++ b/src/apps/sudoku/SudokuView.cpp @@ -61,6 +61,15 @@ SudokuView::SudokuView(BRect frame, const char* name, } +SudokuView::SudokuView(const char* name, const BMessage& settings) + : + BView(name, + B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS) +{ + _InitObject(&settings); +} + + SudokuView::SudokuView(BMessage* archive) : BView(archive) diff --git a/src/apps/sudoku/SudokuView.h b/src/apps/sudoku/SudokuView.h index 15239bd7ad..ae30889fea 100644 --- a/src/apps/sudoku/SudokuView.h +++ b/src/apps/sudoku/SudokuView.h @@ -35,6 +35,8 @@ public: SudokuView(BRect frame, const char* name, const BMessage& settings, uint32 resizingMode); + SudokuView(const char* name, + const BMessage& settings); SudokuView(BMessage* archive); virtual ~SudokuView(); diff --git a/src/apps/sudoku/SudokuWindow.cpp b/src/apps/sudoku/SudokuWindow.cpp index 73e87b699f..f84dd5aa8d 100644 --- a/src/apps/sudoku/SudokuWindow.cpp +++ b/src/apps/sudoku/SudokuWindow.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -22,7 +23,6 @@ #include -#include "CenteredViewContainer.h" #include "ProgressWindow.h" #include "Sudoku.h" #include "SudokuField.h" @@ -176,27 +176,16 @@ SudokuWindow::SudokuWindow() int32 level = 0; settings.FindInt32("level", &level); - // create GUI + // Create GUI - BMenuBar* menuBar = new BMenuBar(Bounds(), "menu"); - AddChild(menuBar); + BMenuBar* menuBar = new BMenuBar("menu"); + fSudokuView = new SudokuView("sudoku view", settings); - frame.top = menuBar->Frame().bottom; + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) + .Add(menuBar) + .Add(fSudokuView); - BView* top = new BView(frame, NULL, B_FOLLOW_ALL, B_WILL_DRAW); - top->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - AddChild(top); - - fSudokuView = new SudokuView( - top->Bounds().InsetByCopy(10, 10).OffsetToSelf(0, 0), - "sudoku view", settings, B_FOLLOW_NONE); - CenteredViewContainer* container = new CenteredViewContainer(fSudokuView, - top->Bounds().InsetByCopy(10, 10), - "center", B_FOLLOW_ALL); - container->SetHighColor(top->ViewColor()); - top->AddChild(container); - - // add menu + // Build menu // "File" menu BMenu* menu = new BMenu(B_TRANSLATE("File")); From d5607aa9715fe0fecd7da33cbef9ddc96c137cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 7 Nov 2015 15:29:03 +0100 Subject: [PATCH 090/370] SMTP: properly use const, and extern "C". * This fixes having it picked up in the mail_daemon. That shouldn't have worked in the last three years... --- src/add-ons/mail_daemon/outbound_protocols/smtp/SMTP.cpp | 8 ++++---- src/add-ons/mail_daemon/outbound_protocols/smtp/SMTP.h | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/add-ons/mail_daemon/outbound_protocols/smtp/SMTP.cpp b/src/add-ons/mail_daemon/outbound_protocols/smtp/SMTP.cpp index 59ad170d0d..b0cb38c14a 100644 --- a/src/add-ons/mail_daemon/outbound_protocols/smtp/SMTP.cpp +++ b/src/add-ons/mail_daemon/outbound_protocols/smtp/SMTP.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2007-2013, Haiku, Inc. All rights reserved. + * Copyright 2007-2015, Haiku, Inc. All rights reserved. * Copyright 2001-2002 Dr. Zoidberg Enterprises. All rights reserved. * Copyright 2011, Clemens Zeidler * @@ -246,7 +246,7 @@ SplitChallengeIntoMap(BString str, map& m) // #pragma mark - -SMTPProtocol::SMTPProtocol(BMailAccountSettings& settings) +SMTPProtocol::SMTPProtocol(const BMailAccountSettings& settings) : BOutboundMailProtocol(settings), fAuthType(0) @@ -1061,8 +1061,8 @@ SMTPProtocol::SendCommand(const char *cmd) // #pragma mark - -BOutboundMailProtocol* -instantiate_outbound_protocol(BMailAccountSettings& settings) +extern "C" BOutboundMailProtocol* +instantiate_outbound_protocol(const BMailAccountSettings& settings) { return new SMTPProtocol(settings); } diff --git a/src/add-ons/mail_daemon/outbound_protocols/smtp/SMTP.h b/src/add-ons/mail_daemon/outbound_protocols/smtp/SMTP.h index 243511d64c..1bf47baf8d 100644 --- a/src/add-ons/mail_daemon/outbound_protocols/smtp/SMTP.h +++ b/src/add-ons/mail_daemon/outbound_protocols/smtp/SMTP.h @@ -1,5 +1,5 @@ /* - * Copyright 2007-2012, Haiku Inc. All Rights Reserved. + * Copyright 2007-2015, Haiku Inc. All Rights Reserved. * Copyright 2001-2002 Dr. Zoidberg Enterprises. All rights reserved. * Copyright 2011, Clemens Zeidler * @@ -23,7 +23,8 @@ class SMTPProtocol : public BOutboundMailProtocol { public: - SMTPProtocol(BMailAccountSettings& settings); + SMTPProtocol( + const BMailAccountSettings& settings); virtual ~SMTPProtocol(); status_t Connect(); From d0ac609964842f8cdb6d54b3c539c6c15293e172 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Sat, 7 Nov 2015 16:37:05 +0100 Subject: [PATCH 091/370] Use B_USE_WINDOW_SPACING Use B_USE_WINDOW_SPACING as inset from contents to window border. Some whitespace cleanup. --- src/apps/activitymonitor/ActivityWindow.cpp | 2 +- src/apps/bootmanager/WizardView.cpp | 8 ++++---- src/apps/charactermap/CharacterWindow.cpp | 5 ++--- src/apps/codycam/CodyCam.cpp | 8 ++++---- src/apps/deskbar/PreferencesWindow.cpp | 11 ++++------- src/apps/devices/DevicesView.cpp | 2 +- src/apps/diskprobe/OpenWindow.cpp | 2 +- src/apps/diskprobe/ProbeView.cpp | 3 ++- src/apps/diskprobe/TypeEditors.cpp | 2 +- src/apps/diskusage/MainWindow.cpp | 2 +- src/apps/expander/ExpanderWindow.cpp | 6 +++--- src/apps/installer/EULAWindow.cpp | 6 +++--- src/apps/installer/InstallerWindow.cpp | 12 +++++------- .../mediaconverter/MediaConverterWindow.cpp | 2 +- .../mediaplayer/settings/SettingsWindow.cpp | 6 ++++-- src/apps/people/PersonView.cpp | 7 ++----- src/apps/people/PersonWindow.cpp | 6 ++++-- src/apps/poorman/PoorManAdvancedView.cpp | 5 +++-- src/apps/poorman/PoorManLoggingView.cpp | 17 +++++++++-------- src/apps/poorman/PoorManPreferencesWindow.cpp | 12 ++++++------ src/apps/poorman/PoorManSiteView.cpp | 15 ++++++++------- src/apps/screenshot/ScreenshotApp.cpp | 8 ++++---- src/apps/screenshot/ScreenshotWindow.cpp | 5 +++-- src/apps/terminal/PrefWindow.cpp | 2 +- src/apps/text_search/GrepWindow.cpp | 10 +++++----- src/apps/webpositive/SettingsWindow.cpp | 15 +++++++++------ src/kits/tracker/FindPanel.cpp | 2 +- src/kits/tracker/TrackerSettingsWindow.cpp | 10 +++++----- src/preferences/appearance/APRWindow.cpp | 2 +- .../datatranslations/DataTranslationsWindow.cpp | 2 +- .../filetypes/ApplicationTypesWindow.cpp | 5 +++-- src/preferences/filetypes/FileTypesWindow.cpp | 6 +++--- src/preferences/keymap/KeymapWindow.cpp | 7 +++---- src/preferences/keymap/ModifierKeysWindow.cpp | 2 +- src/preferences/media/MediaWindow.cpp | 5 ++--- src/preferences/network/NetworkWindow.cpp | 2 +- src/preferences/printers/PrintersWindow.cpp | 4 ++-- src/preferences/screen/ScreenWindow.cpp | 2 +- .../screensaver/ScreenSaverWindow.cpp | 10 ++++++---- src/preferences/shortcuts/ShortcutsWindow.cpp | 2 +- src/preferences/sounds/HWindow.cpp | 2 +- src/preferences/touchpad/TouchpadPrefView.cpp | 2 +- .../virtualmemory/SettingsWindow.cpp | 2 +- 43 files changed, 125 insertions(+), 121 deletions(-) diff --git a/src/apps/activitymonitor/ActivityWindow.cpp b/src/apps/activitymonitor/ActivityWindow.cpp index 010db6be41..ce5961cdb0 100644 --- a/src/apps/activitymonitor/ActivityWindow.cpp +++ b/src/apps/activitymonitor/ActivityWindow.cpp @@ -64,7 +64,7 @@ ActivityWindow::ActivityWindow() fLayout = new BGroupLayout(B_VERTICAL); float inset = ceilf(be_plain_font->Size() * 0.7); - fLayout->SetInsets(inset, inset, inset, inset); + fLayout->SetInsets(B_USE_WINDOW_SPACING); fLayout->SetSpacing(inset); BView* top = new BView("top", 0, fLayout); diff --git a/src/apps/bootmanager/WizardView.cpp b/src/apps/bootmanager/WizardView.cpp index 6a69e8956d..d565f7e226 100644 --- a/src/apps/bootmanager/WizardView.cpp +++ b/src/apps/bootmanager/WizardView.cpp @@ -118,8 +118,8 @@ void WizardView::_BuildUI() { fPageContainer = new BGroupView("page container"); - fPageContainer->GroupLayout()->SetInsets(B_USE_DEFAULT_SPACING, - B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING); + fPageContainer->GroupLayout()->SetInsets(B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING); fPrevious = new BButton("previous", B_TRANSLATE_COMMENT("Previous", "Button"), new BMessage(kMessagePrevious)); @@ -132,8 +132,8 @@ WizardView::_BuildUI() .Add(fPageContainer) .Add(new BSeparatorView(B_HORIZONTAL)) .AddGroup(B_HORIZONTAL) - .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, - B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, + B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING) .Add(quit) .AddGlue() .Add(fPrevious) diff --git a/src/apps/charactermap/CharacterWindow.cpp b/src/apps/charactermap/CharacterWindow.cpp index bffd98080a..6d011faa6e 100644 --- a/src/apps/charactermap/CharacterWindow.cpp +++ b/src/apps/charactermap/CharacterWindow.cpp @@ -228,11 +228,10 @@ CharacterWindow::CharacterWindow() fCharacterView->SetExplicitMinSize(BSize(viewFont.StringWidth("w") * 40, B_SIZE_UNSET)); - BLayoutBuilder::Group<>(this, B_VERTICAL) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .Add(menuBar) .AddGroup(B_HORIZONTAL) - .SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING, - B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) .AddGroup(B_VERTICAL) .AddGroup(B_HORIZONTAL) .Add(fFilterControl) diff --git a/src/apps/codycam/CodyCam.cpp b/src/apps/codycam/CodyCam.cpp index 895eca25a1..84e5b54608 100644 --- a/src/apps/codycam/CodyCam.cpp +++ b/src/apps/codycam/CodyCam.cpp @@ -617,7 +617,7 @@ VideoWindow::_BuildCaptureControls() fCaptureSetupBox = new BBox("Capture Controls", B_WILL_DRAW); fCaptureSetupBox->SetLabel(B_TRANSLATE("Capture controls")); - BGridLayout *controlsLayout = new BGridLayout(kXBuffer, 0); + BGridLayout *controlsLayout = new BGridLayout(B_USE_DEFAULT_SPACING, 0); controlsLayout->SetInsets(10, 15, 5, 5); fCaptureSetupBox->SetLayout(controlsLayout); @@ -680,7 +680,7 @@ VideoWindow::_BuildCaptureControls() fUploadClientSelector->SetLabel(B_TRANSLATE("Type:")); - BGridLayout *ftpLayout = new BGridLayout(kXBuffer, 0); + BGridLayout *ftpLayout = new BGridLayout(B_USE_DEFAULT_SPACING, 0); ftpLayout->SetInsets(10, 15, 5, 5); fFtpSetupBox->SetLayout(ftpLayout); @@ -837,10 +837,10 @@ VideoWindow::ToggleMenuOnOff() { BMenuItem* item = fMenu->FindItem(msg_video); item->SetEnabled(!item->IsEnabled()); - + item = fMenu->FindItem(msg_start); item->SetEnabled(!item->IsEnabled()); - + item = fMenu->FindItem(msg_stop); item->SetEnabled(!item->IsEnabled()); } diff --git a/src/apps/deskbar/PreferencesWindow.cpp b/src/apps/deskbar/PreferencesWindow.cpp index c3be5d630b..242126939e 100644 --- a/src/apps/deskbar/PreferencesWindow.cpp +++ b/src/apps/deskbar/PreferencesWindow.cpp @@ -160,8 +160,7 @@ PreferencesWindow::PreferencesWindow(BRect frame) .AddGlue() .Add(BSpaceLayoutItem::CreateVerticalStrut(B_USE_SMALL_SPACING)) .Add(fAppsIconSizeSlider) - .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, - B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_DEFAULT_SPACING) .End() .View()); @@ -187,8 +186,7 @@ PreferencesWindow::PreferencesWindow(BRect frame) .Add(new BButton(B_TRANSLATE("Edit in Tracker" B_UTF8_ELLIPSIS), new BMessage(kEditInTracker))) .AddGlue() - .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, - B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_DEFAULT_SPACING) .End() .View()); @@ -202,8 +200,7 @@ PreferencesWindow::PreferencesWindow(BRect frame) .Add(fWindowAutoRaise) .Add(fWindowAutoHide) .AddGlue() - .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, - B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_DEFAULT_SPACING) .End() .View()); @@ -228,7 +225,7 @@ PreferencesWindow::PreferencesWindow(BRect frame) .Add(fRevertButton) .AddGlue() .End() - .SetInsets(B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) .End(); BMessage windowSettings; diff --git a/src/apps/devices/DevicesView.cpp b/src/apps/devices/DevicesView.cpp index 87609734b7..a487813710 100644 --- a/src/apps/devices/DevicesView.cpp +++ b/src/apps/devices/DevicesView.cpp @@ -95,7 +95,7 @@ DevicesView::CreateLayout() BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .Add(menuBar) .AddSplit(B_HORIZONTAL) - .SetInsets(B_USE_ITEM_INSETS) + .SetInsets(B_USE_WINDOW_SPACING) .AddGroup(B_VERTICAL) .Add(fOrderByMenu, 1) .Add(scrollView, 2) diff --git a/src/apps/diskprobe/OpenWindow.cpp b/src/apps/diskprobe/OpenWindow.cpp index 58b85cc168..a3d26e7ae6 100644 --- a/src/apps/diskprobe/OpenWindow.cpp +++ b/src/apps/diskprobe/OpenWindow.cpp @@ -57,7 +57,7 @@ OpenWindow::OpenWindow() new BMessage(B_QUIT_REQUESTED)); BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) .Add(field) .AddGroup(B_HORIZONTAL) .Add(cancelButton) diff --git a/src/apps/diskprobe/ProbeView.cpp b/src/apps/diskprobe/ProbeView.cpp index e0c1bd3092..863df7075a 100644 --- a/src/apps/diskprobe/ProbeView.cpp +++ b/src/apps/diskprobe/ProbeView.cpp @@ -481,7 +481,8 @@ HeaderView::HeaderView(const entry_ref *ref, DataEditor &editor) fLastPosition(0) { SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - GridLayout()->SetInsets(B_USE_SMALL_SPACING); + GridLayout()->SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING); fIconView = new IconView(ref, editor.IsDevice()); GridLayout()->AddView(fIconView, 0, 0, 1, 2); diff --git a/src/apps/diskprobe/TypeEditors.cpp b/src/apps/diskprobe/TypeEditors.cpp index b2b558578f..1025f5f7f1 100644 --- a/src/apps/diskprobe/TypeEditors.cpp +++ b/src/apps/diskprobe/TypeEditors.cpp @@ -1173,7 +1173,7 @@ MessageView::SetTo(BMessage& message) fTextView->SetText(""); char text[512]; - snprintf(text, sizeof(text), B_TRANSLATE_COMMENT("what: '%.4s'\n\n", + snprintf(text, sizeof(text), B_TRANSLATE_COMMENT("what: '%.4s'\n\n", "'What' is a message specifier that defines the type of the message."), (char*)&message.what); fTextView->Insert(text); diff --git a/src/apps/diskusage/MainWindow.cpp b/src/apps/diskusage/MainWindow.cpp index 9baec79775..f44f051e76 100644 --- a/src/apps/diskusage/MainWindow.cpp +++ b/src/apps/diskusage/MainWindow.cpp @@ -35,7 +35,7 @@ MainWindow::MainWindow(BRect pieRect) AddChild(BLayoutBuilder::Group<>(B_VERTICAL) .Add(fControlsView) - .SetInsets(0, B_USE_WINDOW_INSETS, 0, 0) + .SetInsets(0, B_USE_WINDOW_SPACING, 0, 0) ); float maxHeight = BScreen(this).Frame().Height() - 12; fControlsView->SetExplicitMaxSize(BSize(maxHeight, maxHeight)); diff --git a/src/apps/expander/ExpanderWindow.cpp b/src/apps/expander/ExpanderWindow.cpp index 44b122e8c5..171a50d75c 100644 --- a/src/apps/expander/ExpanderWindow.cpp +++ b/src/apps/expander/ExpanderWindow.cpp @@ -80,9 +80,9 @@ ExpanderWindow::ExpanderWindow(BRect frame, const entry_ref* ref, size.width = std::max(size.width, fSourceButton->PreferredSize().width); size.width = std::max(size.width, fExpandButton->PreferredSize().width); - fDestButton->SetExplicitMaxSize(size); - fSourceButton->SetExplicitMaxSize(size); - fExpandButton->SetExplicitMaxSize(size); + fDestButton->SetExplicitSize(size); + fSourceButton->SetExplicitSize(size); + fExpandButton->SetExplicitSize(size); fListingText = new BTextView("listingText"); fListingText->SetText(""); diff --git a/src/apps/installer/EULAWindow.cpp b/src/apps/installer/EULAWindow.cpp index 9f1f5b6bcc..ca7abd19ea 100644 --- a/src/apps/installer/EULAWindow.cpp +++ b/src/apps/installer/EULAWindow.cpp @@ -142,10 +142,10 @@ EULAWindow::EULAWindow() if (!be_roster->IsRunning(kTrackerSignature)) SetWorkspaces(B_ALL_WORKSPACES); - BLayoutBuilder::Group<>(this, B_VERTICAL, 10) - .SetInsets(10) + BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) .Add(scrollView) - .AddGroup(B_HORIZONTAL, 10) + .AddGroup(B_HORIZONTAL, B_USE_ITEM_SPACING) .AddGlue() .Add(cancelButton) .Add(continueButton); diff --git a/src/apps/installer/InstallerWindow.cpp b/src/apps/installer/InstallerWindow.cpp index 60ec2aa5e8..36564210eb 100644 --- a/src/apps/installer/InstallerWindow.cpp +++ b/src/apps/installer/InstallerWindow.cpp @@ -173,7 +173,7 @@ InstallerWindow::InstallerWindow() fStatusView = new BTextView("statusView", be_plain_font, NULL, B_WILL_DRAW); - fStatusView->SetInsets(10, 10, 10, 10); + fStatusView->SetInsets(10, 0, 10, 0); fStatusView->MakeEditable(false); fStatusView->MakeSelectable(false); @@ -249,15 +249,13 @@ InstallerWindow::InstallerWindow() toolsMenu->AddItem(fMakeBootableItem); mainMenu->AddItem(toolsMenu); - float spacing = be_control_look->DefaultItemSpacing(); - BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .Add(mainMenu) .Add(logoGroup) .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER)) - .AddGroup(B_VERTICAL, spacing) - .SetInsets(spacing) - .AddGrid(new BGridView(0.0f, spacing)) + .AddGroup(B_VERTICAL, B_USE_ITEM_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) + .AddGrid(new BGridView(B_USE_ITEM_SPACING, B_USE_ITEM_SPACING)) .Add(fSrcMenuField->CreateLabelLayoutItem(), 0, 0) .Add(fSrcMenuField->CreateMenuBarLayoutItem(), 1, 0) .Add(fDestMenuField->CreateLabelLayoutItem(), 0, 1) @@ -271,7 +269,7 @@ InstallerWindow::InstallerWindow() .Add(fSizeView, 0, 6, 2) .End() - .AddGroup(B_HORIZONTAL, spacing) + .AddGroup(B_HORIZONTAL, B_USE_WINDOW_SPACING) .Add(fLaunchDriveSetupButton) .AddGlue() .Add(fBeginButton); diff --git a/src/apps/mediaconverter/MediaConverterWindow.cpp b/src/apps/mediaconverter/MediaConverterWindow.cpp index 8116aa6965..8618145ba0 100644 --- a/src/apps/mediaconverter/MediaConverterWindow.cpp +++ b/src/apps/mediaconverter/MediaConverterWindow.cpp @@ -161,7 +161,7 @@ MediaConverterWindow::MediaConverterWindow(BRect frame) { BPath outputDir; if (find_directory(B_USER_DIRECTORY, &outputDir) != B_OK) - outputDir.SetTo("/boot/home"); + outputDir.SetTo("/boot/home"); fOutputDir.SetTo(outputDir.Path()); fMenuBar = new BMenuBar("menubar"); diff --git a/src/apps/mediaplayer/settings/SettingsWindow.cpp b/src/apps/mediaplayer/settings/SettingsWindow.cpp index 97faf4cb75..42f46a2f6f 100644 --- a/src/apps/mediaplayer/settings/SettingsWindow.cpp +++ b/src/apps/mediaplayer/settings/SettingsWindow.cpp @@ -140,7 +140,8 @@ SettingsWindow::SettingsWindow(BRect frame) BGroupLayout* playGroup; BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .AddGroup(settingsLayout) - .SetInsets(kSpacing, kSpacing, kSpacing * 2, 0) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) .Add(playModeLabel) .AddGroup(B_HORIZONTAL, 0) .GetLayout(&playGroup) @@ -186,7 +187,8 @@ SettingsWindow::SettingsWindow(BRect frame) .AddStrut(kSpacing) .End() .AddGroup(buttonLayout) - .SetInsets(kSpacing) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, + B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING) .Add(fRevertB) .AddGlue() .Add(cancelButton) diff --git a/src/apps/people/PersonView.cpp b/src/apps/people/PersonView.cpp index 9d25a22ed3..08be469840 100644 --- a/src/apps/people/PersonView.cpp +++ b/src/apps/people/PersonView.cpp @@ -60,13 +60,10 @@ PersonView::PersonView(const char* name, const char* categoryAttribute, if (fRef != NULL) file = new BFile(fRef, B_READ_ONLY); - float spacing = be_control_look->DefaultItemSpacing(); - BGridLayout* layout = GridLayout(); - layout->SetInsets(spacing, spacing, spacing, spacing); - // Add picture "field", using ID photo 35mm x 45mm ratio fPictureView = new PictureView(70, 90, ref); + BGridLayout* layout = GridLayout(); layout->AddView(fPictureView, 0, 0, 1, 5); layout->ItemAt(0, 0)->SetExplicitAlignment( BAlignment(B_ALIGN_CENTER, B_ALIGN_TOP)); @@ -353,7 +350,7 @@ PersonView::SetAttribute(const char* attribute, bool update) { char* value = NULL; attr_info info; - BFile* file = NULL; + BFile* file = NULL; if (fRef != NULL) file = new(std::nothrow) BFile(fRef, B_READ_ONLY); diff --git a/src/apps/people/PersonWindow.cpp b/src/apps/people/PersonWindow.cpp index 1fc9d7ffe3..41e892cce6 100644 --- a/src/apps/people/PersonWindow.cpp +++ b/src/apps/people/PersonWindow.cpp @@ -108,9 +108,11 @@ PersonWindow::PersonWindow(BRect frame, const char* title, fView = new PersonView("PeopleView", categoryAttribute, fRef); BLayoutBuilder::Group<>(this, B_VERTICAL, 0) - .SetInsets(0, 0, 0, 0) .Add(menuBar) - .Add(fView); + .AddGroup(B_VERTICAL, 0) + .Add(fView) + .SetInsets(B_USE_WINDOW_SPACING) + .End(); fRevert->SetTarget(fView); selectAllItem->SetTarget(fView); diff --git a/src/apps/poorman/PoorManAdvancedView.cpp b/src/apps/poorman/PoorManAdvancedView.cpp index 260da72b9c..3b8e4e47de 100644 --- a/src/apps/poorman/PoorManAdvancedView.cpp +++ b/src/apps/poorman/PoorManAdvancedView.cpp @@ -37,7 +37,7 @@ PoorManAdvancedView::PoorManAdvancedView(const char* name) // labels below the slider 1 and 200 fMaxConnections->SetLimitLabels("1", "200"); SetMaxSimutaneousConnections(win->MaxConnections()); - + BGroupLayout* connectionOptionsLayout = new BGroupLayout(B_VERTICAL, 0); connectionOptions->SetLayout(connectionOptionsLayout); @@ -49,7 +49,8 @@ PoorManAdvancedView::PoorManAdvancedView(const char* name) .Add(fMaxConnections) .End() .AddGlue() - .SetInsets(B_USE_ITEM_INSETS); + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING); } void diff --git a/src/apps/poorman/PoorManLoggingView.cpp b/src/apps/poorman/PoorManLoggingView.cpp index dacef76463..ae9c7901f0 100644 --- a/src/apps/poorman/PoorManLoggingView.cpp +++ b/src/apps/poorman/PoorManLoggingView.cpp @@ -4,7 +4,7 @@ * Started: 5/12/2004 * Version: 0.1 */ - + #include #include #include @@ -26,31 +26,31 @@ PoorManLoggingView::PoorManLoggingView(const char* name) { PoorManWindow* win; win = ((PoorManApplication*)be_app)->GetPoorManWindow(); - + BBox* consoleLogging = new BBox(B_TRANSLATE("Console Logging")); consoleLogging->SetLabel(STR_BBX_CONSOLE_LOGGING); - + // File Logging BBox BBox* fileLogging = new BBox(B_TRANSLATE("File Logging")); fileLogging->SetLabel(STR_BBX_FILE_LOGGING); - + // Console Logging fLogConsole = new BCheckBox(B_TRANSLATE("Log To Console"), STR_CBX_LOG_CONSOLE, new BMessage(MSG_PREF_LOG_CBX_CONSOLE)); // set the checkbox to the value the program has SetLogConsoleValue(win->LogConsoleFlag()); - + // File Logging fLogFile = new BCheckBox(B_TRANSLATE("Log To File"), STR_CBX_LOG_FILE, new BMessage(MSG_PREF_LOG_CBX_FILE)); // set the checkbox to the value the program has SetLogFileValue(win->LogFileFlag()); - + // File Name fLogFileName = new BTextControl(B_TRANSLATE("File Name"), STR_TXT_LOG_FILE_NAME, NULL, NULL); SetLogFileName(win->LogPath()); - + // Create Log File fCreateLogFile = new BButton(B_TRANSLATE("Create Log File"), STR_BTN_CREATE_LOG_FILE, new BMessage(MSG_PREF_LOG_BTN_CREATE_FILE)); @@ -63,7 +63,8 @@ PoorManLoggingView::PoorManLoggingView(const char* name) fileLogging->SetLayout(fileLoggingLayout); BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_ITEM_INSETS) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) .AddGroup(consoleLoggingLayout) .SetInsets(B_USE_ITEM_INSETS) .AddGroup(B_HORIZONTAL) diff --git a/src/apps/poorman/PoorManPreferencesWindow.cpp b/src/apps/poorman/PoorManPreferencesWindow.cpp index d34223b013..31fcc7b616 100644 --- a/src/apps/poorman/PoorManPreferencesWindow.cpp +++ b/src/apps/poorman/PoorManPreferencesWindow.cpp @@ -103,7 +103,7 @@ PoorManPreferencesWindow::MessageReceived(BMessage* message) PoorManServer* server; win = ((PoorManApplication*)be_app)->GetPoorManWindow(); server = win->GetServer(); - + PRINT(("Pref Window: sendDir CheckBox: %d\n", fSiteView->SendDirValue())); server->SetListDir(fSiteView->SendDirValue()); @@ -118,7 +118,7 @@ PoorManPreferencesWindow::MessageReceived(BMessage* message) win->SetDirLabel(fSiteView->WebDir()); } - PRINT(("Pref Window: logConsole CheckBox: %d\n", + PRINT(("Pref Window: logConsole CheckBox: %d\n", fLoggingView->LogConsoleValue())); win->SetLogConsoleFlag(fLoggingView->LogConsoleValue()); PRINT(("Pref Window: logFile CheckBox: %d\n", @@ -127,13 +127,13 @@ PoorManPreferencesWindow::MessageReceived(BMessage* message) PRINT(("Pref Window: logFileName: %s\n", fLoggingView->LogFileName())); win->SetLogPath(fLoggingView->LogFileName()); - + PRINT(("Pref Window: MaxConnections Slider: %" B_PRId32 "\n", fAdvancedView->MaxSimultaneousConnections())); server->SetMaxConns(fAdvancedView->MaxSimultaneousConnections()); win->SetMaxConnections( (int16)fAdvancedView->MaxSimultaneousConnections()); - + if (Lock()) Quit(); break; @@ -190,7 +190,7 @@ PoorManPreferencesWindow::SelectWebDir(BMessage* message) PRINT(("DIR: %s\n", path.Path())); fSiteView->SetWebDir(path.Path()); - + bool temp; if (message->FindBool("Default Dialog", &temp) == B_OK) { PoorManWindow* win = ((PoorManApplication *)be_app)->GetPoorManWindow(); @@ -199,7 +199,7 @@ PoorManPreferencesWindow::SelectWebDir(BMessage* message) win->SetWebDir(fSiteView->WebDir()); win->SetDirLabel(fSiteView->WebDir()); win->SaveSettings(); - win->Show(); + win->Show(); } if (Lock()) Quit(); diff --git a/src/apps/poorman/PoorManSiteView.cpp b/src/apps/poorman/PoorManSiteView.cpp index 3a35cb0ff1..eb602dc51b 100644 --- a/src/apps/poorman/PoorManSiteView.cpp +++ b/src/apps/poorman/PoorManSiteView.cpp @@ -4,7 +4,7 @@ * Started: 5/07/2004 * Version: 0.1 */ - + #include #include @@ -38,24 +38,25 @@ PoorManSiteView::PoorManSiteView(const char* name) // Web Directory Text Control fWebDir = new BTextControl(STR_TXT_DIRECTORY, NULL, NULL); SetWebDir(win->WebDir()); - + // Select Web Directory Button fSelectWebDir = new BButton("Select Web Dir", STR_BTN_DIRECTORY, new BMessage(MSG_PREF_SITE_BTN_SELECT)); - + // Index File Name Text Control fIndexFileName = new BTextControl(STR_TXT_INDEX, NULL, NULL); SetIndexFileName(win->IndexFileName()); - - + + BGroupLayout* webSiteLocationLayout = new BGroupLayout(B_VERTICAL, 0); webSiteLocation->SetLayout(webSiteLocationLayout); - + BGroupLayout* webSiteOptionsLayout = new BGroupLayout(B_VERTICAL, 0); webSiteOptions->SetLayout(webSiteOptionsLayout); BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_ITEM_INSETS) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) .AddGroup(webSiteLocationLayout) .SetInsets(B_USE_ITEM_INSETS) .AddGrid(B_USE_SMALL_SPACING, B_USE_SMALL_SPACING) diff --git a/src/apps/screenshot/ScreenshotApp.cpp b/src/apps/screenshot/ScreenshotApp.cpp index 2855508430..0b5449d57a 100644 --- a/src/apps/screenshot/ScreenshotApp.cpp +++ b/src/apps/screenshot/ScreenshotApp.cpp @@ -87,7 +87,7 @@ ScreenshotApp::MessageReceived(BMessage* message) BApplication::MessageReceived(message); break; } - + if (status != B_OK) be_app->PostMessage(B_QUIT_REQUESTED); } @@ -97,12 +97,12 @@ void ScreenshotApp::ArgvReceived(int32 argc, char** argv) { for (int32 i = 0; i < argc; i++) { - if (strcmp(argv[i], "-s") == 0 + if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--silent") == 0) fSilent = true; - else if (strcmp(argv[i], "-c") == 0 + else if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--clipboard") == 0) - fClipboard = true; + fClipboard = true; } } diff --git a/src/apps/screenshot/ScreenshotWindow.cpp b/src/apps/screenshot/ScreenshotWindow.cpp index c80552f22b..e0525590d3 100644 --- a/src/apps/screenshot/ScreenshotWindow.cpp +++ b/src/apps/screenshot/ScreenshotWindow.cpp @@ -200,8 +200,9 @@ ScreenshotWindow::ScreenshotWindow(const Utility& utility, bool silent, BBox* previewBox = new BBox(B_FANCY_BORDER, fPreview); BLayoutBuilder::Group<>(this, B_VERTICAL, 0) - .SetInsets(kSpacing) - .AddGroup(B_HORIZONTAL, kSpacing) + .AddGroup(B_HORIZONTAL) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) .Add(previewBox) .AddGroup(B_VERTICAL, 0) .Add(fActiveWindow) diff --git a/src/apps/terminal/PrefWindow.cpp b/src/apps/terminal/PrefWindow.cpp index b56f9c65b7..73935ade2b 100644 --- a/src/apps/terminal/PrefWindow.cpp +++ b/src/apps/terminal/PrefWindow.cpp @@ -43,7 +43,7 @@ PrefWindow::PrefWindow(const BMessenger& messenger) BLayoutBuilder::Group<>(this, B_VERTICAL) .AddGroup(B_VERTICAL) - .SetInsets(10, 10, 10, 10) + .SetInsets(B_USE_WINDOW_SPACING) .Add(fAppearanceView = new AppearancePrefView( B_TRANSLATE("Appearance"), fTerminalMessenger)) .AddGroup(B_HORIZONTAL) diff --git a/src/apps/text_search/GrepWindow.cpp b/src/apps/text_search/GrepWindow.cpp index 5e2864e80a..cab747e199 100644 --- a/src/apps/text_search/GrepWindow.cpp +++ b/src/apps/text_search/GrepWindow.cpp @@ -547,19 +547,19 @@ GrepWindow::_LayoutViews() "ScrollSearchResults", fSearchResults, B_FULL_UPDATE_ON_RESIZE, true, true); - BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_HALF_ITEM_SPACING) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .SetInsets(0, 0, -1, -1) .Add(fMenuBar) - .AddGrid(B_USE_HALF_ITEM_SPACING) - .SetInsets(B_USE_ITEM_INSETS, B_USE_HALF_ITEM_INSETS, - B_USE_ITEM_INSETS, 0) + .AddGrid(B_USE_HALF_ITEM_INSETS) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) .Add(fSearchText, 0, 0, 3) .Add(fShowLinesCheckbox, 0, 1) .Add(BSpaceLayoutItem::CreateGlue(), 1, 1) .Add(fButton, 2, 1) .End() .AddGroup(B_VERTICAL, 0) - .SetInsets(-1, 0, -1, -1) + .SetInsets(-2, 0, -1, -1) .Add(scroller) .End() .End(); diff --git a/src/apps/webpositive/SettingsWindow.cpp b/src/apps/webpositive/SettingsWindow.cpp index ae71aee8f2..36d75cfb1d 100644 --- a/src/apps/webpositive/SettingsWindow.cpp +++ b/src/apps/webpositive/SettingsWindow.cpp @@ -331,7 +331,7 @@ SettingsWindow::_CreateGeneralPage(float spacing) new BMessage(MSG_SHOW_HOME_BUTTON_CHANGED)); fShowHomeButton->SetValue(B_CONTROL_ON); - BView* view = BGroupLayoutBuilder(B_VERTICAL, spacing / 2) + BView* view = BGroupLayoutBuilder(B_VERTICAL, 0) .Add(BGridLayoutBuilder(spacing / 2, spacing / 2) .Add(fStartPageControl->CreateLabelLayoutItem(), 0, 0) .Add(fStartPageControl->CreateTextViewLayoutItem(), 1, 0) @@ -355,10 +355,11 @@ SettingsWindow::_CreateGeneralPage(float spacing) .Add(fAutoHideInterfaceInFullscreenMode) .Add(fAutoHidePointer) .Add(fShowHomeButton) - .Add(fDaysInHistory) .Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing)) + .Add(fDaysInHistory) - .SetInsets(spacing, spacing, spacing, spacing) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) .TopView() ; @@ -417,7 +418,8 @@ SettingsWindow::_CreateFontsPage(float spacing) .Add(fFixedSizesMenu->CreateLabelLayoutItem(), 0, 13) .Add(fFixedSizesMenu->CreateMenuBarLayoutItem(), 1, 13) - .SetInsets(spacing, spacing, spacing, spacing) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) .View() ; @@ -473,7 +475,7 @@ SettingsWindow::_CreateProxyPage(float spacing) fProxyPasswordControl->SetText( fSettings->GetValue(kSettingsKeyProxyPassword, "")); - BView* view = BGroupLayoutBuilder(B_VERTICAL, spacing / 2) + BView* view = BGroupLayoutBuilder(B_VERTICAL, 0) .Add(fUseProxyCheckBox) .Add(BGridLayoutBuilder(spacing / 2, spacing / 2) .Add(fProxyAddressControl->CreateLabelLayoutItem(), 0, 0) @@ -492,7 +494,8 @@ SettingsWindow::_CreateProxyPage(float spacing) ) .Add(BSpaceLayoutItem::CreateGlue()) - .SetInsets(spacing, spacing, spacing, spacing) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) .TopView() ; diff --git a/src/kits/tracker/FindPanel.cpp b/src/kits/tracker/FindPanel.cpp index 2fc403449c..66d098e46c 100644 --- a/src/kits/tracker/FindPanel.cpp +++ b/src/kits/tracker/FindPanel.cpp @@ -866,7 +866,7 @@ FindPanel::FindPanel(BFile* node, FindWindow* parent, bool fromTemplate, .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER)) .Add(queryControls); BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING) - .SetInsets(B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) .Add(queryBox) .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) .Add(icon) diff --git a/src/kits/tracker/TrackerSettingsWindow.cpp b/src/kits/tracker/TrackerSettingsWindow.cpp index 11470ef384..3b085a0f72 100644 --- a/src/kits/tracker/TrackerSettingsWindow.cpp +++ b/src/kits/tracker/TrackerSettingsWindow.cpp @@ -96,20 +96,20 @@ TrackerSettingsWindow::TrackerSettingsWindow() fSettingsContainerBox = new BBox("SettingsContainerBox"); - const float spacing = be_control_look->DefaultItemSpacing(); +// const float spacing = be_control_look->DefaultItemSpacing(); BLayoutBuilder::Group<>(this) - .AddGroup(B_HORIZONTAL, spacing) + .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) .Add(scrollView) - .AddGroup(B_VERTICAL, spacing) + .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING) .Add(fSettingsContainerBox) - .AddGroup(B_HORIZONTAL, spacing) + .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) .Add(fDefaultsButton) .Add(fRevertButton) .AddGlue() .End() .End() - .SetInsets(spacing, spacing, spacing, spacing) + .SetInsets(B_USE_WINDOW_SPACING) .End(); fSettingsTypeListView->AddItem(new SettingsItem(B_TRANSLATE("Desktop"), diff --git a/src/preferences/appearance/APRWindow.cpp b/src/preferences/appearance/APRWindow.cpp index f213daadc3..71b30cfee6 100644 --- a/src/preferences/appearance/APRWindow.cpp +++ b/src/preferences/appearance/APRWindow.cpp @@ -112,7 +112,7 @@ APRWindow::_UpdateButtons() { fDefaultsButton->SetEnabled(_IsDefaultable()); fRevertButton->SetEnabled(_IsRevertable()); -} +} bool diff --git a/src/preferences/datatranslations/DataTranslationsWindow.cpp b/src/preferences/datatranslations/DataTranslationsWindow.cpp index 2d71c40012..24b83e58c3 100644 --- a/src/preferences/datatranslations/DataTranslationsWindow.cpp +++ b/src/preferences/datatranslations/DataTranslationsWindow.cpp @@ -231,7 +231,7 @@ DataTranslationsWindow::_SetupViews() // Build the layout BLayoutBuilder::Group<>(this, B_HORIZONTAL) - .SetInsets(B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) .Add(scrollView, 3) .AddGrid(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, 6) .SetInsets(0, 0, 0, 0) diff --git a/src/preferences/filetypes/ApplicationTypesWindow.cpp b/src/preferences/filetypes/ApplicationTypesWindow.cpp index f191ed607f..c776f33410 100644 --- a/src/preferences/filetypes/ApplicationTypesWindow.cpp +++ b/src/preferences/filetypes/ApplicationTypesWindow.cpp @@ -256,9 +256,10 @@ ApplicationTypesWindow::ApplicationTypesWindow(const BMessage& settings) .Add(fTrackerButton) .AddGlue() .End() - .AddGlue() + .AddGlue(10.0) .End() - .SetInsets(padding, padding, padding, padding); + + .SetInsets(B_USE_WINDOW_SPACING); BMimeType::StartWatching(this); _SetType(NULL); diff --git a/src/preferences/filetypes/FileTypesWindow.cpp b/src/preferences/filetypes/FileTypesWindow.cpp index 310adf8c1c..c771569f97 100644 --- a/src/preferences/filetypes/FileTypesWindow.cpp +++ b/src/preferences/filetypes/FileTypesWindow.cpp @@ -547,7 +547,7 @@ FileTypesWindow::FileTypesWindow(const BMessage& settings) .SetInsets(0) .Add(menuBar) .AddGroup(B_HORIZONTAL, 0) - .SetInsets(padding, padding, padding, padding) + .SetInsets(B_USE_WINDOW_SPACING) .AddSplit(fMainSplitView) .AddGroup(B_VERTICAL, padding) .Add(typeListScrollView) @@ -1194,7 +1194,7 @@ FileTypesWindow::_MoveUpAttributeIndex(int32 index) // so just ignore this attribute name. // NOTE: This shows that the attribute description is // too fragile. It would have been better to pack each - // attribute description into a separate BMessage. + // attribute description into a separate BMessage. continue; } @@ -1207,7 +1207,7 @@ FileTypesWindow::_MoveUpAttributeIndex(int32 index) else if (j == index) originalIndex = j - 1; else - originalIndex = j; + originalIndex = j; attributes.FindData(kAttributeNames[i], type, originalIndex, &data, &size); if (j == 0) { diff --git a/src/preferences/keymap/KeymapWindow.cpp b/src/preferences/keymap/KeymapWindow.cpp index 65da77def3..0b3a8d02d2 100644 --- a/src/preferences/keymap/KeymapWindow.cpp +++ b/src/preferences/keymap/KeymapWindow.cpp @@ -98,11 +98,10 @@ KeymapWindow::KeymapWindow() new BMessage(kMsgSwitchShortcuts)); // controls pane - BLayoutBuilder::Group<>(this, B_VERTICAL) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .Add(_CreateMenu()) .AddGroup(B_HORIZONTAL) - .SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING, - B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) .Add(_CreateMapLists(), 0.25) .AddGroup(B_VERTICAL) .Add(fKeyboardLayoutView) @@ -114,12 +113,12 @@ KeymapWindow::KeymapWindow() .Add(fTextControl) .AddGlue(0.0) .AddGroup(B_HORIZONTAL) + .AddGlue() .Add(fDefaultsButton = new BButton("defaultsButton", B_TRANSLATE("Defaults"), new BMessage(kMsgDefaultKeymap))) .Add(fRevertButton = new BButton("revertButton", B_TRANSLATE("Revert"), new BMessage(kMsgRevertKeymap))) - .AddGlue() .End() .End() .End() diff --git a/src/preferences/keymap/ModifierKeysWindow.cpp b/src/preferences/keymap/ModifierKeysWindow.cpp index dd1e5918ae..b18f9f713f 100644 --- a/src/preferences/keymap/ModifierKeysWindow.cpp +++ b/src/preferences/keymap/ModifierKeysWindow.cpp @@ -325,7 +325,7 @@ ModifierKeysWindow::ModifierKeysWindow() .Add(fRevertButton) .Add(fOkButton) .End() - .SetInsets(B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) .End(); _MarkMenuItems(); diff --git a/src/preferences/media/MediaWindow.cpp b/src/preferences/media/MediaWindow.cpp index 1275a6a502..b1f2d7b168 100644 --- a/src/preferences/media/MediaWindow.cpp +++ b/src/preferences/media/MediaWindow.cpp @@ -411,8 +411,7 @@ MediaWindow::_InitWindow() // Layout all views BLayoutBuilder::Group<>(this, B_HORIZONTAL) - .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, - B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) .Add(scrollView, 0.0f) .AddGroup(B_VERTICAL) .SetInsets(0, 0, 0, 0) @@ -657,7 +656,7 @@ status_t MediaWindow::_RestartMediaServices(void* data) { MediaWindow* window = (MediaWindow*)data; - + shutdown_media_server(); launch_media_server(); diff --git a/src/preferences/network/NetworkWindow.cpp b/src/preferences/network/NetworkWindow.cpp index a721538ba4..d51f5f9b98 100644 --- a/src/preferences/network/NetworkWindow.cpp +++ b/src/preferences/network/NetworkWindow.cpp @@ -136,7 +136,7 @@ NetworkWindow::NetworkWindow() // Build the layout BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) #if ENABLE_PROFILES .AddGroup(B_HORIZONTAL, B_USE_SMALL_SPACING) diff --git a/src/preferences/printers/PrintersWindow.cpp b/src/preferences/printers/PrintersWindow.cpp index 516ec524d9..cc5f25c28d 100644 --- a/src/preferences/printers/PrintersWindow.cpp +++ b/src/preferences/printers/PrintersWindow.cpp @@ -230,7 +230,7 @@ PrintersWindow::PrintTestPage(PrinterItem* printer) BMessage* settings = job->Settings(); if (settings == NULL) { - delete job; + delete job; return; } @@ -376,7 +376,7 @@ PrintersWindow::_BuildGUI() .AddGlue(); BLayoutBuilder::Group<>(this, B_VERTICAL, 0) - .SetInsets(B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) .Add(printersBox) .AddStrut(B_USE_DEFAULT_SPACING) .Add(fJobsBox); diff --git a/src/preferences/screen/ScreenWindow.cpp b/src/preferences/screen/ScreenWindow.cpp index 330757afaa..0054c316f2 100644 --- a/src/preferences/screen/ScreenWindow.cpp +++ b/src/preferences/screen/ScreenWindow.cpp @@ -535,7 +535,7 @@ ScreenWindow::ScreenWindow(ScreenSettings* settings) .Add(fRevertButton) .AddGlue() .End() - .SetInsets(B_USE_DEFAULT_SPACING); + .SetInsets(B_USE_WINDOW_SPACING); _UpdateControls(); _UpdateMonitor(); diff --git a/src/preferences/screensaver/ScreenSaverWindow.cpp b/src/preferences/screensaver/ScreenSaverWindow.cpp index 5dfa4dd821..8bd3e6a652 100644 --- a/src/preferences/screensaver/ScreenSaverWindow.cpp +++ b/src/preferences/screensaver/ScreenSaverWindow.cpp @@ -349,7 +349,7 @@ FadeView::FadeView(const char* name, ScreenSaverSettings& settings) fadeNeverText->MakeSelectable(false); fadeNeverText->SetText(B_TRANSLATE("Don't fade when mouse is here")); - box->AddChild(BLayoutBuilder::Group<>(B_VERTICAL) + box->AddChild(BLayoutBuilder::Group<>(B_VERTICAL, 0) .SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING) .AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING) @@ -384,7 +384,8 @@ FadeView::FadeView(const char* name, ScreenSaverSettings& settings) .View()); BLayoutBuilder::Group<>(this, B_HORIZONTAL) - .SetInsets(B_USE_SMALL_SPACING) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, 0) .Add(box) .End(); } @@ -555,7 +556,8 @@ ModulesView::ModulesView(const char* name, ScreenSaverSettings& settings) fSettingsBox->SetLabel(B_TRANSLATE("Screensaver settings")); BLayoutBuilder::Group<>(this, B_HORIZONTAL) - .SetInsets(B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, 0) .AddGroup(B_VERTICAL) .Add(fPreviewView) .Add(saversListScrollView) @@ -931,7 +933,7 @@ ScreenSaverWindow::ScreenSaverWindow() B_ALIGN_USE_FULL_HEIGHT)); topView->SetExplicitMinSize(BSize(fMinWidth, fMinHeight)); BLayoutBuilder::Group<>(topView, B_VERTICAL) - .SetInsets(0, B_USE_SMALL_SPACING, 0, 0) + .SetInsets(0, B_USE_DEFAULT_SPACING, 0, B_USE_WINDOW_SPACING) .Add(fTabView) .End(); diff --git a/src/preferences/shortcuts/ShortcutsWindow.cpp b/src/preferences/shortcuts/ShortcutsWindow.cpp index 0fc38d4b20..9eba4696a3 100644 --- a/src/preferences/shortcuts/ShortcutsWindow.cpp +++ b/src/preferences/shortcuts/ShortcutsWindow.cpp @@ -240,7 +240,7 @@ ShortcutsWindow::ShortcutsWindow() BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .Add(menuBar) .AddGroup(B_VERTICAL) - .SetInsets(B_USE_WINDOW_INSETS) + .SetInsets(B_USE_WINDOW_SPACING) .Add(fColumnListView) .AddGroup(B_HORIZONTAL) .AddGroup(B_HORIZONTAL) diff --git a/src/preferences/sounds/HWindow.cpp b/src/preferences/sounds/HWindow.cpp index 1e21295eba..5b0fc2b57b 100644 --- a/src/preferences/sounds/HWindow.cpp +++ b/src/preferences/sounds/HWindow.cpp @@ -314,7 +314,7 @@ HWindow::_InitGUI() playbutton->SetExplicitSize(buttonsSize); BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) .Add(fEventList) .AddGroup(B_HORIZONTAL) .Add(menuField) diff --git a/src/preferences/touchpad/TouchpadPrefView.cpp b/src/preferences/touchpad/TouchpadPrefView.cpp index 7a93a5796f..5ebe979746 100644 --- a/src/preferences/touchpad/TouchpadPrefView.cpp +++ b/src/preferences/touchpad/TouchpadPrefView.cpp @@ -459,7 +459,7 @@ TouchpadPrefView::SetupView() fRevertButton->SetEnabled(false); BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) .Add(scrollBox) .Add(tapBox) .AddGroup(B_HORIZONTAL) diff --git a/src/preferences/virtualmemory/SettingsWindow.cpp b/src/preferences/virtualmemory/SettingsWindow.cpp index c1623915dd..a9d1d58483 100644 --- a/src/preferences/virtualmemory/SettingsWindow.cpp +++ b/src/preferences/virtualmemory/SettingsWindow.cpp @@ -213,7 +213,7 @@ SettingsWindow::SettingsWindow() fRevertButton->SetEnabled(false); BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING) .Add(box) .AddGroup(B_HORIZONTAL) .Add(fDefaultsButton) From 744a39273b77fed45ca433c771d470962c226fe0 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Sat, 7 Nov 2015 16:54:41 +0100 Subject: [PATCH 092/370] Use templatized version of BLayoutBuilder ...also more B_USE_WINDOW_SPACING --- src/apps/activitymonitor/SettingsWindow.cpp | 10 ++++---- src/apps/diskprobe/AttributeWindow.cpp | 11 ++++----- src/apps/diskprobe/TypeEditors.cpp | 9 +++---- src/apps/firstbootprompt/BootPromptWindow.cpp | 24 ++++++++----------- src/apps/mail/Prefs.cpp | 13 ++++------ .../mediaconverter/MediaConverterWindow.cpp | 14 ++++++----- .../backgrounds/BackgroundsView.cpp | 13 +++++----- src/preferences/bluetooth/BluetoothWindow.cpp | 24 +++++++++---------- src/preferences/printers/AddPrinterDialog.cpp | 11 ++++----- 9 files changed, 58 insertions(+), 71 deletions(-) diff --git a/src/apps/activitymonitor/SettingsWindow.cpp b/src/apps/activitymonitor/SettingsWindow.cpp index de582630c2..67829b060e 100644 --- a/src/apps/activitymonitor/SettingsWindow.cpp +++ b/src/apps/activitymonitor/SettingsWindow.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include #include @@ -94,17 +94,15 @@ SettingsWindow::SettingsWindow(ActivityWindow* target) B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS), fTarget(target) { - SetLayout(new BGroupLayout(B_VERTICAL)); - fIntervalSlider = new IntervalSlider(B_TRANSLATE("Update time interval:"), new BMessage(kMsgUpdateTimeInterval), kNumUpdateIntervals); fIntervalSlider->SetInterval(target->RefreshInterval()); // controls pane - AddChild(BGroupLayoutBuilder(B_VERTICAL) + BLayoutBuilder::Group<>(this, B_VERTICAL) .Add(fIntervalSlider) - .SetInsets(10, 10, 10, 10) - ); + .SetInsets(B_USE_WINDOW_SPACING); + if (target->IsAlwaysOnTop()) SetFeel(B_MODAL_ALL_WINDOW_FEEL); } diff --git a/src/apps/diskprobe/AttributeWindow.cpp b/src/apps/diskprobe/AttributeWindow.cpp index 3b1f2d5780..6f78817aa7 100644 --- a/src/apps/diskprobe/AttributeWindow.cpp +++ b/src/apps/diskprobe/AttributeWindow.cpp @@ -14,9 +14,8 @@ #include #include #include -#include -#include #include +#include #include #include #include @@ -72,10 +71,10 @@ EditorTabView::SetTypeEditorTab(BView *view) } BGroupView* group = new BGroupView(B_VERTICAL); - BGroupLayoutBuilder(group) - .AddGlue() - .Add(view, 0) - .AddGlue(); + BLayoutBuilder::Group<>(group, B_VERTICAL) + .SetInsets(B_USE_WINDOW_SPACING, 0, B_USE_WINDOW_SPACING, 0) + .Add(view) + .AddGlue(25.0f); group->SetName(view->Name()); diff --git a/src/apps/diskprobe/TypeEditors.cpp b/src/apps/diskprobe/TypeEditors.cpp index 1025f5f7f1..f5708fbdcf 100644 --- a/src/apps/diskprobe/TypeEditors.cpp +++ b/src/apps/diskprobe/TypeEditors.cpp @@ -14,9 +14,8 @@ #include #include #include -#include -#include #include +#include #include #include #include @@ -852,8 +851,6 @@ ImageView::ImageView(DataEditor &editor) fBitmap(NULL), fScaleSlider(NULL) { - BGroupLayout* layout = new BGroupLayout(B_HORIZONTAL); - SetLayout(layout); if (editor.Type() == B_MINI_ICON_TYPE || editor.Type() == B_LARGE_ICON_TYPE #ifdef HAIKU_TARGET_PLATFORM_HAIKU @@ -877,7 +874,7 @@ ImageView::ImageView(DataEditor &editor) fScaleSlider->SetHashMarks(B_HASH_MARKS_BOTH); fScaleSlider->SetHashMarkCount(15); - BGroupLayoutBuilder(layout) + BLayoutBuilder::Group<>(this, B_HORIZONTAL) .SetInsets(B_USE_WINDOW_SPACING, 256, B_USE_WINDOW_SPACING, B_H_SCROLL_BAR_HEIGHT) // Leave space for the icon .AddGlue() @@ -887,7 +884,7 @@ ImageView::ImageView(DataEditor &editor) .End() .AddGlue(); } else { - BGroupLayoutBuilder(layout) + BLayoutBuilder::Group<>(this, B_HORIZONTAL) .SetInsets(B_USE_WINDOW_SPACING, 256, B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING) // Leave space for the icon .AddGlue() diff --git a/src/apps/firstbootprompt/BootPromptWindow.cpp b/src/apps/firstbootprompt/BootPromptWindow.cpp index b64b57247c..b80b2bf56a 100644 --- a/src/apps/firstbootprompt/BootPromptWindow.cpp +++ b/src/apps/firstbootprompt/BootPromptWindow.cpp @@ -187,14 +187,10 @@ BootPromptWindow::BootPromptWindow() _PopulateLanguages(); _PopulateKeymaps(); - float spacing = be_control_look->DefaultItemSpacing(); - - SetLayout(new BGroupLayout(B_HORIZONTAL)); - - AddChild(BLayoutBuilder::Group<>(B_VERTICAL, 0) - .AddGroup(B_HORIZONTAL, spacing) - .AddGroup(B_VERTICAL, spacing) - .AddGroup(B_VERTICAL, spacing) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) + .AddGroup(B_HORIZONTAL) + .AddGroup(B_VERTICAL) + .AddGroup(B_VERTICAL) .Add(fLanguagesLabelView) .Add(languagesScrollView) .End() @@ -203,17 +199,17 @@ BootPromptWindow::BootPromptWindow() .End() .End() .Add(fInfoTextView) - .SetInsets(spacing, spacing, spacing, spacing) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) .End() .Add(new BSeparatorView(B_HORIZONTAL)) - .AddGroup(B_HORIZONTAL, spacing) + .AddGroup(B_HORIZONTAL) .AddGlue() .Add(fInstallerButton) .Add(fDesktopButton) - .SetInsets(spacing, spacing, spacing, spacing) - .End() - .View() - ); + .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, + B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING) + .End(); fLanguagesListView->MakeFocus(); diff --git a/src/apps/mail/Prefs.cpp b/src/apps/mail/Prefs.cpp index 806dd00387..e45f335479 100644 --- a/src/apps/mail/Prefs.cpp +++ b/src/apps/mail/Prefs.cpp @@ -44,7 +44,7 @@ of their respective holders. All rights reserved. #include #include #include -#include +#include #include #include #include @@ -263,19 +263,16 @@ TPrefsWindow::TPrefsWindow(BRect rect, BFont* font, int32* level, bool* wrap, fAttachAttributesMenu); add_menu_to_layout(menu, mailLayout, layoutRow); - SetLayout(new BGroupLayout(B_HORIZONTAL)); - - AddChild(BGroupLayoutBuilder(B_VERTICAL, kSpacing) + BLayoutBuilder::Group<>(this, B_VERTICAL) .Add(interfaceBox) .Add(mailBox) - .Add(BGroupLayoutBuilder(B_HORIZONTAL, kSpacing) + .AddGroup(B_HORIZONTAL, 0) .Add(fRevert) .AddGlue() .Add(cancelButton) .Add(okButton) - ) - .SetInsets(kSpacing, kSpacing, kSpacing, kSpacing) - ); + .End() + .SetInsets(B_USE_WINDOW_SPACING); Show(); } diff --git a/src/apps/mediaconverter/MediaConverterWindow.cpp b/src/apps/mediaconverter/MediaConverterWindow.cpp index 8618145ba0..7fee41fa76 100644 --- a/src/apps/mediaconverter/MediaConverterWindow.cpp +++ b/src/apps/mediaconverter/MediaConverterWindow.cpp @@ -274,16 +274,18 @@ MediaConverterWindow::MediaConverterWindow(BRect frame) BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .SetInsets(0, 0, 0, 0) .Add(fMenuBar) - .AddSplit(B_HORIZONTAL, padding / 2) - .SetInsets(padding, padding, padding, padding) - .Add(fSourcesBox, 0.4) - .AddGroup(B_VERTICAL, padding, 0.6) + .AddSplit(B_HORIZONTAL, B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, 0) + .Add(fSourcesBox) + .AddGroup(B_VERTICAL, B_USE_ITEM_SPACING) .Add(fInfoBox) .Add(fOutputBox) .End() .End() - .AddGrid(padding, padding) - .SetInsets(padding, 0, padding, padding) + .AddGrid(B_USE_ITEM_SPACING) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, + B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING) .Add(fStatus, 0, 0) .Add(fFileStatus, 0, 1) .Add(BSpaceLayoutItem::CreateGlue(), 1, 0) diff --git a/src/preferences/backgrounds/BackgroundsView.cpp b/src/preferences/backgrounds/BackgroundsView.cpp index dc21255413..71853c8f92 100644 --- a/src/preferences/backgrounds/BackgroundsView.cpp +++ b/src/preferences/backgrounds/BackgroundsView.cpp @@ -222,21 +222,22 @@ BackgroundsView::BackgroundsView() fApply->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_NO_VERTICAL)); - AddChild(BLayoutBuilder::Group<>(B_VERTICAL) - .AddGroup(B_HORIZONTAL) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) + .SetInsets(B_USE_WINDOW_SPACING) + .AddGroup(B_HORIZONTAL, 0) .AddGroup(B_VERTICAL, 0) .AddStrut(floorf(rightbox->TopBorderOffset() - previewBox->TopBorderOffset()) - 1) .Add(previewBox) .End() + .AddStrut(B_USE_DEFAULT_SPACING) .Add(rightbox) .End() - .AddGroup(B_HORIZONTAL) + .AddGroup(B_HORIZONTAL, 0) .Add(fRevert) .Add(fApply) - .End() - .SetInsets(B_USE_DEFAULT_SPACING) - .View()); + .SetInsets(0, B_USE_DEFAULT_SPACING, 0, 0) + .End(); fApply->MakeDefault(true); } diff --git a/src/preferences/bluetooth/BluetoothWindow.cpp b/src/preferences/bluetooth/BluetoothWindow.cpp index 28cdf3568f..81ab400e26 100644 --- a/src/preferences/bluetooth/BluetoothWindow.cpp +++ b/src/preferences/bluetooth/BluetoothWindow.cpp @@ -2,20 +2,21 @@ * Copyright 2008-10, Oliver Ruiz Dorantes, * All rights reserved. Distributed under the terms of the MIT License. */ -#include "BluetoothWindow.h" +#include "BluetoothWindow.h" +#include "RemoteDevicesView.h" + #include #include -#include +#include #include -#include -#include #include +#include + #include #include -#include "RemoteDevicesView.h" #include "defs.h" @@ -91,18 +92,17 @@ BluetoothWindow::BluetoothWindow(BRect frame) fRevertButton->SetEnabled(false); - AddChild(BGroupLayoutBuilder(B_VERTICAL, 0) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .Add(fMenubar) - .Add(BSpaceLayoutItem::CreateVerticalStrut(5)) + .AddStrut(B_USE_DEFAULT_SPACING) .Add(tabView) - .Add(BSpaceLayoutItem::CreateVerticalStrut(5)) - .Add(BGroupLayoutBuilder(B_HORIZONTAL, 0) + .AddStrut(B_USE_DEFAULT_SPACING) + .AddGroup(B_HORIZONTAL, 0) .Add(fRevertButton) .AddGlue() .Add(fDefaultsButton) - ) - .SetInsets(5, 5, 5, 5) - ); + .End() + .SetInsets(B_USE_WINDOW_SPACING); } diff --git a/src/preferences/printers/AddPrinterDialog.cpp b/src/preferences/printers/AddPrinterDialog.cpp index cf4c74a821..395b692454 100644 --- a/src/preferences/printers/AddPrinterDialog.cpp +++ b/src/preferences/printers/AddPrinterDialog.cpp @@ -15,10 +15,9 @@ #include #include #include -#include -#include #include #include +#include #include #include #include @@ -207,9 +206,7 @@ AddPrinterDialog::_BuildGUI(int stage) BButton *cancel = new BButton(NULL, B_TRANSLATE("Cancel"), new BMessage(B_CANCEL)); - SetLayout(new BGridLayout()); - - AddChild(BGridLayoutBuilder(0, 4) + BLayoutBuilder::Grid<>(this, B_USE_ITEM_SPACING, B_USE_ITEM_SPACING) .Add(fName->CreateLabelLayoutItem(), 0, 0) .Add(fName->CreateTextViewLayoutItem(), 1, 0) .Add(printerMenuField->CreateLabelLayoutItem(), 0, 1) @@ -221,8 +218,8 @@ AddPrinterDialog::_BuildGUI(int stage) .Add(cancel) .Add(fOk) , 0, 3, 2) - .SetInsets(8, 8, 8, 8) - ); + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING); SetDefaultButton(fOk); fOk->MakeDefault(true); From c8325bb7d73c1d74f116620a01f5332c94986b99 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Sat, 7 Nov 2015 16:58:35 +0100 Subject: [PATCH 093/370] Improve layouting of Expander Especially actually hide the content's scroll view, which otherwise would peak out if the B_USE_WINDOW_SPACING would ever be increased. --- src/apps/expander/ExpanderPreferences.cpp | 62 ++++++++++------------- src/apps/expander/ExpanderWindow.cpp | 53 ++++++++++--------- 2 files changed, 54 insertions(+), 61 deletions(-) diff --git a/src/apps/expander/ExpanderPreferences.cpp b/src/apps/expander/ExpanderPreferences.cpp index f602002209..b03bbb78fa 100644 --- a/src/apps/expander/ExpanderPreferences.cpp +++ b/src/apps/expander/ExpanderPreferences.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -51,13 +52,6 @@ ExpanderPreferences::ExpanderPreferences(BMessage* settings) { const float kSpacing = be_control_look->DefaultItemSpacing(); - BBox* settingsBox = new BBox(B_PLAIN_BORDER, NULL); - BGroupLayout* settingsLayout = new BGroupLayout(B_VERTICAL, kSpacing / 2); - settingsBox->SetLayout(settingsLayout); - BBox* buttonBox = new BBox(B_PLAIN_BORDER, NULL); - BGroupLayout* buttonLayout = new BGroupLayout(B_HORIZONTAL, kSpacing / 2); - buttonBox->SetLayout(buttonLayout); - BStringView* expansionLabel = new BStringView("stringViewExpansion", B_TRANSLATE("Expansion")); expansionLabel->SetFont(be_bold_font); @@ -103,54 +97,50 @@ ExpanderPreferences::ExpanderPreferences(BMessage* settings) // Build the layout BLayoutBuilder::Group<>(this, B_VERTICAL, 0) - .AddGroup(settingsLayout) - .AddGroup(B_HORIZONTAL) - .Add(expansionLabel) - .AddGlue() - .End() + .AddGroup(B_VERTICAL, 0) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) + .Add(expansionLabel) .AddGroup(B_VERTICAL, 0) .Add(fAutoExpand) .Add(fCloseWindow) - .SetInsets(kSpacing, 0, 0, 0) - .End() - .AddGroup(B_HORIZONTAL, 0) - .Add(destinationLabel) .AddGlue() - .SetInsets(0, kSpacing, 0, 0) - .End() + .SetInsets(B_USE_SMALL_SPACING, B_USE_SMALL_SPACING, 0, + B_USE_ITEM_SPACING) + .End() + .Add(destinationLabel) .AddGroup(B_VERTICAL, 0) .Add(fLeaveDest) .Add(fSameDest) .Add(fDestUse) .AddGroup(B_HORIZONTAL, 0) .Add(fDestText, 0.8) - .AddStrut(be_control_look->DefaultLabelSpacing()) + .AddStrut(B_USE_ITEM_SPACING) .Add(fSelect, 0.2) - .SetInsets(kSpacing * 2, 0, kSpacing / 2, 0) - .End() - .SetInsets(kSpacing, 0, 0, 0) - .End() - .AddGroup(B_HORIZONTAL, 0) - .Add(otherLabel) + .SetInsets(kSpacing * 2, 0, 0, 0) + .End() .AddGlue() - .SetInsets(0, kSpacing / 2, 0, 0) - .End() + .SetInsets(B_USE_SMALL_SPACING, B_USE_SMALL_SPACING, 0, + B_USE_ITEM_SPACING) + .End() + .Add(otherLabel) .AddGroup(B_VERTICAL, 0) .Add(fOpenDest) .Add(fAutoShow) - .SetInsets(kSpacing, 0, 0, 0) - .End() - .SetInsets(kSpacing, kSpacing, kSpacing, kSpacing) - .End() - .AddGroup(buttonLayout) - .AddGroup(B_HORIZONTAL, kSpacing) .AddGlue() - .Add(cancel) - .Add(okbutton) + .SetInsets(B_USE_SMALL_SPACING, B_USE_SMALL_SPACING, 0, 0) + .End() .End() - .SetInsets(kSpacing, kSpacing, kSpacing, kSpacing) + .Add(new BSeparatorView(B_HORIZONTAL)) + .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) + .SetInsets(0, B_USE_DEFAULT_SPACING, + B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING) + .AddGlue() + .Add(cancel) + .Add(okbutton) .End(); + fDestText->SetExplicitAlignment( BAlignment(B_ALIGN_HORIZONTAL_UNSET, B_ALIGN_VERTICAL_CENTER)); diff --git a/src/apps/expander/ExpanderWindow.cpp b/src/apps/expander/ExpanderWindow.cpp index 171a50d75c..59b657d0e7 100644 --- a/src/apps/expander/ExpanderWindow.cpp +++ b/src/apps/expander/ExpanderWindow.cpp @@ -102,35 +102,33 @@ ExpanderWindow::ExpanderWindow(BRect frame, const entry_ref* ref, const float spacing = be_control_look->DefaultItemSpacing(); BGroupLayout* pathLayout; - BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0) - .SetInsets(0.0) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .Add(fBar) - .AddGroup(B_VERTICAL, spacing) - .AddGroup(B_HORIZONTAL, spacing) - .AddGroup(B_VERTICAL, 5.0) - .Add(fSourceButton) - .Add(fDestButton) - .Add(fExpandButton) + .AddGroup(B_VERTICAL, B_USE_ITEM_SPACING) + .AddGroup(B_HORIZONTAL, B_USE_ITEM_SPACING) + .Add(fSourceButton) + .Add(fSourceText = new BTextControl(NULL, NULL, + new BMessage(MSG_SOURCETEXT))) .End() - .AddGroup(B_VERTICAL, spacing) - .Add(fSourceText = new BTextControl(NULL, NULL, - new BMessage(MSG_SOURCETEXT))) - .Add(fDestText = new BTextControl(NULL, NULL, - new BMessage(MSG_DESTTEXT))) - .AddGroup(B_HORIZONTAL, spacing) - .GetLayout(&pathLayout) - .Add(fShowContents = new BCheckBox( - B_TRANSLATE("Show contents"), - new BMessage(MSG_SHOWCONTENTS))) - .Add(fStatusView = new BStringView(NULL, - statusPlaceholderString)) + .AddGroup(B_HORIZONTAL, B_USE_ITEM_SPACING) + .Add(fDestButton) + .Add(fDestText = new BTextControl(NULL, NULL, + new BMessage(MSG_DESTTEXT))) + .End() + .AddGroup(B_HORIZONTAL, B_USE_ITEM_SPACING) + .Add(fExpandButton) + .AddGroup(B_HORIZONTAL, B_USE_ITEM_SPACING) + .GetLayout(&pathLayout) + .Add(fShowContents = new BCheckBox( + B_TRANSLATE("Show contents"), + new BMessage(MSG_SHOWCONTENTS))) + .Add(fStatusView = new BStringView(NULL, + statusPlaceholderString)) .End() .End() - .End() .Add(fScrollView) - .SetInsets(spacing, spacing, spacing, spacing) - .End() - .End(); + .SetInsets(B_USE_WINDOW_SPACING) + .End(); pathLayout->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); size = GetLayout()->View()->PreferredSize(); @@ -141,6 +139,8 @@ ExpanderWindow::ExpanderWindow(BRect frame, const entry_ref* ref, SetZoomLimits(Bounds().Width(), fSizeLimit); fPreviousHeight = -1; + fScrollView->Hide(); + Show(); } @@ -309,9 +309,12 @@ ExpanderWindow::MessageReceived(BMessage* message) if (fListingStarted) StopListing(); + fScrollView->Hide(); _UpdateWindowSize(false); - } else + } else { + fScrollView->Show(); StartListing(); + } break; case MSG_SOURCETEXT: From 3c5208e4392da8a9451afd5eb55483a871be6182 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Sat, 7 Nov 2015 17:15:56 +0100 Subject: [PATCH 094/370] Improve/fix layout Some tweaks to the layout of apps/prefs in the course of using B_USE_WINDOW_SPACING. --- src/apps/codycam/CodyCam.cpp | 38 +++++------- src/apps/codycam/CodyCam.h | 6 +- src/apps/mail/MailWindow.cpp | 7 ++- src/apps/midiplayer/MidiPlayerWindow.cpp | 56 +++++++++--------- src/apps/people/PersonWindow.cpp | 2 +- src/apps/poorman/PoorManPreferencesWindow.cpp | 10 ++-- src/apps/screenshot/ScreenshotWindow.cpp | 9 +-- src/preferences/keyboard/KeyboardView.cpp | 12 ++-- src/preferences/keyboard/KeyboardWindow.cpp | 15 +++-- src/preferences/keymap/ModifierKeysWindow.cpp | 3 +- src/preferences/mouse/MouseWindow.cpp | 16 +++-- src/preferences/mouse/SettingsView.cpp | 58 +++++++------------ 12 files changed, 108 insertions(+), 124 deletions(-) diff --git a/src/apps/codycam/CodyCam.cpp b/src/apps/codycam/CodyCam.cpp index 84e5b54608..ea8678e6bd 100644 --- a/src/apps/codycam/CodyCam.cpp +++ b/src/apps/codycam/CodyCam.cpp @@ -36,15 +36,6 @@ #define WINDOW_OFFSET_X 28 #define WINDOW_OFFSET_Y 28 -const int32 kBtnHeight = 20; -const int32 kBtnWidth = 60; -const int32 kBtnBuffer = 25; -const int32 kXBuffer = 10; -const int32 kYBuffer = 10; -const int32 kMenuHeight = 15; -const int32 kButtonHeight = 15; -const int32 kSliderViewRectHeight = 40; - #define CALL printf #define ERROR printf #define FTPINFO printf @@ -133,7 +124,7 @@ CodyCam::~CodyCam() void CodyCam::ReadyToRun() { - fWindow = new VideoWindow(BRect(28, 28, 28, 28), + fWindow = new VideoWindow( (const char*) B_TRANSLATE_SYSTEM_NAME("CodyCam"), B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS, &fPort); @@ -187,10 +178,7 @@ CodyCam::MessageReceived(BMessage *message) status_t err = fMediaRoster->GetParameterWebFor(node, &web); if (err >= B_OK && web != NULL) { view = BMediaTheme::ViewFor(web); - fVideoControlWindow = new ControlWindow( - BRect(2 * WINDOW_OFFSET_X + WINDOW_SIZE_X, WINDOW_OFFSET_Y, - 2 * WINDOW_OFFSET_X + WINDOW_SIZE_X + view->Bounds().right, - WINDOW_OFFSET_Y + view->Bounds().bottom), view, node); + fVideoControlWindow = new ControlWindow(view, node); fMediaRoster->StartWatching(BMessenger(NULL, fVideoControlWindow), node, B_MEDIA_WEB_CHANGED); fVideoControlWindow->Show(); @@ -407,10 +395,10 @@ CodyCam::_TearDownNodes() // #pragma mark - Video Window Class -VideoWindow::VideoWindow(BRect frame, const char* title, window_type type, +VideoWindow::VideoWindow(const char* title, window_type type, uint32 flags, port_id* consumerPort) : - BWindow(frame, title, type, flags), + BWindow(BRect(50, 50, 50, 50), title, type, flags), fPortPtr(consumerPort), fVideoView(NULL) { @@ -428,7 +416,7 @@ VideoWindow::VideoWindow(BRect frame, const char* title, window_type type, _SetUpSettings("codycam", ""); - BMenuBar* menuBar = new BMenuBar(BRect(0, 0, 0, 0), "menu bar"); + BMenuBar* menuBar = new BMenuBar("menu bar"); BMenuItem* menuItem; fMenu = new BMenu(B_TRANSLATE("File")); @@ -466,17 +454,17 @@ VideoWindow::VideoWindow(BRect frame, const char* title, window_type type, box->AddChild(fVideoView); BLayoutBuilder::Group<>(this, B_VERTICAL, 0) - .SetInsets(0, 0, 0, 0) .Add(menuBar) - .AddGroup(B_VERTICAL, kYBuffer) - .SetInsets(kXBuffer, kYBuffer, kXBuffer, kYBuffer) + .AddGroup(B_VERTICAL) + .SetInsets(B_USE_WINDOW_SPACING) .Add(box) - .AddGroup(B_HORIZONTAL, kXBuffer) - .SetInsets(0, 0, 0, 0) + .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) .Add(fCaptureSetupBox) .Add(fFtpSetupBox) .End() - .Add(fStatusLine); + .Add(fStatusLine) + .End() + .AddGlue(); Show(); } @@ -849,10 +837,10 @@ VideoWindow::ToggleMenuOnOff() // #pragma mark - -ControlWindow::ControlWindow(const BRect& frame, BView* controls, +ControlWindow::ControlWindow(BView* controls, media_node node) : - BWindow(frame, B_TRANSLATE("Video settings"), B_TITLED_WINDOW, + BWindow(BRect(), B_TRANSLATE("Video settings"), B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS) { fView = controls; diff --git a/src/apps/codycam/CodyCam.h b/src/apps/codycam/CodyCam.h index 0fcad38281..d1ae0267b1 100644 --- a/src/apps/codycam/CodyCam.h +++ b/src/apps/codycam/CodyCam.h @@ -114,7 +114,7 @@ private: class VideoWindow : public BWindow { public: - VideoWindow(BRect frame, const char* title, + VideoWindow(const char* title, window_type type, uint32 flags, port_id* consumerport); ~VideoWindow(); @@ -164,7 +164,7 @@ private: ftp_msg_info fFtpInfo; Settings* fSettings; - + BMenu* fMenu; StringValueSetting* fServerSetting; @@ -182,7 +182,7 @@ private: class ControlWindow : public BWindow { public: - ControlWindow(const BRect& frame, BView* controls, + ControlWindow(BView* controls, media_node node); void MessageReceived(BMessage* message); bool QuitRequested(); diff --git a/src/apps/mail/MailWindow.cpp b/src/apps/mail/MailWindow.cpp index c1af1f87cf..d6dc5183d7 100644 --- a/src/apps/mail/MailWindow.cpp +++ b/src/apps/mail/MailWindow.cpp @@ -557,8 +557,11 @@ TMailWindow::TMailWindow(BRect rect, const char* title, TMailApp* app, BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .Add(fMenuBar) - .Add(fToolBar) - .Add(fHeaderView) + .AddGroup(B_VERTICAL, 0) + .Add(fToolBar) + .Add(fHeaderView) + .SetInsets(B_USE_WINDOW_SPACING, 0, B_USE_WINDOW_SPACING, 0) + .End() .Add(fContentView); if (to != NULL) diff --git a/src/apps/midiplayer/MidiPlayerWindow.cpp b/src/apps/midiplayer/MidiPlayerWindow.cpp index ed82038637..84bdef07fb 100644 --- a/src/apps/midiplayer/MidiPlayerWindow.cpp +++ b/src/apps/midiplayer/MidiPlayerWindow.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -252,46 +253,41 @@ MidiPlayerWindow::CreateViews() new BMessage(MSG_PLAY_STOP)); fPlayButton->SetEnabled(false); - BBox* divider = new BBox(B_EMPTY_STRING, B_WILL_DRAW | B_FRAME_EVENTS, - B_FANCY_BORDER); - divider->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 1)); - BStringView* volumeLabel = new BStringView(NULL, B_TRANSLATE("Volume:")); volumeLabel->SetAlignment(B_ALIGN_LEFT); // Build the layout - BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_SMALL_SPACING) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .Add(fScopeView) - .AddGroup(B_VERTICAL, B_USE_SMALL_SPACING) - .AddGroup(B_HORIZONTAL, 0.0f) - .AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING) - .Add(fShowScopeCheckBox, 1, 0) + .AddGroup(B_VERTICAL, 0) + .AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING) + .Add(fShowScopeCheckBox, 1, 0) - .Add(fReverbMenuField->CreateLabelLayoutItem(), 0, 1) - .AddGroup(B_HORIZONTAL, 0.0f, 1, 1) - .Add(fReverbMenuField->CreateMenuBarLayoutItem()) - .AddGlue() - .End() - - .Add(fInputMenuField->CreateLabelLayoutItem(), 0, 2) - .AddGroup(B_HORIZONTAL, 0.0f, 1, 2) - .Add(fInputMenuField->CreateMenuBarLayoutItem()) - .AddGlue() - .End() - - .Add(volumeLabel, 0, 3) - .Add(fVolumeSlider, 0, 4, 2, 1) + .Add(fReverbMenuField->CreateLabelLayoutItem(), 0, 1) + .AddGroup(B_HORIZONTAL, 0.0f, 1, 1) + .Add(fReverbMenuField->CreateMenuBarLayoutItem()) + .AddGlue() .End() - .AddGlue() + + .Add(fInputMenuField->CreateLabelLayoutItem(), 0, 2) + .AddGroup(B_HORIZONTAL, 0.0f, 1, 2) + .Add(fInputMenuField->CreateMenuBarLayoutItem()) + .AddGlue() + .End() + + .Add(volumeLabel, 0, 3) + .Add(fVolumeSlider, 0, 4, 2, 1) .End() .AddGlue() - .Add(divider) - .AddGlue() - .Add(fPlayButton) - .AddGlue() - .SetInsets(B_USE_WINDOW_INSETS) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) + + .End() + .Add(new BSeparatorView(B_HORIZONTAL)) + .AddGroup(B_VERTICAL, 0) + .Add(fPlayButton) + .SetInsets(0, B_USE_DEFAULT_SPACING, 0, B_USE_WINDOW_SPACING) .End() - .SetInsets(0) .End(); } diff --git a/src/apps/people/PersonWindow.cpp b/src/apps/people/PersonWindow.cpp index 41e892cce6..e10eedae4f 100644 --- a/src/apps/people/PersonWindow.cpp +++ b/src/apps/people/PersonWindow.cpp @@ -45,7 +45,7 @@ PersonWindow::PersonWindow(BRect frame, const char* title, const char* nameAttribute, const char* categoryAttribute, const entry_ref* ref) : - BWindow(frame, title, B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE + BWindow(frame, title, B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS), fRef(NULL), fPanel(NULL), diff --git a/src/apps/poorman/PoorManPreferencesWindow.cpp b/src/apps/poorman/PoorManPreferencesWindow.cpp index 31fcc7b616..629e6a6b4c 100644 --- a/src/apps/poorman/PoorManPreferencesWindow.cpp +++ b/src/apps/poorman/PoorManPreferencesWindow.cpp @@ -36,6 +36,7 @@ PoorManPreferencesWindow::PoorManPreferencesWindow(BRect frame, char * name) new BMessage(MSG_PREF_BTN_DONE)); fPrefTabView = new BTabView("Pref Tab View", B_WIDTH_FROM_WIDEST); + fPrefTabView->SetBorder(B_NO_BORDER); // Site Tab fSiteTab = new BTab(); @@ -75,15 +76,16 @@ PoorManPreferencesWindow::PoorManPreferencesWindow(BRect frame, char * name) fLogFilePanel->SetButtonLabel(B_DEFAULT_BUTTON, B_TRANSLATE("Create")); change_title = fLogFilePanel->Window(); change_title->SetTitle(STR_FILEPANEL_CREATE_LOG_FILE); - - BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_WINDOW_INSETS) + + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) + .SetInsets(0, B_USE_DEFAULT_SPACING, 0, B_USE_WINDOW_SPACING) .Add(fPrefTabView) .AddGroup(B_HORIZONTAL) .AddGlue() .Add(fCancelButton) - .Add(fDoneButton); + .Add(fDoneButton) + .SetInsets(B_USE_WINDOW_SPACING, 0, B_USE_WINDOW_SPACING, 0); } diff --git a/src/apps/screenshot/ScreenshotWindow.cpp b/src/apps/screenshot/ScreenshotWindow.cpp index e0525590d3..75035e988e 100644 --- a/src/apps/screenshot/ScreenshotWindow.cpp +++ b/src/apps/screenshot/ScreenshotWindow.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -227,10 +228,10 @@ ScreenshotWindow::ScreenshotWindow(const Utility& utility, bool silent, .AddGlue() .End() .End() - .AddStrut(kSpacing) - .Add(divider) - .AddStrut(kSpacing) - .AddGroup(B_HORIZONTAL, kSpacing) + .Add(new BSeparatorView(B_HORIZONTAL)) + .AddGroup(B_HORIZONTAL, 0) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, + B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING) .Add(new BButton("", B_TRANSLATE("Copy to clipboard"), new BMessage(B_COPY))) .Add(new BButton("", B_TRANSLATE("New screenshot"), diff --git a/src/preferences/keyboard/KeyboardView.cpp b/src/preferences/keyboard/KeyboardView.cpp index b17f9f63de..d72c5a1131 100644 --- a/src/preferences/keyboard/KeyboardView.cpp +++ b/src/preferences/keyboard/KeyboardView.cpp @@ -12,8 +12,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -40,6 +39,7 @@ KeyboardView::KeyboardView() fRepeatSlider->SetHashMarks(B_HASH_MARKS_BOTTOM); fRepeatSlider->SetHashMarkCount(5); fRepeatSlider->SetLimitLabels(B_TRANSLATE("Slow"),B_TRANSLATE("Fast")); + fRepeatSlider->SetExplicitMinSize(BSize(200, B_SIZE_UNSET)); // Create the "Delay until key repeat" slider... @@ -60,14 +60,10 @@ KeyboardView::KeyboardView() textcontrol->StringWidth(B_TRANSLATE("Typing test area")), B_SIZE_UNSET)); // Build the layout - SetLayout(new BGroupLayout(B_HORIZONTAL)); - - AddChild(BGroupLayoutBuilder(B_VERTICAL, 10) + BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING) .Add(fRepeatSlider) .Add(fDelaySlider) - .Add(textcontrol) - .SetInsets(10, 10, 10, 10) - ); + .Add(textcontrol); } diff --git a/src/preferences/keyboard/KeyboardWindow.cpp b/src/preferences/keyboard/KeyboardWindow.cpp index a0fe65ed69..3014fbfede 100644 --- a/src/preferences/keyboard/KeyboardWindow.cpp +++ b/src/preferences/keyboard/KeyboardWindow.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -36,8 +37,6 @@ KeyboardWindow::KeyboardWindow() // Add the main settings view fSettingsView = new KeyboardView(); - BBox* fSettingsBox = new BBox("keyboard_box"); - fSettingsBox->AddChild(fSettingsView); // Add the "Default" button.. fDefaultsButton = new BButton(B_TRANSLATE("Defaults"), new BMessage(BUTTON_DEFAULTS)); @@ -48,12 +47,18 @@ KeyboardWindow::KeyboardWindow() // Build the layout BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) - .Add(fSettingsBox) .AddGroup(B_HORIZONTAL) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, 0) + .Add(fSettingsView) + .End() + .Add(new BSeparatorView(B_HORIZONTAL)) + .AddGroup(B_HORIZONTAL) + .SetInsets(B_USE_WINDOW_SPACING, 0, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING) .Add(fDefaultsButton) .Add(fRevertButton) - .AddGlue(); + .End(); BSlider* slider = (BSlider* )FindView("key_repeat_rate"); if (slider !=NULL) diff --git a/src/preferences/keymap/ModifierKeysWindow.cpp b/src/preferences/keymap/ModifierKeysWindow.cpp index b18f9f713f..621f50c24c 100644 --- a/src/preferences/keymap/ModifierKeysWindow.cpp +++ b/src/preferences/keymap/ModifierKeysWindow.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -289,7 +290,7 @@ ModifierKeysWindow::ModifierKeysWindow() new BMessage(kMsgApplyModifiers)); fOkButton->MakeDefault(true); - BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_SMALL_SPACING) + BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING) .AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING) .Add(keyRole, 0, 0) .Add(keyLabel, 1, 0) diff --git a/src/preferences/mouse/MouseWindow.cpp b/src/preferences/mouse/MouseWindow.cpp index 06e7e5a317..4ce29a8776 100644 --- a/src/preferences/mouse/MouseWindow.cpp +++ b/src/preferences/mouse/MouseWindow.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "MouseWindow.h" @@ -39,8 +40,6 @@ MouseWindow::MouseWindow(BRect _rect) { // Add the main settings view fSettingsView = new SettingsView(fSettings); - fSettingsBox = new BBox("main box"); - fSettingsBox->AddChild(fSettingsView); // Add the "Default" button fDefaultsButton = new BButton(B_TRANSLATE("Defaults"), @@ -58,12 +57,19 @@ MouseWindow::MouseWindow(BRect _rect) // Build the layout BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) - .Add(fSettingsBox) .AddGroup(B_HORIZONTAL) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, 0) + .Add(fSettingsView) + .End() + .Add(new BSeparatorView(B_HORIZONTAL)) + .AddGroup(B_HORIZONTAL) + .SetInsets(B_USE_WINDOW_SPACING, 0, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING) .Add(fDefaultsButton) .Add(fRevertButton) - .AddGlue(); + .AddGlue() + .End(); // check if the window is on screen BRect rect = BScreen().Frame(); diff --git a/src/preferences/mouse/SettingsView.cpp b/src/preferences/mouse/SettingsView.cpp index bc806db173..fdb9b27c1d 100644 --- a/src/preferences/mouse/SettingsView.cpp +++ b/src/preferences/mouse/SettingsView.cpp @@ -17,9 +17,8 @@ #include #include #include -#include -#include #include +#include #include #include #include @@ -137,7 +136,7 @@ SettingsView::SettingsView(MouseSettings& settings) BMenuField* focusField = new BMenuField(B_TRANSLATE("Focus mode:"), fFocusMenu); - focusField->SetAlignment(B_ALIGN_RIGHT); + focusField->SetAlignment(B_ALIGN_LEFT); // Add the "Focus follows mouse mode" pop up menu fFocusFollowsMouseMenu = new BPopUpMenu(B_TRANSLATE("Normal")); @@ -165,61 +164,49 @@ SettingsView::SettingsView(MouseSettings& settings) fAcceptFirstClickBox = new BCheckBox(B_TRANSLATE("Accept first click"), new BMessage(kMsgAcceptFirstClick)); - // dividers - // This one is a vertical line for B_HORIZONTAL - BSeparatorView* hdivider = new BSeparatorView(B_VERTICAL, B_FANCY_BORDER); - - // This one is a horizontal line for B_VERTICAL - BSeparatorView* vdivider = new BSeparatorView(B_HORIZONTAL, B_FANCY_BORDER); - // Build the layout - SetLayout(new BGroupLayout(B_VERTICAL)); // Layout is : // A | B // ----- // C - AddChild(BGroupLayoutBuilder(B_VERTICAL, B_USE_SMALL_SPACING) - + BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING) // Horizontal : A|B - .AddGroup(B_HORIZONTAL, B_USE_SMALL_SPACING) + .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) // Vertical block A: mouse type/view/test - .AddGroup(B_VERTICAL, 10) + .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING) .AddGroup(B_HORIZONTAL, 0) .AddGlue() .Add(typeField) .AddGlue() - .End() + .End() .AddGlue() - - .Add(BGroupLayoutBuilder(B_HORIZONTAL, 0) + .AddGroup(B_HORIZONTAL, 0) .AddGlue() .Add(fMouseView) .AddGlue() - ) + .End() .AddGlue() .Add(doubleClickTextControl) - .End() - - .Add(hdivider) + .End() + .Add(new BSeparatorView(B_VERTICAL)) // Vertical block B: speed settings .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING, 3) - .Add(BGroupLayoutBuilder(B_HORIZONTAL, 0) + .AddGroup(B_HORIZONTAL, 0) .Add(fClickSpeedSlider) - ) - .Add(BGroupLayoutBuilder(B_HORIZONTAL, 0) + .End() + .AddGroup(B_HORIZONTAL, 0) .Add(fMouseSpeedSlider) - ) - .Add(BGroupLayoutBuilder(B_HORIZONTAL, 0) + .End() + .AddGroup(B_HORIZONTAL, 0) .Add(fAccelerationSlider) - ) + .End() + .End() .End() - .End() - - .Add(vdivider) + .AddStrut(B_USE_DEFAULT_SPACING) // Horizontal Block C: focus mode .AddGroup(B_HORIZONTAL, B_USE_SMALL_SPACING) @@ -227,11 +214,10 @@ SettingsView::SettingsView(MouseSettings& settings) .AddGlue() .AddGroup(B_VERTICAL, 0) .Add(fAcceptFirstClickBox) - .End() - .End() - .SetInsets(B_USE_SMALL_SPACING, B_USE_SMALL_SPACING, - B_USE_SMALL_SPACING, B_USE_SMALL_SPACING) - ); + .End() + .End(); + + SetBorder(B_NO_BORDER); } From ad926b253a0bd4711ecbfdc9026b4ae811306922 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Sat, 7 Nov 2015 17:20:18 +0100 Subject: [PATCH 095/370] Improve/fix tab view layout as discussed See http://www.freelists.org/post/haiku-development/Unifying-visuals-of-BTabView-usage Besides the tab bar going the full width of the window, also some layouting tweaks to several apps and prefs. Still missing: the first (and last) tabs in the tab bar should be inset by B_USE_WINDOW_SPACING so the controls in the tab view line up nicely. I think I remember stippi wanting to look into it... :) --- src/apps/webpositive/SettingsWindow.cpp | 18 +++---- src/preferences/appearance/APRView.cpp | 17 +++---- src/preferences/appearance/APRWindow.cpp | 9 +++- .../appearance/AntialiasingSettingsView.cpp | 12 ++--- src/preferences/appearance/FontView.cpp | 3 +- .../appearance/LookAndFeelSettingsView.cpp | 33 +++++-------- src/preferences/locale/FormatSettingsView.cpp | 6 +-- src/preferences/locale/LocaleWindow.cpp | 31 +++++++----- src/preferences/mail/ConfigWindow.cpp | 22 ++++++--- src/preferences/notifications/DisplayView.cpp | 23 ++++----- src/preferences/notifications/GeneralView.cpp | 48 ++++++++----------- .../notifications/NotificationsView.cpp | 45 ++++++++--------- src/preferences/notifications/PrefletView.cpp | 10 ++-- src/preferences/notifications/PrefletWin.cpp | 15 ++++-- src/preferences/time/ClockView.cpp | 3 +- src/preferences/time/DateTimeView.cpp | 10 ++-- src/preferences/time/NetworkTimeView.cpp | 3 +- src/preferences/time/TimeWindow.cpp | 12 +++-- src/preferences/time/ZoneView.cpp | 8 ++-- 19 files changed, 160 insertions(+), 168 deletions(-) diff --git a/src/apps/webpositive/SettingsWindow.cpp b/src/apps/webpositive/SettingsWindow.cpp index 36d75cfb1d..8ac49408b7 100644 --- a/src/apps/webpositive/SettingsWindow.cpp +++ b/src/apps/webpositive/SettingsWindow.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -81,8 +82,6 @@ SettingsWindow::SettingsWindow(BRect frame, SettingsMessage* settings) | B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE), fSettings(settings) { - SetLayout(new BGroupLayout(B_VERTICAL)); - fApplyButton = new BButton(B_TRANSLATE("Apply"), new BMessage(MSG_APPLY)); fCancelButton = new BButton(B_TRANSLATE("Cancel"), new BMessage(MSG_CANCEL)); @@ -92,17 +91,19 @@ SettingsWindow::SettingsWindow(BRect frame, SettingsMessage* settings) float spacing = be_control_look->DefaultItemSpacing(); BTabView* tabView = new BTabView("settings pages", B_WIDTH_FROM_LABEL); + tabView->SetBorder(B_NO_BORDER); - AddChild(BGroupLayoutBuilder(B_VERTICAL, spacing) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) + .SetInsets(0, B_USE_DEFAULT_SPACING, 0, B_USE_WINDOW_SPACING) .Add(tabView) - .Add(BGroupLayoutBuilder(B_HORIZONTAL, spacing) + .Add(new BSeparatorView(B_HORIZONTAL)) + .AddGroup(B_HORIZONTAL) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, + B_USE_WINDOW_SPACING, 0) .Add(fRevertButton) .AddGlue() .Add(fCancelButton) - .Add(fApplyButton) - ) - .SetInsets(spacing, spacing, spacing, spacing) - ); + .Add(fApplyButton); tabView->AddTab(_CreateGeneralPage(spacing)); tabView->AddTab(_CreateFontsPage(spacing)); @@ -484,6 +485,7 @@ SettingsWindow::_CreateProxyPage(float spacing) .Add(fProxyPortControl->CreateLabelLayoutItem(), 0, 1) .Add(fProxyPortControl->CreateTextViewLayoutItem(), 1, 1) ) + .Add(BSpaceLayoutItem::CreateVerticalStrut(spacing)) .Add(fUseProxyAuthCheckBox) .Add(BGridLayoutBuilder(spacing / 2, spacing / 2) .Add(fProxyUsernameControl->CreateLabelLayoutItem(), 0, 0) diff --git a/src/preferences/appearance/APRView.cpp b/src/preferences/appearance/APRView.cpp index 401fa162b7..b1e587ad25 100644 --- a/src/preferences/appearance/APRView.cpp +++ b/src/preferences/appearance/APRView.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -96,18 +96,13 @@ APRView::APRView(const char* name) fPicker = new BColorControl(B_ORIGIN, B_CELLS_32x8, 8.0, "picker", new BMessage(UPDATE_COLOR)); - SetLayout(new BGroupLayout(B_VERTICAL)); - - AddChild(BGroupLayoutBuilder(B_VERTICAL, 0) - .Add(fScrollView) - .Add(BSpaceLayoutItem::CreateVerticalStrut(5)) - .Add(BGroupLayoutBuilder(B_HORIZONTAL) + BLayoutBuilder::Group<>(this, B_VERTICAL) + .Add(fScrollView, 10.0) + .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) .Add(fColorPreview) - .Add(BSpaceLayoutItem::CreateHorizontalStrut(5)) .Add(fPicker) - ) - .SetInsets(10, 10, 10, 10) - ); + .End() + .SetInsets(B_USE_WINDOW_SPACING); fColorPreview->Parent()->SetExplicitMaxSize( BSize(B_SIZE_UNSET, fPicker->Bounds().Height())); diff --git a/src/preferences/appearance/APRWindow.cpp b/src/preferences/appearance/APRWindow.cpp index 71b30cfee6..85116049bc 100644 --- a/src/preferences/appearance/APRWindow.cpp +++ b/src/preferences/appearance/APRWindow.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "AntialiasingSettingsView.h" @@ -61,15 +62,19 @@ APRWindow::APRWindow(BRect frame) tabView->AddTab(fColorsView); tabView->AddTab(fLookAndFeelSettings); tabView->AddTab(fAntialiasingSettings); + tabView->SetBorder(B_NO_BORDER); _UpdateButtons(); - BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) + .SetInsets(0, B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING) .Add(tabView) + .Add(new BSeparatorView(B_HORIZONTAL)) .AddGroup(B_HORIZONTAL) .Add(fDefaultsButton) .Add(fRevertButton) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, + B_USE_DEFAULT_SPACING, 0) .AddGlue(); } diff --git a/src/preferences/appearance/AntialiasingSettingsView.cpp b/src/preferences/appearance/AntialiasingSettingsView.cpp index ab11ac9324..c90b507474 100644 --- a/src/preferences/appearance/AntialiasingSettingsView.cpp +++ b/src/preferences/appearance/AntialiasingSettingsView.cpp @@ -16,8 +16,7 @@ #include #include -#include -#include +#include #include #include #include @@ -136,10 +135,8 @@ AntialiasingSettingsView::AntialiasingSettingsView(const char* name) subpixelAntialiasingDisabledLabel->MakeSelectable(false); #endif // !FT_CONFIG_OPTION_SUBPIXEL_RENDERING - SetLayout(new BGroupLayout(B_VERTICAL)); - + BLayoutBuilder::Grid<>(this, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING) // controls pane - AddChild(BGridLayoutBuilder(10, 10) .Add(fHintingMenuField->CreateLabelLayoutItem(), 0, 0) .Add(fHintingMenuField->CreateMenuBarLayoutItem(), 1, 0) @@ -154,9 +151,8 @@ AntialiasingSettingsView::AntialiasingSettingsView(const char* name) #else .Add(BSpaceLayoutItem::CreateGlue(), 0, 3, 2) #endif - - .SetInsets(10, 10, 10, 10) - ); + .AddGlue(0, 4) + .SetInsets(B_USE_WINDOW_SPACING); _SetCurrentAntialiasing(); _SetCurrentHinting(); diff --git a/src/preferences/appearance/FontView.cpp b/src/preferences/appearance/FontView.cpp index 3a686e47b5..74d78e0309 100644 --- a/src/preferences/appearance/FontView.cpp +++ b/src/preferences/appearance/FontView.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -71,7 +72,7 @@ FontView::FontView(const char* name) fMenuView = new FontSelectionView("menu", B_TRANSLATE("Menu font:")); BGridLayout* layout = new BGridLayout(5, 5); - layout->SetInsets(10, 10, 10, 10); + layout->SetInsets(B_USE_WINDOW_SPACING); SetLayout(layout); int32 row = 0; diff --git a/src/preferences/appearance/LookAndFeelSettingsView.cpp b/src/preferences/appearance/LookAndFeelSettingsView.cpp index 5e7f252639..a3f57129b0 100644 --- a/src/preferences/appearance/LookAndFeelSettingsView.cpp +++ b/src/preferences/appearance/LookAndFeelSettingsView.cpp @@ -21,8 +21,6 @@ #include #include #include -#include -#include #include #include #include @@ -95,7 +93,7 @@ LookAndFeelSettingsView::LookAndFeelSettingsView(const char* name) .AddGroup(B_VERTICAL, 1) .Add(new BStringView("single", B_TRANSLATE("Single:"))) .Add(fArrowStyleSingle) - .Add(new BStringView("spacer", "")) + .AddStrut(B_USE_DEFAULT_SPACING) .Add(new BStringView("double", B_TRANSLATE("Double:"))) .Add(fArrowStyleDouble) .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, @@ -105,32 +103,23 @@ LookAndFeelSettingsView::LookAndFeelSettingsView(const char* name) arrowStyleBox->AddChild(arrowStyleView); arrowStyleBox->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER)); + arrowStyleBox->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); BStringView* scrollBarLabel = new BStringView("scroll bar", B_TRANSLATE("Scroll bar:")); scrollBarLabel->SetExplicitAlignment( BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP)); - SetLayout(new BGroupLayout(B_VERTICAL)); - // control layout - AddChild(BGroupLayoutBuilder(B_VERTICAL, B_USE_DEFAULT_SPACING) - .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING) - .Add(BGridLayoutBuilder(B_USE_DEFAULT_SPACING, - B_USE_DEFAULT_SPACING) - .Add(fDecorMenuField->CreateLabelLayoutItem(), 0, 0) - .Add(fDecorMenuField->CreateMenuBarLayoutItem(), 1, 0) - .Add(fDecorInfoButton, 2, 0) - ) - .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) - .Add(scrollBarLabel) - .Add(arrowStyleBox) - .End() - .AddGlue() - .End() - .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, - B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING) - ); + BLayoutBuilder::Grid<>(this, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING) + .Add(fDecorMenuField->CreateLabelLayoutItem(), 0, 0) + .Add(fDecorMenuField->CreateMenuBarLayoutItem(), 1, 0) + .Add(fDecorInfoButton, 2, 0) + .Add(scrollBarLabel, 0, 1) + .Add(arrowStyleBox, 1, 1) + .AddGlue(0, 2) + .SetInsets(B_USE_WINDOW_SPACING); + // TODO : Decorator Preview Image? } diff --git a/src/preferences/locale/FormatSettingsView.cpp b/src/preferences/locale/FormatSettingsView.cpp index 6463c4d8a9..8de1d675ab 100644 --- a/src/preferences/locale/FormatSettingsView.cpp +++ b/src/preferences/locale/FormatSettingsView.cpp @@ -227,17 +227,13 @@ FormatSettingsView::FormatSettingsView() .Add(BSpaceLayoutItem::CreateGlue(), 2, 1) .View()); - BGroupLayout* rootLayout = new BGroupLayout(B_VERTICAL, spacing); - SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - SetLayout(rootLayout); - BLayoutBuilder::Group<>(rootLayout) + BLayoutBuilder::Group<>(this, B_VERTICAL) .Add(fUseLanguageStringsCheckBox) .Add(fDateBox) .Add(fTimeBox) .AddGroup(B_HORIZONTAL, spacing) .Add(fNumberBox) .Add(fMonetaryBox) - .AddGlue() .End() .AddGlue(); } diff --git a/src/preferences/locale/LocaleWindow.cpp b/src/preferences/locale/LocaleWindow.cpp index ef8c2de6ce..d66d41020e 100644 --- a/src/preferences/locale/LocaleWindow.cpp +++ b/src/preferences/locale/LocaleWindow.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -78,6 +79,8 @@ LocaleWindow::LocaleWindow() float spacing = be_control_look->DefaultItemSpacing(); BTabView* tabView = new BTabView("tabview", B_WIDTH_FROM_WIDEST); + tabView->SetBorder(B_NO_BORDER); + BGroupView* languageTab = new BGroupView(B_TRANSLATE("Language"), B_HORIZONTAL, spacing); @@ -165,15 +168,16 @@ LocaleWindow::LocaleWindow() new BMessage(kMsgPreferredLanguageDragged)); BLayoutBuilder::Group<>(languageTab) - .AddGroup(B_VERTICAL, spacing) + .AddGroup(B_VERTICAL) .Add(new BStringView("", B_TRANSLATE("Available languages"))) .Add(scrollView) .End() - .AddGroup(B_VERTICAL, spacing) + .AddGroup(B_VERTICAL) .Add(new BStringView("", B_TRANSLATE("Preferred languages"))) .Add(scrollViewEnabled) .End() - .SetInsets(spacing, spacing, spacing, spacing); + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING); BView* countryTab = new BView(B_TRANSLATE("Formatting"), B_WILL_DRAW); countryTab->SetLayout(new BGroupLayout(B_VERTICAL, 0)); @@ -242,7 +246,8 @@ LocaleWindow::LocaleWindow() .Add(scrollView) .End() .Add(fFormatView) - .SetInsets(spacing, spacing, spacing, spacing)); + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING)); BView* optionsTab = new BView(B_TRANSLATE("Options"), B_WILL_DRAW); optionsTab->SetLayout(new BGroupLayout(B_VERTICAL, 0)); @@ -254,10 +259,11 @@ LocaleWindow::LocaleWindow() fFilesystemTranslationCheckbox->SetValue( BLocaleRoster::Default()->IsFilesystemTranslationPreferred()); - optionsTab->AddChild(BLayoutBuilder::Group<>(B_VERTICAL, spacing) + optionsTab->AddChild(BLayoutBuilder::Group<>(B_VERTICAL) .Add(fFilesystemTranslationCheckbox) .AddGlue() - .SetInsets(spacing, spacing, spacing, spacing)); + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING)); tabView->AddTab(languageTab); tabView->AddTab(countryTab); @@ -270,15 +276,16 @@ LocaleWindow::LocaleWindow() = new BButton(B_TRANSLATE("Revert"), new BMessage(kMsgRevert)); fRevertButton->SetEnabled(false); - BLayoutBuilder::Group<>(this, B_VERTICAL, spacing) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) + .SetInsets(0, B_USE_DEFAULT_SPACING, 0, B_USE_WINDOW_SPACING) .Add(tabView) - .AddGroup(B_HORIZONTAL, spacing) + .Add(new BSeparatorView(B_HORIZONTAL)) + .AddGroup(B_HORIZONTAL) .Add(button) .Add(fRevertButton) - .AddGlue() - .End() - .SetInsets(spacing, spacing, spacing, spacing) - .End(); + .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, + B_USE_WINDOW_SPACING, 0) + .AddGlue(); _Refresh(true); _SettingsReverted(); diff --git a/src/preferences/mail/ConfigWindow.cpp b/src/preferences/mail/ConfigWindow.cpp index a9b07d98eb..2afb5a40e2 100644 --- a/src/preferences/mail/ConfigWindow.cpp +++ b/src/preferences/mail/ConfigWindow.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -208,6 +209,7 @@ ConfigWindow::ConfigWindow() fSaveSettings(false) { BTabView* tabView = new BTabView("tab"); + tabView->SetBorder(B_NO_BORDER); // accounts listview @@ -231,7 +233,8 @@ ConfigWindow::ConfigWindow() false, true); BLayoutBuilder::Group<>(view, B_HORIZONTAL) - .SetInsets(B_USE_DEFAULT_SPACING) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) .AddGroup(B_VERTICAL) .Add(scroller) .AddGroup(B_HORIZONTAL) @@ -287,11 +290,13 @@ ConfigWindow::ConfigWindow() editMenuButton->SetEnabled(false); BLayoutBuilder::Group<>(view, B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) - .AddGlue() + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) +// .AddGlue() .AddGroup(B_HORIZONTAL, 0.f) .AddGlue() .Add(fCheckMailCheckBox) + .AddStrut(be_control_look->DefaultLabelSpacing()) .Add(fIntervalControl->CreateTextViewLayoutItem()) .AddStrut(be_control_look->DefaultLabelSpacing()) .Add(fIntervalControl->CreateLabelLayoutItem()) @@ -313,13 +318,16 @@ ConfigWindow::ConfigWindow() BButton* revertButton = new BButton("revert", B_TRANSLATE("Revert"), new BMessage(kMsgRevertSettings)); - BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) + .SetInsets(0, B_USE_DEFAULT_SPACING, 0, B_USE_WINDOW_SPACING) .Add(tabView) - .AddGroup(B_HORIZONTAL) + .Add(new BSeparatorView(B_HORIZONTAL)) + .AddGroup(B_HORIZONTAL, 0) .Add(revertButton) .AddGlue() - .Add(applyButton); + .Add(applyButton) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, + B_USE_WINDOW_SPACING, 0); _LoadSettings(); // this will also move our window to the stored position diff --git a/src/preferences/notifications/DisplayView.cpp b/src/preferences/notifications/DisplayView.cpp index 98bde3c499..afe02a0928 100644 --- a/src/preferences/notifications/DisplayView.cpp +++ b/src/preferences/notifications/DisplayView.cpp @@ -13,19 +13,19 @@ #include #include #include -#include #include -#include -#include -#include -#include +#include #include #include #include +#include #include #include -#include #include +#include +#include + +#include #include "DisplayView.h" #include "SettingsHost.h" @@ -52,18 +52,13 @@ DisplayView::DisplayView(SettingsHost* host) fIconSize->SetLabelFromMarked(true); fIconSizeField = new BMenuField(B_TRANSLATE("Icon size:"), fIconSize); - // Calculate inset - float inset = ceilf(be_plain_font->Size() * 0.7f); - - SetLayout(new BGroupLayout(B_VERTICAL)); - AddChild(BGridLayoutBuilder(inset, inset) + BLayoutBuilder::Grid<>(this, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING) .Add(fWindowWidth->CreateLabelLayoutItem(), 0, 0) .Add(fWindowWidth->CreateTextViewLayoutItem(), 1, 0) .Add(fIconSizeField->CreateLabelLayoutItem(), 0, 1) .Add(fIconSizeField->CreateMenuBarLayoutItem(), 1, 1) - .Add(BSpaceLayoutItem::CreateGlue(), 0, 2, 2, 1) - .SetInsets(inset, inset, inset, inset) - ); + .AddGlue(0, 2) + .SetInsets(B_USE_WINDOW_SPACING); } diff --git a/src/preferences/notifications/GeneralView.cpp b/src/preferences/notifications/GeneralView.cpp index 55a1f91a16..a11f4b9b9c 100644 --- a/src/preferences/notifications/GeneralView.cpp +++ b/src/preferences/notifications/GeneralView.cpp @@ -12,27 +12,27 @@ #include -#include -#include -#include #include -#include #include #include -#include -#include #include -#include -#include -#include -#include -#include -#include #include -#include -#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include +#include +#include +#include + +#include #include "GeneralView.h" #include "SettingsHost.h" @@ -62,20 +62,15 @@ GeneralView::GeneralView(SettingsHost* host) B_TRANSLATE("seconds of inactivity")); // Default position - // TODO: Here will come a screen representation with the four corners + // TODO: Here will come a screen representation with the four corners // clickable - // Calculate inset - float inset = ceilf(be_plain_font->Size() * 0.7f); - - SetLayout(new BGroupLayout(B_VERTICAL)); - AddChild(BGroupLayoutBuilder(B_VERTICAL, inset) - .AddGroup(B_HORIZONTAL, inset) + BLayoutBuilder::Group<>(this, B_VERTICAL) + .AddGroup(B_HORIZONTAL, B_USE_WINDOW_SPACING) .Add(fNotificationBox) .AddGlue() .End() - - .AddGroup(B_VERTICAL, inset) + .AddGroup(B_VERTICAL, B_USE_WINDOW_SPACING) .Add(fAutoStart) .AddGroup(B_HORIZONTAL) .AddGroup(B_HORIZONTAL, 2) @@ -84,9 +79,8 @@ GeneralView::GeneralView(SettingsHost* host) .End() .End() .End() - .SetInsets(inset, inset, inset, inset) - .AddGlue() - ); + .SetInsets(B_USE_WINDOW_SPACING) + .AddGlue(); } @@ -165,7 +159,7 @@ GeneralView::MessageReceived(BMessage* msg) } } break; - } + } case kSettingChanged: SettingsPane::MessageReceived(msg); break; diff --git a/src/preferences/notifications/NotificationsView.cpp b/src/preferences/notifications/NotificationsView.cpp index fcb02dc58b..ccca0543ae 100644 --- a/src/preferences/notifications/NotificationsView.cpp +++ b/src/preferences/notifications/NotificationsView.cpp @@ -9,20 +9,19 @@ #include #include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include - #include #include +#include +#include +#include +#include +#include +#include +#include + +#include +#include #include "NotificationsView.h" @@ -59,23 +58,23 @@ NotificationsView::NotificationsView(SettingsHost* host) new BMessage(kSettingChanged)); // Applications list - fApplications = new BColumnListView(rect, B_TRANSLATE("Applications"), - 0, B_WILL_DRAW, B_FANCY_BORDER, true); + fApplications = new BColumnListView(B_TRANSLATE("Applications"), + 0, B_FANCY_BORDER, true); fApplications->SetSelectionMode(B_SINGLE_SELECTION_LIST); fAppCol = new BStringColumn(B_TRANSLATE("Application"), 200, - be_plain_font->StringWidth(B_TRANSLATE("Application")) + + be_plain_font->StringWidth(B_TRANSLATE("Application")) + (kCLVTitlePadding * 2), rect.Width(), B_TRUNCATE_END, B_ALIGN_LEFT); fApplications->AddColumn(fAppCol, kAppIndex); fAppEnabledCol = new BStringColumn(B_TRANSLATE("Enabled"), 10, - be_plain_font->StringWidth(B_TRANSLATE("Enabled")) + + be_plain_font->StringWidth(B_TRANSLATE("Enabled")) + (kCLVTitlePadding * 2), rect.Width(), B_TRUNCATE_END, B_ALIGN_LEFT); fApplications->AddColumn(fAppEnabledCol, kAppEnabledIndex); // Notifications list - fNotifications = new BColumnListView(rect, B_TRANSLATE("Notifications"), - 0, B_WILL_DRAW, B_FANCY_BORDER, true); + fNotifications = new BColumnListView(B_TRANSLATE("Notifications"), + 0, B_FANCY_BORDER, true); fNotifications->SetSelectionMode(B_SINGLE_SELECTION_LIST); fTitleCol = new BStringColumn(B_TRANSLATE("Title"), 100, @@ -98,22 +97,16 @@ NotificationsView::NotificationsView(SettingsHost* host) (kCLVTitlePadding * 2), rect.Width(), B_TRUNCATE_END, B_ALIGN_LEFT); fNotifications->AddColumn(fAllowCol, kAllowIndex); - // Calculate inset - float inset = ceilf(be_plain_font->Size() * 0.7f); - - // Set layout - SetLayout(new BGroupLayout(B_VERTICAL)); - // Add views - AddChild(BGroupLayoutBuilder(B_VERTICAL, inset) + BLayoutBuilder::Group<>(this, B_VERTICAL) .AddGroup(B_HORIZONTAL) .AddGlue() .Add(fSearch) .End() .Add(fApplications) .Add(fNotifications) - .SetInsets(inset, inset, inset, inset) - ); + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING); } diff --git a/src/preferences/notifications/PrefletView.cpp b/src/preferences/notifications/PrefletView.cpp index df155e4672..82cc5c63cd 100644 --- a/src/preferences/notifications/PrefletView.cpp +++ b/src/preferences/notifications/PrefletView.cpp @@ -8,17 +8,17 @@ */ #include -#include +#include #include #include -#include #include +#include -#include "SettingsHost.h" -#include "PrefletView.h" -#include "GeneralView.h" #include "DisplayView.h" +#include "GeneralView.h" #include "NotificationsView.h" +#include "PrefletView.h" +#include "SettingsHost.h" #undef B_TRANSLATION_CONTEXT diff --git a/src/preferences/notifications/PrefletWin.cpp b/src/preferences/notifications/PrefletWin.cpp index 64b1e492be..465604b798 100644 --- a/src/preferences/notifications/PrefletWin.cpp +++ b/src/preferences/notifications/PrefletWin.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -33,11 +34,12 @@ const int32 kApply = '_APY'; PrefletWin::PrefletWin() : BWindow(BRect(0, 0, 1, 1), B_TRANSLATE_SYSTEM_NAME("Notifications"), - B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_NOT_RESIZABLE - | B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS) + B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS + | B_AUTO_UPDATE_SIZE_LIMITS) { // Preflet container view fMainView = new PrefletView(this); + fMainView->SetBorder(B_NO_BORDER); // Apply and revert buttons fRevert = new BButton("revert", B_TRANSLATE("Revert"), @@ -47,13 +49,16 @@ PrefletWin::PrefletWin() fApply->SetEnabled(false); // Build the layout - BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) + .SetInsets(0, B_USE_DEFAULT_SPACING, 0, 0) .Add(fMainView) + .Add(new BSeparatorView(B_HORIZONTAL)) .AddGroup(B_HORIZONTAL) .Add(fRevert) .AddGlue() - .Add(fApply); + .Add(fApply) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, + B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING); ReloadSettings(); diff --git a/src/preferences/time/ClockView.cpp b/src/preferences/time/ClockView.cpp index 04746823ba..a67d2198e9 100644 --- a/src/preferences/time/ClockView.cpp +++ b/src/preferences/time/ClockView.cpp @@ -67,7 +67,8 @@ ClockView::ClockView(const char* name) .AddGroup(B_VERTICAL, 0) .Add(showClockBox) .End() - .SetInsets(B_USE_DEFAULT_SPACING); + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING); } diff --git a/src/preferences/time/DateTimeView.cpp b/src/preferences/time/DateTimeView.cpp index 0dd9b3c956..487ca4f8b9 100644 --- a/src/preferences/time/DateTimeView.cpp +++ b/src/preferences/time/DateTimeView.cpp @@ -186,18 +186,18 @@ DateTimeView::_InitView() B_WILL_DRAW | B_FRAME_EVENTS, B_FANCY_BORDER); divider->SetExplicitMaxSize(BSize(1, B_SIZE_UNLIMITED)); - const float kInset = be_control_look->DefaultItemSpacing(); - BLayoutBuilder::Group<>(this) - .AddGroup(B_VERTICAL, kInset / 2) + BLayoutBuilder::Group<>(this, B_HORIZONTAL, B_USE_DEFAULT_SPACING) + .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING) .Add(fDateEdit) .Add(fCalendarView) .End() .Add(divider) - .AddGroup(B_VERTICAL, 0) + .AddGroup(B_VERTICAL) .Add(fTimeEdit) .Add(fClock) .End() - .SetInsets(kInset, kInset, kInset, kInset); + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING); } diff --git a/src/preferences/time/NetworkTimeView.cpp b/src/preferences/time/NetworkTimeView.cpp index 4d44b3071a..f5fa4ddcb6 100644 --- a/src/preferences/time/NetworkTimeView.cpp +++ b/src/preferences/time/NetworkTimeView.cpp @@ -524,7 +524,8 @@ NetworkTimeView::_InitView() .Add(fResetButton) .Add(fSynchronizeButton) .End() - .SetInsets(B_USE_DEFAULT_SPACING); + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING); } diff --git a/src/preferences/time/TimeWindow.cpp b/src/preferences/time/TimeWindow.cpp index 63b640a92d..c248628f4e 100644 --- a/src/preferences/time/TimeWindow.cpp +++ b/src/preferences/time/TimeWindow.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "BaseView.h" @@ -129,6 +130,7 @@ TTimeWindow::_InitWindow() fTabView->AddTab(fTimeZoneView); fTabView->AddTab(fNetworkTimeView); fTabView->AddTab(fClockView); + fTabView->SetBorder(B_NO_BORDER); fBaseView->AddChild(fTabView); @@ -139,10 +141,14 @@ TTimeWindow::_InitWindow() fRevertButton->SetExplicitAlignment( BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE)); - BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) + BLayoutBuilder::Group<>(this, B_VERTICAL, 0) + .SetInsets(0, B_USE_DEFAULT_SPACING, 0, 0) .Add(fBaseView) - .Add(fRevertButton); + .Add(new BSeparatorView(B_HORIZONTAL)) + .AddGroup(B_HORIZONTAL) + .Add(fRevertButton) + .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, + B_USE_DEFAULT_SPACING, B_USE_WINDOW_SPACING); } diff --git a/src/preferences/time/ZoneView.cpp b/src/preferences/time/ZoneView.cpp index 29b24c3038..6e20785d10 100644 --- a/src/preferences/time/ZoneView.cpp +++ b/src/preferences/time/ZoneView.cpp @@ -238,8 +238,6 @@ TimeZoneView::_InitView() _ShowOrHidePreview(); fOldUseGmtTime = fUseGmtTime; - const float kIndentSpacing - = be_control_look->DefaultItemSpacing() * 2; BLayoutBuilder::Group<>(this) .Add(scrollList) .AddGroup(B_VERTICAL, 0) @@ -248,7 +246,7 @@ TimeZoneView::_InitView() .AddGroup(B_VERTICAL, 0) .Add(fLocalTime) .Add(fGmtTime) - .SetInsets(kIndentSpacing, 0, 0, 0) + .SetInsets(B_USE_WINDOW_SPACING, 0, 0, 0) .End() .AddGlue() .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING) @@ -257,8 +255,8 @@ TimeZoneView::_InitView() .End() .Add(fSetZone) .End() - .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, - B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING); + .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, + B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING); } From 95fd629fa32fcd0df88872749ae0ba9abd638d78 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sat, 7 Nov 2015 18:02:06 +0100 Subject: [PATCH 096/370] Don't use -mapcs-frame with Clang --- build/jam/ArchitectureRules | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/build/jam/ArchitectureRules b/build/jam/ArchitectureRules index 42a0159a1e..a9d05b67dd 100644 --- a/build/jam/ArchitectureRules +++ b/build/jam/ArchitectureRules @@ -43,8 +43,13 @@ rule ArchitectureSetup architecture local cpu = $(HAIKU_CPU_$(architecture)) ; if $(cpu) = arm { - # For stackcrawls - gccBaseFlags += -mapcs-frame ; + if $(HAIKU_CC_IS_CLANG_$(architecture)) = 1 { + # Clang only defines __ARMEL__ when using -target arm-haiku-unknown + gccBaseFlags += -D__ARM__=1 ; + } else { + # For stackcrawls - not supported by Clang + gccBaseFlags += -mapcs-frame ; + } } # activating graphite optimizations From 5213914cec1d865231170af94b1bfbb669f06db7 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sat, 7 Nov 2015 18:03:20 +0100 Subject: [PATCH 097/370] Fix flags for RPi2 There's no point in tuning for the RPi1 CPU. --- build/jam/board/rpi2/BoardSetup | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/jam/board/rpi2/BoardSetup b/build/jam/board/rpi2/BoardSetup index 0c8e8b8671..e9c285af9f 100644 --- a/build/jam/board/rpi2/BoardSetup +++ b/build/jam/board/rpi2/BoardSetup @@ -58,7 +58,7 @@ HAIKU_BOARD_SDIMAGE_SIZE = 128 ; # gcc flags for the specific cpu # -local flags = -mtune=arm1176jzf-s -march=armv7-a ; +local flags = -march=armv7-a -mfloat-abi=hard ; HAIKU_ASFLAGS_$(HAIKU_PACKAGING_ARCH) += $(flags) ; HAIKU_CCFLAGS_$(HAIKU_PACKAGING_ARCH) += $(flags) ; From 95d4ed6778c138150a29a435d2683adc1beb3692 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sat, 7 Nov 2015 18:06:38 +0100 Subject: [PATCH 098/370] Add missing "using std::nothrow" --- src/system/boot/loader/FileMapDisk.cpp | 4 ++++ src/system/boot/loader/file_systems/amiga_ffs/Directory.cpp | 3 +++ src/system/boot/loader/file_systems/amiga_ffs/File.cpp | 3 +++ src/system/boot/loader/file_systems/amiga_ffs/Volume.cpp | 1 + src/system/boot/loader/file_systems/bfs/Directory.cpp | 3 +++ src/system/boot/loader/file_systems/bfs/Stream.cpp | 1 + src/system/boot/loader/file_systems/bfs/bfs.cpp | 1 + src/system/boot/loader/file_systems/fat/Directory.cpp | 3 +++ src/system/boot/loader/file_systems/fat/Volume.cpp | 1 + src/system/boot/loader/file_systems/tarfs/tarfs.cpp | 4 ++++ src/system/boot/loader/net/NetStack.cpp | 3 +++ src/system/boot/loader/net/RemoteDisk.cpp | 4 ++++ src/system/boot/loader/net/UDP.cpp | 3 +++ 13 files changed, 34 insertions(+) diff --git a/src/system/boot/loader/FileMapDisk.cpp b/src/system/boot/loader/FileMapDisk.cpp index 89dc832b5c..06b2cd67c9 100644 --- a/src/system/boot/loader/FileMapDisk.cpp +++ b/src/system/boot/loader/FileMapDisk.cpp @@ -24,6 +24,10 @@ # define TRACE(x) ; #endif + +using std::nothrow; + + // constructor FileMapDisk::FileMapDisk() : diff --git a/src/system/boot/loader/file_systems/amiga_ffs/Directory.cpp b/src/system/boot/loader/file_systems/amiga_ffs/Directory.cpp index f0325a617d..43ea058d50 100644 --- a/src/system/boot/loader/file_systems/amiga_ffs/Directory.cpp +++ b/src/system/boot/loader/file_systems/amiga_ffs/Directory.cpp @@ -15,6 +15,9 @@ #include +using std::nothrow; + + namespace FFS { diff --git a/src/system/boot/loader/file_systems/amiga_ffs/File.cpp b/src/system/boot/loader/file_systems/amiga_ffs/File.cpp index f75be4f8ff..7222fb3ea0 100644 --- a/src/system/boot/loader/file_systems/amiga_ffs/File.cpp +++ b/src/system/boot/loader/file_systems/amiga_ffs/File.cpp @@ -11,6 +11,9 @@ #include +using std::nothrow; + + namespace FFS { diff --git a/src/system/boot/loader/file_systems/amiga_ffs/Volume.cpp b/src/system/boot/loader/file_systems/amiga_ffs/Volume.cpp index 295ff39f9d..996d2a1173 100644 --- a/src/system/boot/loader/file_systems/amiga_ffs/Volume.cpp +++ b/src/system/boot/loader/file_systems/amiga_ffs/Volume.cpp @@ -18,6 +18,7 @@ using namespace FFS; +using std::nothrow; Volume::Volume(boot::Partition *partition) diff --git a/src/system/boot/loader/file_systems/bfs/Directory.cpp b/src/system/boot/loader/file_systems/bfs/Directory.cpp index dda1c40bc7..ce1a688630 100644 --- a/src/system/boot/loader/file_systems/bfs/Directory.cpp +++ b/src/system/boot/loader/file_systems/bfs/Directory.cpp @@ -19,6 +19,9 @@ extern Node *get_node_from(int fd); +using std::nothrow; + + namespace BFS { diff --git a/src/system/boot/loader/file_systems/bfs/Stream.cpp b/src/system/boot/loader/file_systems/bfs/Stream.cpp index 4cdea7dd85..47a20e4816 100644 --- a/src/system/boot/loader/file_systems/bfs/Stream.cpp +++ b/src/system/boot/loader/file_systems/bfs/Stream.cpp @@ -18,6 +18,7 @@ using namespace BFS; +using std::nothrow; class CachedBlock { diff --git a/src/system/boot/loader/file_systems/bfs/bfs.cpp b/src/system/boot/loader/file_systems/bfs/bfs.cpp index 2bb31f95a6..f32e4bae78 100644 --- a/src/system/boot/loader/file_systems/bfs/bfs.cpp +++ b/src/system/boot/loader/file_systems/bfs/bfs.cpp @@ -27,6 +27,7 @@ using namespace BFS; +using std::nothrow; Volume::Volume(boot::Partition *partition) diff --git a/src/system/boot/loader/file_systems/fat/Directory.cpp b/src/system/boot/loader/file_systems/fat/Directory.cpp index 87a8f3f2af..559dae6d68 100644 --- a/src/system/boot/loader/file_systems/fat/Directory.cpp +++ b/src/system/boot/loader/file_systems/fat/Directory.cpp @@ -26,6 +26,9 @@ #define TRACE(x) do {} while (0) +using std::nothrow; + + namespace FATFS { diff --git a/src/system/boot/loader/file_systems/fat/Volume.cpp b/src/system/boot/loader/file_systems/fat/Volume.cpp index a6cbd35a5f..28b2dbcd24 100644 --- a/src/system/boot/loader/file_systems/fat/Volume.cpp +++ b/src/system/boot/loader/file_systems/fat/Volume.cpp @@ -24,6 +24,7 @@ using namespace FATFS; +using std::nothrow; Volume::Volume(boot::Partition *partition) diff --git a/src/system/boot/loader/file_systems/tarfs/tarfs.cpp b/src/system/boot/loader/file_systems/tarfs/tarfs.cpp index f5c19f7080..83e29e3b9f 100644 --- a/src/system/boot/loader/file_systems/tarfs/tarfs.cpp +++ b/src/system/boot/loader/file_systems/tarfs/tarfs.cpp @@ -37,6 +37,10 @@ static const uint32 kFloppyArchiveOffset = BOOT_ARCHIVE_IMAGE_OFFSET * 1024; // defined at build time, see build/jam/BuildSetup static const size_t kTarRegionSize = 8 * 1024 * 1024; // 8 MB + +using std::nothrow; + + namespace TarFS { diff --git a/src/system/boot/loader/net/NetStack.cpp b/src/system/boot/loader/net/NetStack.cpp index 52b354387d..7a172eeb4c 100644 --- a/src/system/boot/loader/net/NetStack.cpp +++ b/src/system/boot/loader/net/NetStack.cpp @@ -16,6 +16,9 @@ #include +using std::nothrow; + + // sNetStack NetStack *NetStack::sNetStack = NULL; diff --git a/src/system/boot/loader/net/RemoteDisk.cpp b/src/system/boot/loader/net/RemoteDisk.cpp index b78e5fa01d..6778f716c5 100644 --- a/src/system/boot/loader/net/RemoteDisk.cpp +++ b/src/system/boot/loader/net/RemoteDisk.cpp @@ -18,6 +18,10 @@ static const bigtime_t kRequestTimeout = 100000LL; + +using std::nothrow; + + #if __BYTE_ORDER == __LITTLE_ENDIAN static inline diff --git a/src/system/boot/loader/net/UDP.cpp b/src/system/boot/loader/net/UDP.cpp index 205ddc61b8..10af060bc4 100644 --- a/src/system/boot/loader/net/UDP.cpp +++ b/src/system/boot/loader/net/UDP.cpp @@ -22,6 +22,9 @@ #endif +using std::nothrow; + + // #pragma mark - UDPPacket From b310316956e8984a7d03e072dc86aa06fc9863f1 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sat, 7 Nov 2015 18:07:16 +0100 Subject: [PATCH 099/370] Fix arm/arch_string.S for Clang --- .../libroot/posix/string/arch/arm/arch_string.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/system/libroot/posix/string/arch/arm/arch_string.S b/src/system/libroot/posix/string/arch/arm/arch_string.S index 5826ce9dea..7ff32e5ec1 100644 --- a/src/system/libroot/posix/string/arch/arm/arch_string.S +++ b/src/system/libroot/posix/string/arch/arm/arch_string.S @@ -115,16 +115,16 @@ FUNCTION(memcpy): msr CPSR_f, r12 // move into NZCV fields in CPSR // move as many bytes as necessary to get the dst aligned - ldrvsb r3, [r1], #1 // V set - ldrcsh r4, [r1], #2 // C set + ldrbvs r3, [r1], #1 // V set + ldrhcs r4, [r1], #2 // C set ldreq r5, [r1], #4 // Z set - strvsb r3, [r0], #1 - strcsh r4, [r0], #2 + strbvs r3, [r0], #1 + strhcs r4, [r0], #2 streq r5, [r0], #4 - ldmmiia r1!, {r3-r4} // N set - stmmiia r0!, {r3-r4} + ldmiami r1!, {r3-r4} // N set + stmiami r0!, {r3-r4} // fix the remaining len sub r2, r2, r12, lsr #28 From 71e03249928f4f6a69f42d080157c4ba1ba3389b Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sat, 7 Nov 2015 18:16:23 +0100 Subject: [PATCH 100/370] Move new / delete kernel_cpp.h -> kernel_cpp.cpp new and delete may not be defined as inline, as Clang loudly complains. The same is true for static. --- headers/private/kernel/util/kernel_cpp.h | 59 ------------------------ src/system/kernel/util/kernel_cpp.cpp | 57 +++++++++++++++++++++++ 2 files changed, 57 insertions(+), 59 deletions(-) diff --git a/headers/private/kernel/util/kernel_cpp.h b/headers/private/kernel/util/kernel_cpp.h index c5c5373f32..9c5ab9a11b 100644 --- a/headers/private/kernel/util/kernel_cpp.h +++ b/headers/private/kernel/util/kernel_cpp.h @@ -22,65 +22,6 @@ extern const nothrow_t std::nothrow; typedef struct {} mynothrow_t; extern const mynothrow_t mynothrow; - -inline void * -operator new(size_t size) throw (std::bad_alloc) -{ - // we don't actually throw any exceptions, but we have to - // keep the prototype as specified in , or else GCC 3 - // won't like us - return malloc(size); -} - - -inline void * -operator new[](size_t size) throw (std::bad_alloc) -{ - return malloc(size); -} - - -inline void * -operator new(size_t size, const std::nothrow_t &) throw () -{ - return malloc(size); -} - - -inline void * -operator new[](size_t size, const std::nothrow_t &) throw () -{ - return malloc(size); -} - - -inline void * -operator new(size_t size, const mynothrow_t &) throw () -{ - return malloc(size); -} - - -inline void * -operator new[](size_t size, const mynothrow_t &) throw () -{ - return malloc(size); -} - - -inline void -operator delete(void *ptr) throw () -{ - free(ptr); -} - - -inline void -operator delete[](void *ptr) throw () -{ - free(ptr); -} - #endif // #if _KERNEL_MODE #endif // __cplusplus diff --git a/src/system/kernel/util/kernel_cpp.cpp b/src/system/kernel/util/kernel_cpp.cpp index 52ee3e660b..0ad305a2bc 100644 --- a/src/system/kernel/util/kernel_cpp.cpp +++ b/src/system/kernel/util/kernel_cpp.cpp @@ -73,6 +73,63 @@ __cxa_finalize(void* dsoHandle) // full C++ support in the kernel #if (defined(_KERNEL_MODE) || defined(_LOADER_MODE)) +void * +operator new(size_t size) throw (std::bad_alloc) +{ + // we don't actually throw any exceptions, but we have to + // keep the prototype as specified in , or else GCC 3 + // won't like us + return malloc(size); +} + + +void * +operator new[](size_t size) throw (std::bad_alloc) +{ + return malloc(size); +} + + +void * +operator new(size_t size, const std::nothrow_t &) throw () +{ + return malloc(size); +} + + +void * +operator new[](size_t size, const std::nothrow_t &) throw () +{ + return malloc(size); +} + + +void * +operator new(size_t size, const mynothrow_t &) throw () +{ + return malloc(size); +} + + +void * +operator new[](size_t size, const mynothrow_t &) throw () +{ + return malloc(size); +} + + +void +operator delete(void *ptr) throw () +{ + free(ptr); +} + + +void +operator delete[](void *ptr) throw () +{ + free(ptr); +} #ifndef _BOOT_MODE From ed6dfed2a02cef245d8c8e5a3613ba71eecd8896 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sat, 7 Nov 2015 18:16:40 +0100 Subject: [PATCH 101/370] Fix a type mismatch for std::min() --- src/system/boot/loader/file_systems/fat/Stream.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/system/boot/loader/file_systems/fat/Stream.cpp b/src/system/boot/loader/file_systems/fat/Stream.cpp index 3ed255f656..c8fc4ada49 100644 --- a/src/system/boot/loader/file_systems/fat/Stream.cpp +++ b/src/system/boot/loader/file_systems/fat/Stream.cpp @@ -386,7 +386,8 @@ Stream::WriteAt(off_t pos, const void* _buffer, size_t* _length, size_t inBlockOffset = offset % fVolume.BlockSize(); // write - size_t toWrite = std::min(fVolume.BlockSize() - inBlockOffset, length); + size_t toWrite = std::min((size_t)fVolume.BlockSize() - inBlockOffset, + length); if (toWrite == (size_t)fVolume.BlockSize()) { // write the whole block ssize_t written = write_pos(fVolume.Device(), From 55de0addd599e2aae041c2b17236429a0dc469ef Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sat, 7 Nov 2015 18:29:50 +0100 Subject: [PATCH 102/370] arm/arch_string.S: Only use sane insns for Clang --- .../libroot/posix/string/arch/arm/arch_string.S | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/system/libroot/posix/string/arch/arm/arch_string.S b/src/system/libroot/posix/string/arch/arm/arch_string.S index 7ff32e5ec1..e5918f1c3d 100644 --- a/src/system/libroot/posix/string/arch/arm/arch_string.S +++ b/src/system/libroot/posix/string/arch/arm/arch_string.S @@ -115,6 +115,7 @@ FUNCTION(memcpy): msr CPSR_f, r12 // move into NZCV fields in CPSR // move as many bytes as necessary to get the dst aligned +#ifdef __clang__ ldrbvs r3, [r1], #1 // V set ldrhcs r4, [r1], #2 // C set ldreq r5, [r1], #4 // Z set @@ -125,6 +126,18 @@ FUNCTION(memcpy): ldmiami r1!, {r3-r4} // N set stmiami r0!, {r3-r4} +#else + ldrvsb r3, [r1], #1 // V set + ldrcsh r4, [r1], #2 // C set + ldreq r5, [r1], #4 // Z set + + strvsb r3, [r0], #1 + strcsh r4, [r0], #2 + streq r5, [r0], #4 + + ldmmiia r1!, {r3-r4} // N set + stmmiia r0!, {r3-r4} +#endif // fix the remaining len sub r2, r2, r12, lsr #28 From 96474f3de2fb00c55ab3f4352a5495c2d31273fe Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sat, 7 Nov 2015 18:30:07 +0100 Subject: [PATCH 103/370] Define __ARM_ARCH__=7 for RPi2 when using Clang --- build/jam/board/rpi2/BoardSetup | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/jam/board/rpi2/BoardSetup b/build/jam/board/rpi2/BoardSetup index e9c285af9f..990774c4d1 100644 --- a/build/jam/board/rpi2/BoardSetup +++ b/build/jam/board/rpi2/BoardSetup @@ -59,6 +59,9 @@ HAIKU_BOARD_SDIMAGE_SIZE = 128 ; # local flags = -march=armv7-a -mfloat-abi=hard ; +if $(HAIKU_CC_IS_CLANG_$(architecture)) = 1 { + flags += -D__ARM_ARCH__=7 ; +} HAIKU_ASFLAGS_$(HAIKU_PACKAGING_ARCH) += $(flags) ; HAIKU_CCFLAGS_$(HAIKU_PACKAGING_ARCH) += $(flags) ; From 9b1ce4307b2efe829348af98d7e164225157e57d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 7 Nov 2015 18:30:31 +0100 Subject: [PATCH 104/370] Added flag for the Breton language. Anyone wants to do the translation? BZH POWAH! --- data/artwork/icons/flags/BR Breton | Bin 0 -> 10463 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/artwork/icons/flags/BR Breton diff --git a/data/artwork/icons/flags/BR Breton b/data/artwork/icons/flags/BR Breton new file mode 100644 index 0000000000000000000000000000000000000000..a5b006c4777114a2f5422e256f79f9741ee199a0 GIT binary patch literal 10463 zcmeHNU1%Id9G}aXG>K7rVkqYw)!R%^udSt5-fcXN(C{3?Q8t~W_R}Ea%UFOm;-mn+|2)D z{xdtjng49&zek2f2M-S&+AWY0$SV!faJLXi$Xjc4K+1Lr(Iy55M~7(R^)2K&wi05C z$KT!}#0AJuppDNzcefBqCSV5LT1~f=m_yY1fLI( z6rCY{8U}B1`I+HiX@|Cc0pGFHCCF#L%-3ChDO)r!yFwUN(JUEavTT-YkX2m>{QxQ` zM^IMNKHW#!mFp-qmrkKv2+(Z*HE8NzarH?{doE48Z$Ykuo<&(jNqWJhuSi;sN;6Bs z?^r+}4K=~Q%Fi_4l;z5$l998G6C#lSavZZSy%LkTPMvrby!a!b46>&Rb=u>Q%0J)vj+kzTQy_@3RB2bCQVsTu4u}r zqiEI@J>u3$vrZk>Q^-*V=B#YhQbS8xq6JzaO<7Q`Xv(OgXx0@y;?_yCP94@$$ZL-* z^2(k{MDyA2!L3B~*`3g33i@pNT@CpTGGw| z=794Sy|?GG;R!i|FAVr)26ejF%s^nFk+GJd>(c&JGYCW?>{KfDbit^IZ7tCd_yS1b zPtFnw`ShFtmDCFZXZ>?3B2gy05wC)ZayD;=9tI?PQIwV?H*Lcm5T9Vv2jr|&XNG2GW>zZW*-5OAGkBSc zf?N;u)cWA_5H*%6srA7(o^I$eQ6{?)=g>4tFYlriUxm0=nP`FQg{w~O)8IOw4oAgz zv>^X>@VGsL>!}^|oyfGA#0q*WGjNb?`;hUrEc;A~_Ru@pNl$;97#q$UqCUql*?|AD z%a^-Cvy41wX!Ecq!AFrxmNqOL{kD}YRq|!4n6=GvNvtGyx8M8XGPZm;ot<0k>-yH= zL%s;1Suu~B1=F6^D!FXIkS2=RXX^>7`dmar-iMiuLWDcK z5hA-Fb3Aq!5fgj|!7w6L1O8c;?;}DCS0lpJ;_TUonCxrq{pjlSR}w21lOKvp59l!_ z-Y#hdOn$rc$DSAy-*YtyCg~WH=EB5Ux^Zwln7k43JoyBEcB9S{z7;k)PkJG%cb@P< zquzNk)qu~NA?mMnp73T#o+mi?b9U`PzyGPfE$UdKrvgW|m$-y~3uyz@6;+8OT@|5(|)o$}-pOdWbY zpWoZxe@_fbGl24$bZ;oL`JY@ydgVR~!rrF(Tw#gLH->S=3>~qF#iH*EPWimx`w_T9y!9-iKU_zA>KS zT&IL1U*AE-*hg*TD~UnXyMF0vz`xJs``0ggs`_yjClu-3z8ID`<6crtSayX^%bx3{ zmmpKKM?Lnz#F^s^24{npPE4GQ+S&8J?F!HKUC?E}NqiX=j3@Gv%9*7$FK)H*!u|P8Sh;wzPtY(&eRer$JD%^Vn Date: Sat, 7 Nov 2015 18:48:26 +0100 Subject: [PATCH 105/370] Add back declarations to kernel_cpp.h for GCC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Axel Dörfler --- headers/private/kernel/util/kernel_cpp.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/headers/private/kernel/util/kernel_cpp.h b/headers/private/kernel/util/kernel_cpp.h index 9c5ab9a11b..728f32e4af 100644 --- a/headers/private/kernel/util/kernel_cpp.h +++ b/headers/private/kernel/util/kernel_cpp.h @@ -22,6 +22,17 @@ extern const nothrow_t std::nothrow; typedef struct {} mynothrow_t; extern const mynothrow_t mynothrow; +#ifndef __clang__ +extern void* operator new(size_t size) throw (std::bad_alloc); +extern void* operator new[](size_t size) throw (std::bad_alloc); +extern void* operator new(size_t size, const std::nothrow_t &) throw (); +extern void* operator new[](size_t size, const std::nothrow_t &) throw (); +extern void* operator new(size_t size, const mynothrow_t &) throw (); +extern void* operator new[](size_t size, const mynothrow_t &) throw (); +extern void operator delete(void *ptr) throw (); +extern void operator delete[](void *ptr) throw (); +#endif + #endif // #if _KERNEL_MODE #endif // __cplusplus From d8c022250dcfaaf6cba80a709147f5d626108492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 7 Nov 2015 20:46:45 +0100 Subject: [PATCH 106/370] BMailAccountSettings: use BPathFinder. * This allows to put add-ons in non-packaged folders, too. * Also, Set{In|Out}boundAddOn() only ever looked in the system dir. --- headers/os/mail/MailSettings.h | 2 + src/kits/mail/MailSettings.cpp | 69 +++++++++++++++++++--------------- 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/headers/os/mail/MailSettings.h b/headers/os/mail/MailSettings.h index eac7c85d30..26b63366d7 100644 --- a/headers/os/mail/MailSettings.h +++ b/headers/os/mail/MailSettings.h @@ -171,6 +171,8 @@ public: private: status_t _CreateAccountFilePath(); + status_t _GetAddOnRef(const char* subPath, + const char* name, entry_ref& ref); private: status_t fStatus; diff --git a/src/kits/mail/MailSettings.cpp b/src/kits/mail/MailSettings.cpp index 98984203ad..52cabe4ff5 100644 --- a/src/kits/mail/MailSettings.cpp +++ b/src/kits/mail/MailSettings.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -431,23 +432,24 @@ BMailAddOnSettings::Load(const BMessage& message) return B_BAD_VALUE; BPath path(pathString); + if (!path.IsAbsolute()) { - directory_which which[] = { - B_USER_ADDONS_DIRECTORY, - B_SYSTEM_ADDONS_DIRECTORY - }; + BStringList paths; + BPathFinder().FindPaths(B_FIND_PATH_ADD_ONS_DIRECTORY, "mail_daemon", + paths); - for (size_t i = 0; i < sizeof(which) / sizeof(which[0]); i++) { - status_t status = find_directory(which[i], &path); - if (status != B_OK) - continue; + status_t status = B_ENTRY_NOT_FOUND; - path.Append("mail_daemon"); - path.Append(pathString); - - if (BEntry(path.Path()).Exists()) + for (int32 i = 0; i < paths.CountStrings(); i++) { + path.SetTo(paths.StringAt(i), pathString); + BEntry entry(path.Path()); + if (entry.Exists()) { + status = B_OK; break; + } } + if (status != B_OK) + return status; } status_t status = get_ref_for_path(path.Path(), &fRef); @@ -737,17 +739,11 @@ BMailAccountSettings::ReturnAddress() const bool BMailAccountSettings::SetInboundAddOn(const char* name) { - BPath path; - status_t status = find_directory(B_BEOS_ADDONS_DIRECTORY, &path); - if (status != B_OK) - return false; - path.Append("mail_daemon"); - path.Append("inbound_protocols"); - path.Append(name); entry_ref ref; - get_ref_for_path(path.Path(), &ref); - fInboundSettings.SetAddOnRef(ref); + if (_GetAddOnRef("mail_daemon/inbound_protocols", name, ref) != B_OK) + return false; + fInboundSettings.SetAddOnRef(ref); return true; } @@ -755,17 +751,11 @@ BMailAccountSettings::SetInboundAddOn(const char* name) bool BMailAccountSettings::SetOutboundAddOn(const char* name) { - BPath path; - status_t status = find_directory(B_BEOS_ADDONS_DIRECTORY, &path); - if (status != B_OK) - return false; - path.Append("mail_daemon"); - path.Append("outbound_protocols"); - path.Append(name); entry_ref ref; - get_ref_for_path(path.Path(), &ref); - fOutboundSettings.SetAddOnRef(ref); + if (_GetAddOnRef("mail_daemon/outbound_protocols", name, ref) != B_OK) + return false; + fOutboundSettings.SetAddOnRef(ref); return true; } @@ -980,3 +970,22 @@ BMailAccountSettings::_CreateAccountFilePath() path.Append(fileName); return fAccountFile.SetTo(path.Path()); } + + +status_t +BMailAccountSettings::_GetAddOnRef(const char* subPath, const char* name, + entry_ref& ref) +{ + BStringList paths; + BPathFinder().FindPaths(B_FIND_PATH_ADD_ONS_DIRECTORY, subPath, paths); + + for (int32 i = 0; i < paths.CountStrings(); i++) { + BPath path(paths.StringAt(i), name); + BEntry entry(path.Path()); + if (entry.Exists()) { + if (entry.GetRef(&ref) == B_OK) + return B_OK; + } + } + return B_ENTRY_NOT_FOUND; +} From de0e15ae8c1b2bab0c2217fd7a91b26dc6111761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 7 Nov 2015 21:21:51 +0100 Subject: [PATCH 107/370] launch_daemon: corrected print server signature. * Not sure yet why it actually worked before; must be some other bug :-) --- data/launch/system | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/launch/system b/data/launch/system index 0b762be16e..b519e40b35 100644 --- a/data/launch/system +++ b/data/launch/system @@ -49,7 +49,7 @@ service x-vnd.Haiku-net_server { legacy } -service x-vnd.Haiku-print_server { +service x-vnd.Be-PSRV { launch /system/servers/print_server no_safemode on_demand From 5860caae390c582f58302519106bbc3e68cbd51d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 7 Nov 2015 21:42:45 +0100 Subject: [PATCH 108/370] launch_daemon: Added basic ability to stop/start jobs via API. * Stopping a job is very simplistic right now, and will have to be extended considerably, probably with its own job. --- headers/private/app/LaunchDaemonDefs.h | 2 + headers/private/app/LaunchRoster.h | 6 ++ src/kits/app/LaunchRoster.cpp | 113 +++++++++++++------------ src/servers/launch/Job.cpp | 28 +++++- src/servers/launch/Job.h | 2 + src/servers/launch/LaunchDaemon.cpp | 101 +++++++++++++++++++++- 6 files changed, 194 insertions(+), 58 deletions(-) diff --git a/headers/private/app/LaunchDaemonDefs.h b/headers/private/app/LaunchDaemonDefs.h index ba791aa7ab..e3e1a5e515 100644 --- a/headers/private/app/LaunchDaemonDefs.h +++ b/headers/private/app/LaunchDaemonDefs.h @@ -26,6 +26,8 @@ namespace BPrivate { enum { B_GET_LAUNCH_DATA = 'lnda', B_LAUNCH_TARGET = 'lntg', + B_LAUNCH_JOB = 'lnjo', + B_STOP_LAUNCH_JOB = 'lnsj', B_LAUNCH_SESSION = 'lnse', B_REGISTER_SESSION_DAEMON = 'lnrs', B_REGISTER_LAUNCH_EVENT = 'lnre', diff --git a/headers/private/app/LaunchRoster.h b/headers/private/app/LaunchRoster.h index 785fe0a846..46332de246 100644 --- a/headers/private/app/LaunchRoster.h +++ b/headers/private/app/LaunchRoster.h @@ -34,6 +34,9 @@ public: const BMessage* data = NULL, const char* baseName = NULL); + status_t Start(const char* name); + status_t Stop(const char* name, bool force = false); + status_t StartSession(const char* login); status_t RegisterEvent(const BMessenger& source, @@ -56,6 +59,9 @@ private: friend class Private; void _InitMessenger(); + status_t _SendRequest(BMessage& request); + status_t _SendRequest(BMessage& request, + BMessage& reply); status_t _UpdateEvent(uint32 what, const BMessenger& source, const char* name, uint32 flags = 0); diff --git a/src/kits/app/LaunchRoster.cpp b/src/kits/app/LaunchRoster.cpp index 1290b28190..b990d0ed08 100644 --- a/src/kits/app/LaunchRoster.cpp +++ b/src/kits/app/LaunchRoster.cpp @@ -102,14 +102,7 @@ BLaunchRoster::GetData(const char* signature, BMessage& data) if (status != B_OK) return status; - // send the request - status = fMessenger.SendMessage(&request, &data); - - // evaluate the reply - if (status == B_OK) - status = data.what; - - return status; + return _SendRequest(request, data); } @@ -169,15 +162,43 @@ BLaunchRoster::Target(const char* name, const BMessage* data, if (status != B_OK) return status; - // send the request - BMessage result; - status = fMessenger.SendMessage(&request, &result); + return _SendRequest(request); +} - // evaluate the reply + +status_t +BLaunchRoster::Start(const char* name) +{ + if (name == NULL) + return B_BAD_VALUE; + + BMessage request(B_LAUNCH_JOB); + status_t status = request.AddInt32("user", getuid()); if (status == B_OK) - status = result.what; + status = request.AddString("name", name); + if (status != B_OK) + return status; - return status; + return _SendRequest(request); +} + + +status_t +BLaunchRoster::Stop(const char* name, bool force) +{ + if (name == NULL) + return B_BAD_VALUE; + + BMessage request(B_STOP_LAUNCH_JOB); + status_t status = request.AddInt32("user", getuid()); + if (status == B_OK) + status = request.AddString("name", name); + if (status == B_OK) + status = request.AddBool("force", force); + if (status != B_OK) + return status; + + return _SendRequest(request); } @@ -194,15 +215,7 @@ BLaunchRoster::StartSession(const char* login) if (status != B_OK) return status; - // send the request - BMessage result; - status = fMessenger.SendMessage(&request, &result); - - // evaluate the reply - if (status == B_OK) - status = result.what; - - return status; + return _SendRequest(request); } @@ -245,12 +258,7 @@ BLaunchRoster::GetTargets(BStringList& targets) // send the request BMessage result; - status = fMessenger.SendMessage(&request, &result); - - // evaluate the reply - if (status == B_OK) - status = result.what; - + status = _SendRequest(request, result); if (status == B_OK) status = result.FindStrings("target", &targets); @@ -277,12 +285,7 @@ BLaunchRoster::GetJobs(const char* target, BStringList& jobs) // send the request BMessage result; - status = fMessenger.SendMessage(&request, &result); - - // evaluate the reply - if (status == B_OK) - status = result.what; - + status = _SendRequest(request, result); if (status == B_OK) status = result.FindStrings("job", &jobs); @@ -310,6 +313,26 @@ BLaunchRoster::_InitMessenger() } +status_t +BLaunchRoster::_SendRequest(BMessage& request) +{ + BMessage result; + return _SendRequest(request, result); +} + + +status_t +BLaunchRoster::_SendRequest(BMessage& request, BMessage& result) +{ + // Send the request, and evaluate the reply + status_t status = fMessenger.SendMessage(&request, &result); + if (status == B_OK) + status = result.what; + + return status; +} + + status_t BLaunchRoster::_UpdateEvent(uint32 what, const BMessenger& source, const char* name, uint32 flags) @@ -330,15 +353,7 @@ BLaunchRoster::_UpdateEvent(uint32 what, const BMessenger& source, if (status != B_OK) return status; - // send the request - BMessage result; - status = fMessenger.SendMessage(&request, &result); - - // evaluate the reply - if (status == B_OK) - status = result.what; - - return status; + return _SendRequest(request); } @@ -355,13 +370,5 @@ BLaunchRoster::_GetInfo(uint32 what, const char* name, BMessage& info) if (status != B_OK) return status; - // send the request - BMessage result; - status = fMessenger.SendMessage(&request, &info); - - // evaluate the reply - if (status == B_OK) - status = result.what; - - return status; + return _SendRequest(request, info); } diff --git a/src/servers/launch/Job.cpp b/src/servers/launch/Job.cpp index 5cdeeab428..2c5ad6f3fa 100644 --- a/src/servers/launch/Job.cpp +++ b/src/servers/launch/Job.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -43,6 +44,7 @@ Job::Job(const Job& other) fEnabled(other.IsEnabled()), fService(other.IsService()), fCreateDefaultPort(other.CreateDefaultPort()), + fLaunching(other.IsLaunching()), fInitStatus(B_NO_INIT), fTeam(-1), fLaunchStatus(B_NO_INIT), @@ -380,7 +382,7 @@ bool Job::CanBeLaunched() const { // Services cannot be launched while they are running - return !IsLaunching() && (!IsService() || !IsRunning()); + return IsEnabled() && !IsLaunching() && (!IsService() || !IsRunning()); } @@ -409,6 +411,30 @@ Job::HandleGetLaunchData(BMessage* message) } +status_t +Job::GetMessenger(BMessenger& messenger) +{ + PortMap::const_iterator iterator = fPortMap.begin(); + for (; iterator != fPortMap.end(); iterator++) { + if (iterator->second.HasString("name")) + continue; + + port_id port = (port_id)iterator->second.GetInt32("port", -1); + if (port >= 0) { + BMessenger::Private(messenger).SetTo(fTeam, port, + B_PREFERRED_TOKEN); + return B_OK; + } + } + + // There is no default port, try roster via signature + BString signature = "application/"; + signature << Name(); + + return messenger.SetTo(signature); +} + + status_t Job::Run() { diff --git a/src/servers/launch/Job.h b/src/servers/launch/Job.h index b18dbd1099..3995cf2848 100644 --- a/src/servers/launch/Job.h +++ b/src/servers/launch/Job.h @@ -20,6 +20,7 @@ using namespace BSupportKit; class BMessage; +class BMessenger; class Finder; class Job; @@ -90,6 +91,7 @@ public: void SetLaunching(bool launching); status_t HandleGetLaunchData(BMessage* message); + status_t GetMessenger(BMessenger& messenger); virtual status_t Run(); diff --git a/src/servers/launch/LaunchDaemon.cpp b/src/servers/launch/LaunchDaemon.cpp index 3ac3c62713..d7e5cc10f8 100644 --- a/src/servers/launch/LaunchDaemon.cpp +++ b/src/servers/launch/LaunchDaemon.cpp @@ -153,6 +153,8 @@ public: private: void _HandleGetLaunchData(BMessage* message); void _HandleLaunchTarget(BMessage* message); + void _HandleLaunchJob(BMessage* message); + void _HandleStopLaunchJob(BMessage* message); void _HandleLaunchSession(BMessage* message); void _HandleRegisterSessionDaemon(BMessage* message); void _HandleRegisterLaunchEvent(BMessage* message); @@ -179,6 +181,7 @@ private: void _LaunchJobs(Target* target, bool forceNow = false); void _LaunchJob(Job* job, uint32 options = 0); + void _StopJob(Job* job, bool force); void _AddTarget(Target* target); void _SetCondition(BaseJob* job, const BMessage& message); @@ -501,11 +504,16 @@ LaunchDaemon::MessageReceived(BMessage* message) case B_LAUNCH_TARGET: _HandleLaunchTarget(message); break; + case B_LAUNCH_JOB: + _HandleLaunchJob(message); + break; + case B_STOP_LAUNCH_JOB: + _HandleStopLaunchJob(message); + break; case B_LAUNCH_SESSION: _HandleLaunchSession(message); break; - case B_REGISTER_SESSION_DAEMON: _HandleRegisterSessionDaemon(message); break; @@ -513,15 +521,12 @@ LaunchDaemon::MessageReceived(BMessage* message) case B_REGISTER_LAUNCH_EVENT: _HandleRegisterLaunchEvent(message); break; - case B_UNREGISTER_LAUNCH_EVENT: _HandleUnregisterLaunchEvent(message); break; - case B_NOTIFY_LAUNCH_EVENT: _HandleNotifyLaunchEvent(message); break; - case B_RESET_STICKY_LAUNCH_EVENT: _HandleResetStickyLaunchEvent(message); break; @@ -787,6 +792,67 @@ LaunchDaemon::_HandleLaunchTarget(BMessage* message) } +void +LaunchDaemon::_HandleLaunchJob(BMessage* message) +{ + uid_t user = _GetUserID(message); + if (user < 0) + return; + + const char* name = message->GetString("name"); + + Job* job = FindJob(name); + if (job == NULL) { + Session* session = FindSession(user); + if (session != NULL) { + // Forward request to user launch_daemon + if (session->Daemon().SendMessage(message) == B_OK) + return; + } + + BMessage reply(B_NAME_NOT_FOUND); + message->SendReply(&reply); + return; + } + + job->SetEnabled(true); + _LaunchJob(job, FORCE_NOW); + + BMessage reply((uint32)B_OK); + message->SendReply(&reply); +} + + +void +LaunchDaemon::_HandleStopLaunchJob(BMessage* message) +{ + uid_t user = _GetUserID(message); + if (user < 0) + return; + + const char* name = message->GetString("name"); + + Job* job = FindJob(name); + if (job == NULL) { + Session* session = FindSession(user); + if (session != NULL) { + // Forward request to user launch_daemon + if (session->Daemon().SendMessage(message) == B_OK) + return; + } + + BMessage reply(B_NAME_NOT_FOUND); + message->SendReply(&reply); + return; + } + + _StopJob(job, message->GetBool("force")); + + BMessage reply((uint32)B_OK); + message->SendReply(&reply); +} + + void LaunchDaemon::_HandleLaunchSession(BMessage* message) { @@ -1315,6 +1381,33 @@ LaunchDaemon::_LaunchJob(Job* job, uint32 options) } +void +LaunchDaemon::_StopJob(Job* job, bool force) +{ + // TODO: find out which jobs require this job, and don't stop if any, + // unless force, and then stop them all. + job->SetEnabled(false); + + if (!job->IsRunning()) + return; + + // Be nice first, and send a simple quit message + BMessenger messenger; + if (job->GetMessenger(messenger) == B_OK) { + BMessage request(B_QUIT_REQUESTED); + messenger.SendMessage(&request); + + // TODO: wait a bit before going further + return; + } + // TODO: allow custom shutdown + + send_signal(-job->Team(), SIGINT); + // TODO: this would be the next step, again, after a delay + //send_signal(job->Team(), SIGKILL); +} + + void LaunchDaemon::_AddTarget(Target* target) { From 64df3e0483e2104e15327ea81ee61db2455af7dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 7 Nov 2015 21:44:51 +0100 Subject: [PATCH 109/370] launch_daemon: Added forgotten time update/dstcheck. --- data/launch/user | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/data/launch/user b/data/launch/user index c53d9a5074..f400dd30ef 100644 --- a/data/launch/user +++ b/data/launch/user @@ -27,6 +27,14 @@ target desktop { launch /bin/sh ~/config/settings/boot/UserBootscript } + job check-daylight-saving-time { + launch /system/bin/dstcheck + } + + job update-time { + launch /system/preferences/Time "" --update + } + job first-login { launch /bin/sh /system/boot/PostInstallScript "first login" ~/config/settings/first_login /boot/system/boot/first-login if file_exists ~/config/settings/first_login From 456150599a71ef4f6c5036724683092b22c18937 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sat, 7 Nov 2015 23:02:53 +0100 Subject: [PATCH 110/370] Add __clang__ to a few #ifdefs --- headers/os/support/SupportDefs.h | 2 +- src/build/libroot/atomic.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/headers/os/support/SupportDefs.h b/headers/os/support/SupportDefs.h index e1512360cf..db1ce576f0 100644 --- a/headers/os/support/SupportDefs.h +++ b/headers/os/support/SupportDefs.h @@ -250,7 +250,7 @@ extern void* get_stack_frame(void); /* Use the built-in atomic functions, if requested and available. */ -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || defined(__clang__) static __inline__ void diff --git a/src/build/libroot/atomic.cpp b/src/build/libroot/atomic.cpp index 0e1fed4911..7520c35d27 100644 --- a/src/build/libroot/atomic.cpp +++ b/src/build/libroot/atomic.cpp @@ -6,7 +6,8 @@ #include -#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) +#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7)) \ + && !defined(__clang__) void From c7624537a33eae0db84de63842833e3c9c552869 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sat, 7 Nov 2015 23:11:14 +0100 Subject: [PATCH 111/370] ARM: Alias __aeabi_memcpy to memcpy --- src/system/libroot/posix/string/arch/arm/arch_string.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/system/libroot/posix/string/arch/arm/arch_string.S b/src/system/libroot/posix/string/arch/arm/arch_string.S index e5918f1c3d..5a4340c16e 100644 --- a/src/system/libroot/posix/string/arch/arm/arch_string.S +++ b/src/system/libroot/posix/string/arch/arm/arch_string.S @@ -11,6 +11,7 @@ .align 4 FUNCTION(memcpy): +FUNCTION(__aeabi_memcpy): // check for zero length copy or the same pointer cmp r2, #0 cmpne r1, r0 @@ -165,4 +166,5 @@ FUNCTION(memcpy): // check for zero length copy or the same pointer FUNCTION_END(memcpy) +FUNCTION_END(__aeabi_memcpy) #endif From f2f1efc509f4ab01409d26211e31fb8fe9e8ee52 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sun, 8 Nov 2015 00:04:16 +0100 Subject: [PATCH 112/370] Use -no-integrated-as to create asm struct offsets This depends on quite a nasty hack to generate those, namely using inline assembly to generate a file with things that are not actually assembly, which Clang therefore filters out. --- build/jam/MainBuildRules | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build/jam/MainBuildRules b/build/jam/MainBuildRules index a71a985616..75f35c9667 100644 --- a/build/jam/MainBuildRules +++ b/build/jam/MainBuildRules @@ -371,13 +371,17 @@ rule CreateAsmStructOffsetsHeader header : source [ FSysIncludes $(sysHeaders) : $(systemIncludesOption) ] ; CCDEFS on $(header) = [ FDefines $(defines) ] ; + if $(HAIKU_CC_IS_CLANG_$(architecture)) = 1 { + C++FLAGS on $(header) += -no-integrated-as ; + } + CreateAsmStructOffsetsHeader1 $(header) : $(source) ; } actions CreateAsmStructOffsetsHeader1 { $(C++) -S "$(2)" $(C++FLAGS) $(CCDEFS) $(CCHDRS) -o - \ - | grep "#define" | sed -e 's/[\$\#]\([0-9]\)/\1/' > "$(1)" + | grep "#define" | $(SED) -e 's/[\$\#]\([0-9]\)/\1/' > "$(1)" } rule MergeObjectFromObjects From b0ecbc13f071c9d47b7a112481fcc00312a18e8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 8 Nov 2015 00:05:16 +0100 Subject: [PATCH 113/370] launch_daemon: Refactored some message handlers, more info. * The info getters will now add a lot more info. --- src/servers/launch/LaunchDaemon.cpp | 295 ++++++++++++++++------------ 1 file changed, 169 insertions(+), 126 deletions(-) diff --git a/src/servers/launch/LaunchDaemon.cpp b/src/servers/launch/LaunchDaemon.cpp index d7e5cc10f8..e18d165de9 100644 --- a/src/servers/launch/LaunchDaemon.cpp +++ b/src/servers/launch/LaunchDaemon.cpp @@ -162,6 +162,10 @@ private: void _HandleNotifyLaunchEvent(BMessage* message); void _HandleResetStickyLaunchEvent( BMessage* message); + void _HandleGetLaunchTargets(BMessage* message); + void _HandleGetLaunchTargetInfo(BMessage* message); + void _HandleGetLaunchJobs(BMessage* message); + void _HandleGetLaunchJobInfo(BMessage* message); uid_t _GetUserID(BMessage* message); void _ReadPaths(const BStringList& paths); @@ -197,8 +201,7 @@ private: ExternalEventSource* event, const BString& name); void _ResolveExternalEvents(BaseJob* job); - void _GetTargetInfo(Target* target, BMessage& info); - void _GetJobInfo(Job* job, BMessage& info); + void _GetBaseJobInfo(BaseJob* job, BMessage& info); void _ForwardEventMessage(uid_t user, BMessage* message); @@ -532,123 +535,17 @@ LaunchDaemon::MessageReceived(BMessage* message) break; case B_GET_LAUNCH_TARGETS: - { - uid_t user = _GetUserID(message); - if (user < 0) - return; - - BMessage reply; - status_t status = B_OK; - - if (!fUserMode) { - // Request the data from the user's daemon, too - Session* session = FindSession(user); - if (session != NULL) { - BMessage request(B_GET_LAUNCH_TARGETS); - status = request.AddInt32("user", 0); - if (status == B_OK) { - status = session->Daemon().SendMessage(&request, - &reply); - } - if (status == B_OK) - status = reply.what; - } else - status = B_NAME_NOT_FOUND; - } - - if (status == B_OK) { - TargetMap::const_iterator iterator = fTargets.begin(); - for (; iterator != fTargets.end(); iterator++) - reply.AddString("target", iterator->first); - } - - reply.what = status; - message->SendReply(&reply); + _HandleGetLaunchTargets(message); break; - } case B_GET_LAUNCH_TARGET_INFO: - { - uid_t user = _GetUserID(message); - if (user < 0) - return; - - const char* name = message->GetString("name"); - Target* target = FindTarget(name); - if (target == NULL && !fUserMode) { - _ForwardEventMessage(user, message); - break; - } - - BMessage reply(uint32(target != NULL ? B_OK : B_NAME_NOT_FOUND)); - if (target != NULL) - _GetTargetInfo(target, reply); - message->SendReply(&reply); + _HandleGetLaunchTargetInfo(message); break; - } case B_GET_LAUNCH_JOBS: - { - uid_t user = _GetUserID(message); - if (user < 0) - return; - - const char* targetName = message->GetString("target"); - - BMessage reply; - status_t status = B_OK; - - if (!fUserMode) { - // Request the data from the user's daemon, too - Session* session = FindSession(user); - if (session != NULL) { - BMessage request(B_GET_LAUNCH_JOBS); - status = request.AddInt32("user", 0); - if (status == B_OK && targetName != NULL) - status = request.AddString("target", targetName); - if (status == B_OK) { - status = session->Daemon().SendMessage(&request, - &reply); - } - if (status == B_OK) - status = reply.what; - } else - status = B_NAME_NOT_FOUND; - } - - if (status == B_OK) { - JobMap::const_iterator iterator = fJobs.begin(); - for (; iterator != fJobs.end(); iterator++) { - Job* job = iterator->second; - if (targetName != NULL && (job->Target() == NULL - || job->Target()->Title() != targetName)) { - continue; - } - reply.AddString("job", iterator->first); - } - } - - reply.what = status; - message->SendReply(&reply); + _HandleGetLaunchJobs(message); break; - } case B_GET_LAUNCH_JOB_INFO: - { - uid_t user = _GetUserID(message); - if (user < 0) - return; - - const char* name = message->GetString("name"); - Job* job = FindJob(name); - if (job == NULL && !fUserMode) { - _ForwardEventMessage(user, message); - break; - } - - BMessage reply(uint32(job != NULL ? B_OK : B_NAME_NOT_FOUND)); - if (job != NULL) - _GetJobInfo(job, reply); - message->SendReply(&reply); + _HandleGetLaunchJobInfo(message); break; - } case kMsgEventTriggered: { @@ -1038,6 +935,160 @@ LaunchDaemon::_HandleResetStickyLaunchEvent(BMessage* message) } +void +LaunchDaemon::_HandleGetLaunchTargets(BMessage* message) +{ + uid_t user = _GetUserID(message); + if (user < 0) + return; + + BMessage reply; + status_t status = B_OK; + + if (!fUserMode) { + // Request the data from the user's daemon, too + Session* session = FindSession(user); + if (session != NULL) { + BMessage request(B_GET_LAUNCH_TARGETS); + status = request.AddInt32("user", 0); + if (status == B_OK) { + status = session->Daemon().SendMessage(&request, + &reply); + } + if (status == B_OK) + status = reply.what; + } else + status = B_NAME_NOT_FOUND; + } + + if (status == B_OK) { + TargetMap::const_iterator iterator = fTargets.begin(); + for (; iterator != fTargets.end(); iterator++) + reply.AddString("target", iterator->first); + } + + reply.what = status; + message->SendReply(&reply); +} + + +void +LaunchDaemon::_HandleGetLaunchTargetInfo(BMessage* message) +{ + uid_t user = _GetUserID(message); + if (user < 0) + return; + + const char* name = message->GetString("name"); + Target* target = FindTarget(name); + if (target == NULL && !fUserMode) { + _ForwardEventMessage(user, message); + return; + } + + BMessage info(uint32(target != NULL ? B_OK : B_NAME_NOT_FOUND)); + if (target != NULL) { + _GetBaseJobInfo(target, info); + + for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end(); + iterator++) { + Job* job = iterator->second; + if (job->Target() == target) + info.AddString("job", job->Name()); + } + } + message->SendReply(&info); +} + + +void +LaunchDaemon::_HandleGetLaunchJobs(BMessage* message) +{ + uid_t user = _GetUserID(message); + if (user < 0) + return; + + const char* targetName = message->GetString("target"); + + BMessage reply; + status_t status = B_OK; + + if (!fUserMode) { + // Request the data from the user's daemon, too + Session* session = FindSession(user); + if (session != NULL) { + BMessage request(B_GET_LAUNCH_JOBS); + status = request.AddInt32("user", 0); + if (status == B_OK && targetName != NULL) + status = request.AddString("target", targetName); + if (status == B_OK) { + status = session->Daemon().SendMessage(&request, + &reply); + } + if (status == B_OK) + status = reply.what; + } else + status = B_NAME_NOT_FOUND; + } + + if (status == B_OK) { + JobMap::const_iterator iterator = fJobs.begin(); + for (; iterator != fJobs.end(); iterator++) { + Job* job = iterator->second; + if (targetName != NULL && (job->Target() == NULL + || job->Target()->Title() != targetName)) { + continue; + } + reply.AddString("job", iterator->first); + } + } + + reply.what = status; + message->SendReply(&reply); +} + + +void +LaunchDaemon::_HandleGetLaunchJobInfo(BMessage* message) +{ + uid_t user = _GetUserID(message); + if (user < 0) + return; + + const char* name = message->GetString("name"); + Job* job = FindJob(name); + if (job == NULL && !fUserMode) { + _ForwardEventMessage(user, message); + return; + } + + BMessage info(uint32(job != NULL ? B_OK : B_NAME_NOT_FOUND)); + if (job != NULL) { + _GetBaseJobInfo(job, info); + + info.SetInt32("team", job->Team()); + info.SetBool("enabled", job->IsEnabled()); + info.SetBool("running", job->IsRunning()); + info.SetBool("launched", job->IsLaunched()); + info.SetBool("service", job->IsService()); + + if (job->Target() != NULL) + info.SetString("target", job->Target()->Name()); + + for (int32 i = 0; i < job->Arguments().CountStrings(); i++) + info.AddString("launch", job->Arguments().StringAt(i)); + + for (int32 i = 0; i < job->Requirements().CountStrings(); i++) + info.AddString("requires", job->Requirements().StringAt(i)); + + PortMap::const_iterator iterator = job->Ports().begin(); + for (; iterator != job->Ports().end(); iterator++) + info.AddMessage("port", &iterator->second); + } + message->SendReply(&info); +} + + uid_t LaunchDaemon::_GetUserID(BMessage* message) { @@ -1528,23 +1579,15 @@ LaunchDaemon::_ResolveExternalEvents(BaseJob* job) void -LaunchDaemon::_GetTargetInfo(Target* target, BMessage& info) -{ - info.SetString("name", target->Name()); -} - - -void -LaunchDaemon::_GetJobInfo(Job* job, BMessage& info) +LaunchDaemon::_GetBaseJobInfo(BaseJob* job, BMessage& info) { info.SetString("name", job->Name()); - info.SetInt32("team", job->Team()); - info.SetBool("running", job->IsRunning()); - info.SetBool("launched", job->IsLaunched()); - PortMap::const_iterator iterator = job->Ports().begin(); - for (; iterator != job->Ports().end(); iterator++) - info.AddMessage("port", &iterator->second); + if (job->Event() != NULL) + info.SetString("event", job->Event()->ToString()); + + if (job->Condition() != NULL) + info.SetString("condition", job->Condition()->ToString()); } From 74068663408da669701309728e1ab8ce6b0aead2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 8 Nov 2015 00:06:15 +0100 Subject: [PATCH 114/370] launch_roster: The beginnings of a launch_daemon control tool. --- build/jam/images/definitions/minimum | 2 +- src/bin/Jamfile | 1 + src/bin/launch_roster.cpp | 182 +++++++++++++++++++++++++++ 3 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 src/bin/launch_roster.cpp diff --git a/build/jam/images/definitions/minimum b/build/jam/images/definitions/minimum index 6321369a2e..eba4c4f797 100644 --- a/build/jam/images/definitions/minimum +++ b/build/jam/images/definitions/minimum @@ -13,7 +13,7 @@ SYSTEM_BIN = [ FFilterByBuildFeatures hd hey ideinfo@ide idestatus@ide ifconfig iroster isvolume kernel_debugger keymap keystore - linkcatkeys listarea listattr listimage listdev + launch_roster linkcatkeys listarea listattr listimage listdev listport listres listsem listusb locale logger login lsindex makebootable message mimeset mkfs mkindex modifiers mount mountvolume diff --git a/src/bin/Jamfile b/src/bin/Jamfile index f0fa7edf65..6aae7b68d0 100644 --- a/src/bin/Jamfile +++ b/src/bin/Jamfile @@ -89,6 +89,7 @@ StdBinCommands draggers.cpp ffm.cpp iroster.cpp + launch_roster.cpp listattr.cpp listfont.cpp listres.cpp diff --git a/src/bin/launch_roster.cpp b/src/bin/launch_roster.cpp new file mode 100644 index 0000000000..f66a6f1e6b --- /dev/null +++ b/src/bin/launch_roster.cpp @@ -0,0 +1,182 @@ +/* + * Copyright 2015, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ + + +/*! The launch_daemon's companion command line tool. */ + + +#include +#include + +#include +#include +#include +#include +#include + + +static struct option const kLongOptions[] = { + {"verbose", no_argument, 0, 'v'}, + {"help", no_argument, 0, 'h'}, + {NULL} +}; + +extern const char *__progname; +static const char *kProgramName = __progname; + + +static void +list_jobs(bool verbose) +{ + BLaunchRoster roster; + BStringList jobs; + status_t status = roster.GetJobs(NULL, jobs); + if (status != B_OK) { + fprintf(stderr, "%s: Could not get job listing: %s\n", kProgramName, + strerror(status)); + exit(EXIT_FAILURE); + } + + for (int32 i = 0; i < jobs.CountStrings(); i++) + puts(jobs.StringAt(i).String()); +} + + +static void +list_targets(bool verbose) +{ + BLaunchRoster roster; + BStringList targets; + status_t status = roster.GetTargets(targets); + if (status != B_OK) { + fprintf(stderr, "%s: Could not get target listing: %s\n", kProgramName, + strerror(status)); + exit(EXIT_FAILURE); + } + + for (int32 i = 0; i < targets.CountStrings(); i++) + puts(targets.StringAt(i).String()); +} + + +static void +get_info(const char* name) +{ + BLaunchRoster roster; + BMessage info; + status_t targetStatus = roster.GetTargetInfo(name, info); + if (targetStatus == B_OK) { + printf("Target: %s\n", name); + info.PrintToStream(); + } + + info.MakeEmpty(); + status_t jobStatus = roster.GetJobInfo(name, info); + if (jobStatus == B_OK) { + printf("Job: %s\n", name); + info.PrintToStream(); + } + + if (jobStatus != B_OK && targetStatus != B_OK) { + fprintf(stderr, "%s: Could not get target or job info for \"%s\": " + "%s\n", kProgramName, name, strerror(jobStatus)); + exit(EXIT_FAILURE); + } +} + + +static void +start_job(const char* name) +{ + BLaunchRoster roster; + status_t status = roster.Start(name); + if (status != B_OK) { + fprintf(stderr, "%s: Starting job \"%s\" failed: %s\n", kProgramName, + name, strerror(status)); + exit(EXIT_FAILURE); + } +} + + +static void +stop_job(const char* name) +{ + BLaunchRoster roster; + status_t status = roster.Stop(name); + if (status != B_OK) { + fprintf(stderr, "%s: Stopping job \"%s\" failed: %s\n", kProgramName, + name, strerror(status)); + exit(EXIT_FAILURE); + } +} + + +static void +usage(int status) +{ + fprintf(stderr, "Usage: %s \n" + "Where is one of:\n" + " list - Lists all jobs (the default command)\n" + " list-targets - Lists all targets\n" + "The following s have a argument:\n" + " start - Starts a job\n" + " stop - Stops a running job\n" + " info - Shows info for a job/target\n", + kProgramName); + + exit(status); +} + + +int +main(int argc, char** argv) +{ + const char* command = "list"; + bool verbose = false; + + int c; + while ((c = getopt_long(argc, argv, "hv", kLongOptions, NULL)) != -1) { + switch (c) { + case 0: + break; + case 'h': + usage(0); + break; + case 'v': + verbose = true; + break; + default: + usage(1); + break; + } + } + + if (argc - optind >= 1) + command = argv[optind]; + + if (strcmp(command, "list") == 0) { + list_jobs(verbose); + } else if (strcmp(command, "list-targets") == 0) { + list_targets(verbose); + } else { + // All commands that need a name following + if (argc == optind + 1) + usage(1); + + const char* name = argv[argc - 1]; + + if (strcmp(command, "info") == 0) { + get_info(name); + } else if (strcmp(command, "start") == 0) { + start_job(name); + } else if (strcmp(command, "stop") == 0) { + stop_job(name); + } else { + fprintf(stderr, "%s: Unknown command \"%s\".\n", kProgramName, + command); + } + } + return 0; +} From f10b49ed414c698ce4637231073fc76cba141398 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sun, 8 Nov 2015 00:37:13 +0100 Subject: [PATCH 115/370] Fixup for my last commit (better check for Clang) --- build/jam/MainBuildRules | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build/jam/MainBuildRules b/build/jam/MainBuildRules index 75f35c9667..0e526a1f68 100644 --- a/build/jam/MainBuildRules +++ b/build/jam/MainBuildRules @@ -353,6 +353,10 @@ rule CreateAsmStructOffsetsHeader header : source flags += -Wno-invalid-offsetof ; # TODO: Rather get rid of the respective offsetof() instances. + if $(HAIKU_CC_IS_CLANG_$(TARGET_PACKAGING_ARCH)) = 1 { + flags += -no-integrated-as ; + } + # locate object, search for source, and set on target variables Depends $(header) : $(source) $(PLATFORM) ; @@ -371,10 +375,6 @@ rule CreateAsmStructOffsetsHeader header : source [ FSysIncludes $(sysHeaders) : $(systemIncludesOption) ] ; CCDEFS on $(header) = [ FDefines $(defines) ] ; - if $(HAIKU_CC_IS_CLANG_$(architecture)) = 1 { - C++FLAGS on $(header) += -no-integrated-as ; - } - CreateAsmStructOffsetsHeader1 $(header) : $(source) ; } From b49dd60c46d920e6eca1f38e71ae386736e6abc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sat, 7 Nov 2015 23:58:33 +0100 Subject: [PATCH 116/370] Drop namespace std after 95d4ed6778c138150a29. --- src/system/boot/loader/file_systems/fat/Directory.cpp | 2 +- src/system/boot/loader/file_systems/tarfs/tarfs.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/system/boot/loader/file_systems/fat/Directory.cpp b/src/system/boot/loader/file_systems/fat/Directory.cpp index 559dae6d68..8aa1e9f440 100644 --- a/src/system/boot/loader/file_systems/fat/Directory.cpp +++ b/src/system/boot/loader/file_systems/fat/Directory.cpp @@ -514,7 +514,7 @@ Directory::CreateFile(const char* name, mode_t permissions, Node** _node) return error; // create a File object - File* file = new(std::nothrow) File(fVolume, entryOffset, + File* file = new(nothrow) File(fVolume, entryOffset, entry.Cluster(fVolume.FatBits()), entry.Size(), name); if (file == NULL) return B_NO_MEMORY; diff --git a/src/system/boot/loader/file_systems/tarfs/tarfs.cpp b/src/system/boot/loader/file_systems/tarfs/tarfs.cpp index 83e29e3b9f..552d8003b6 100644 --- a/src/system/boot/loader/file_systems/tarfs/tarfs.cpp +++ b/src/system/boot/loader/file_systems/tarfs/tarfs.cpp @@ -358,7 +358,7 @@ TarFS::Directory::Open(void** _cookie, int mode) _inherited::Open(_cookie, mode); EntryIterator* iterator - = new(std::nothrow) EntryIterator(fEntries.GetIterator()); + = new(nothrow) EntryIterator(fEntries.GetIterator()); if (iterator == NULL) return B_NO_MEMORY; From 7ccbb2f03f42b701aaf8195ef4bcb0d912da009c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sun, 8 Nov 2015 00:01:03 +0100 Subject: [PATCH 117/370] Add operator delete(void *, size_t) for C++14. --- headers/private/kernel/util/kernel_cpp.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/headers/private/kernel/util/kernel_cpp.h b/headers/private/kernel/util/kernel_cpp.h index 728f32e4af..89ac147ecd 100644 --- a/headers/private/kernel/util/kernel_cpp.h +++ b/headers/private/kernel/util/kernel_cpp.h @@ -33,6 +33,16 @@ extern void operator delete(void *ptr) throw (); extern void operator delete[](void *ptr) throw (); #endif +#if __cplusplus >= 201402L + +inline void +operator delete(void *ptr, size_t size) throw () +{ + free(ptr); +} + +#endif // __cplusplus >= 201402L + #endif // #if _KERNEL_MODE #endif // __cplusplus From 6c4cca34c25eefded9a3899bdafeeb9d50666f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sun, 8 Nov 2015 00:33:00 +0100 Subject: [PATCH 118/370] glibc: replace extern __inline with __extern_always_inline for x86. * also update __atan2l for x86, update __FAST_MATH sections. --- .../glibc/include/arch/x86/bits/mathinline.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/system/libroot/posix/glibc/include/arch/x86/bits/mathinline.h b/src/system/libroot/posix/glibc/include/arch/x86/bits/mathinline.h index e8091df684..1288804503 100644 --- a/src/system/libroot/posix/glibc/include/arch/x86/bits/mathinline.h +++ b/src/system/libroot/posix/glibc/include/arch/x86/bits/mathinline.h @@ -22,10 +22,10 @@ # error "Never use directly; include instead." #endif -#ifdef __cplusplus +#ifndef __extern_always_inline # define __MATH_INLINE __inline #else -# define __MATH_INLINE extern __inline +# define __MATH_INLINE __extern_always_inline #endif @@ -416,14 +416,21 @@ __inline_mathcodeNP (tan, __x, \ #endif /* __FAST_MATH__ */ +# if __GNUC_PREREQ (3, 4) +__inline_mathcodeNP2_ (long double, __atan2l, __y, __x, + return __builtin_atan2l (__y, __x)) +# else #define __atan2_code \ register long double __value; \ __asm __volatile__ \ ("fpatan" \ : "=t" (__value) : "0" (__x), "u" (__y) : "st(1)"); \ return __value +# ifdef __FAST_MATH__ __inline_mathcodeNP2 (atan2, __y, __x, __atan2_code) +# endif __inline_mathcodeNP2_ (long double, __atan2l, __y, __x, __atan2_code) +# endif __inline_mathcodeNP2 (fmod, __x, __y, \ @@ -511,6 +518,7 @@ __inline_mathcodeNP (ceil, __x, \ __asm __volatile ("fldcw %0" : : "m" (__cw)); \ return __value) +#ifdef __FAST_MATH__ #define __ldexp_code \ register long double __value; \ __asm __volatile__ \ @@ -523,6 +531,7 @@ ldexp (double __x, int __y) __THROW { __ldexp_code; } +#endif /* Optimized versions for some non-standardized functions. */ @@ -530,7 +539,6 @@ ldexp (double __x, int __y) __THROW # ifdef __FAST_MATH__ __inline_mathcodeNP (expm1, __x, __expm1_code) -# endif /* We cannot rely on M_SQRT being defined. So we do it for ourself here. */ @@ -573,12 +581,12 @@ __inline_mathcodeNP(logb, __x, \ : "=t" (__junk), "=u" (__value) : "0" (__x)); \ return __value) +# endif #endif #ifdef __USE_ISOC99 #ifdef __FAST_MATH__ __inline_mathop_declNP (log2, "fld1; fxch; fyl2x", "0" (__x) : "st(1)") -#endif /* __FAST_MATH__ */ __MATH_INLINE float ldexpf (float __x, int __y) __THROW @@ -592,7 +600,6 @@ ldexpl (long double __x, int __y) __THROW __ldexp_code; } -#ifdef __FAST_MATH__ __inline_mathcodeNP3 (fma, __x, __y, __z, return (__x * __y) + __z) __inline_mathopNP (rint, "frndint") From d8548e00aa26aa576dd6986df0d19e942ebfaf8d Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sun, 8 Nov 2015 00:42:15 +0100 Subject: [PATCH 119/370] Fix some more type mismatches with std::{min,max} --- src/add-ons/kernel/bus_managers/ata/ATATracing.cpp | 2 +- src/add-ons/kernel/bus_managers/usb/Hub.cpp | 7 ++++--- src/system/kernel/debug/debug.cpp | 2 +- src/system/kernel/vm/vm.cpp | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/ata/ATATracing.cpp b/src/add-ons/kernel/bus_managers/ata/ATATracing.cpp index 1f2d53f374..db6723cdea 100644 --- a/src/add-ons/kernel/bus_managers/ata/ATATracing.cpp +++ b/src/add-ons/kernel/bus_managers/ata/ATATracing.cpp @@ -23,7 +23,7 @@ ata_trace_printf(uint32 flags, const char *format, ...) size_t totalBytes = vsnprintf(sTraceBuffer + sTraceBufferOffset, sizeof(sTraceBuffer) - sTraceBufferOffset, format, arguments); sTraceBufferOffset += std::min(totalBytes, - sizeof(sTraceBuffer) - sTraceBufferOffset - 1); + (size_t)(sizeof(sTraceBuffer) - sTraceBufferOffset - 1)); va_end(arguments); } diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp b/src/add-ons/kernel/bus_managers/usb/Hub.cpp index 229786dbe5..64bc4516f0 100644 --- a/src/add-ons/kernel/bus_managers/usb/Hub.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Hub.cpp @@ -417,7 +417,7 @@ Hub::BuildDeviceName(char *string, uint32 *index, size_t bufferSize, int32 managerIndex = GetStack()->IndexOfBusManager(GetBusManager()); size_t totalBytes = snprintf(string + *index, bufferSize - *index, "%" B_PRId32, managerIndex); - *index += std::min(totalBytes, bufferSize - *index - 1); + *index += std::min(totalBytes, (size_t)(bufferSize - *index - 1)); } } @@ -426,7 +426,7 @@ Hub::BuildDeviceName(char *string, uint32 *index, size_t bufferSize, if (*index < bufferSize) { size_t totalBytes = snprintf(string + *index, bufferSize - *index, "/hub"); - *index += std::min(totalBytes, bufferSize - *index - 1); + *index += std::min(totalBytes, (size_t)(bufferSize - *index - 1)); } } else { // find out where the requested device sitts @@ -435,7 +435,8 @@ Hub::BuildDeviceName(char *string, uint32 *index, size_t bufferSize, if (*index < bufferSize) { size_t totalBytes = snprintf(string + *index, bufferSize - *index, "/%" B_PRId32, i); - *index += std::min(totalBytes, bufferSize - *index - 1); + *index += std::min(totalBytes, + (size_t)(bufferSize - *index - 1)); } break; } diff --git a/src/system/kernel/debug/debug.cpp b/src/system/kernel/debug/debug.cpp index 1672d78303..bfd31c98a0 100644 --- a/src/system/kernel/debug/debug.cpp +++ b/src/system/kernel/debug/debug.cpp @@ -1986,7 +1986,7 @@ debug_strlcpy(team_id teamID, char* to, const char* from, size_t size) return B_BAD_ADDRESS; // limit size to avoid address overflows - size_t maxSize = std::min(size, + size_t maxSize = std::min((addr_t)size, ~(addr_t)0 - std::max((addr_t)from, (addr_t)to) + 1); // NOTE: Since strlcpy() determines the length of \a from, the source // address might still overflow. diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 569b62d3de..8bb5167b0c 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -5316,7 +5316,7 @@ user_strlcpy(char* to, const char* from, size_t size) return B_BAD_ADDRESS; // limit size to avoid address overflows - size_t maxSize = std::min(size, + size_t maxSize = std::min((addr_t)size, ~(addr_t)0 - std::max((addr_t)from, (addr_t)to) + 1); // NOTE: Since arch_cpu_user_strlcpy() determines the length of \a from, // the source address might still overflow. From 15d594cccddf715daae268eeff2a65590fb2f6b2 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sun, 8 Nov 2015 00:54:32 +0100 Subject: [PATCH 120/370] ARM: Add __aeabi_memset and __aeabi_memmove alias --- src/system/libroot/posix/string/arch/generic/memset.c | 5 +++++ src/system/libroot/posix/string/memmove.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/system/libroot/posix/string/arch/generic/memset.c b/src/system/libroot/posix/string/arch/generic/memset.c index 68166576a7..bd75a763f4 100644 --- a/src/system/libroot/posix/string/arch/generic/memset.c +++ b/src/system/libroot/posix/string/arch/generic/memset.c @@ -17,3 +17,8 @@ memset(void *s, int c, size_t count) return s; } + +#ifdef __ARM__ +void* __aeabi_memset(void *s, int c, size_t count) + __attribute__((__alias__("memset"))); +#endif diff --git a/src/system/libroot/posix/string/memmove.c b/src/system/libroot/posix/string/memmove.c index 1c005ff3a0..38974d8fdc 100644 --- a/src/system/libroot/posix/string/memmove.c +++ b/src/system/libroot/posix/string/memmove.c @@ -70,4 +70,9 @@ memmove(void* dest, void const* src, size_t count) return dest; } +#ifdef __ARM__ +void* __aeabi_memmove(void* dest, void const* src, size_t count) + __attribute__((__alias__("memmove"))); +#endif + #endif From 93bcaf3650a2d561623d233efc56b339dbb20397 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sun, 8 Nov 2015 00:59:18 +0100 Subject: [PATCH 121/370] arm/arch_exceptions.S: Replace spsr_all with spsr After a quick look at binutils, they seem to be equal, however, Clang does not accept the _all one. --- src/system/kernel/arch/arm/arch_exceptions.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/arch/arm/arch_exceptions.S b/src/system/kernel/arch/arm/arch_exceptions.S index a67ff888f2..42ff0bb533 100644 --- a/src/system/kernel/arch/arm/arch_exceptions.S +++ b/src/system/kernel/arch/arm/arch_exceptions.S @@ -32,20 +32,20 @@ str r0, [sp, #-4]! /* Push return address */ str lr, [sp, #-4]! /* Push SVC lr */ str r2, [sp, #-4]! /* Push SVC sp */ - msr spsr_all, r3 /* Restore correct spsr */ + msr spsr, r3 /* Restore correct spsr */ ldmdb r1, {r0-r3} /* Restore 4 regs from xxx mode */ sub sp, sp, #(4*15) /* Adjust the stack pointer */ stmia sp, {r0-r12} /* Push the user mode registers */ add r0, sp, #(4*13) /* Adjust the stack pointer */ stmia r0, {r13-r14}^ /* Push the user mode registers */ mov r0, r0 /* NOP for previous instruction */ - mrs r0, spsr_all + mrs r0, spsr str r0, [sp, #-4]! /* Save spsr */ .endm .macro PULLFRAMEFROMSVCANDEXIT ldr r0, [sp], #0x0004 /* Get the SPSR from stack */ - msr spsr_all, r0 /* restore SPSR */ + msr spsr, r0 /* restore SPSR */ ldmia sp, {r0-r14}^ /* Restore registers (usr mode) */ mov r0, r0 /* NOP for previous instruction */ add sp, sp, #(4*15) /* Adjust the stack pointer */ From 8f4a653ca65112f5e4565b3609c1a6b37abe271b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 8 Nov 2015 03:55:37 +0100 Subject: [PATCH 122/370] VFS: typo --- src/system/kernel/fs/vfs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 6645658015..097fa3b577 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -2483,7 +2483,7 @@ get_vnode_name(struct vnode* vnode, struct vnode* parent, struct dirent* buffer, if (bufferSize < sizeof(struct dirent)) return B_BAD_VALUE; - // See if the vnode is convering another vnode and move to the covered + // See if the vnode is covering another vnode and move to the covered // vnode so we get the underlying file system VNodePutter vnodePutter; if (Vnode* coveredVnode = get_covered_vnode(vnode)) { From c518435bb11ae496a00423b35b894f8590acf87d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 8 Nov 2015 04:29:22 +0100 Subject: [PATCH 123/370] VFS: pass correct vnode to fs calls in default get_vnode_name The opendir and closedir/free_dircookie hooks were called with mismatched vnode. It seems only googlefs is actually affected by this, since all other fs without a get_vnode_name just don't are about the passed vnode arg to closedir and free_dircookie. Now I should really get some sleep! --- src/system/kernel/fs/vfs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 097fa3b577..963eb371cc 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -2528,8 +2528,8 @@ get_vnode_name(struct vnode* vnode, struct vnode* parent, struct dirent* buffer, } } - FS_CALL(vnode, close_dir, cookie); - FS_CALL(vnode, free_dir_cookie, cookie); + FS_CALL(parent, close_dir, cookie); + FS_CALL(parent, free_dir_cookie, cookie); } return status; } From 25472bc40ac23dafefedf8e81aa51b1a08688648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 7 Nov 2015 21:16:47 +0100 Subject: [PATCH 124/370] googlefs: update default Google server --- src/add-ons/kernel/file_systems/googlefs/settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/add-ons/kernel/file_systems/googlefs/settings.c b/src/add-ons/kernel/file_systems/googlefs/settings.c index 8534d31401..7959abde57 100644 --- a/src/add-ons/kernel/file_systems/googlefs/settings.c +++ b/src/add-ons/kernel/file_systems/googlefs/settings.c @@ -7,7 +7,7 @@ #include #include "settings.h" -#define DEFAULT_GOOGLE_SERVER "66.102.11.99" +#define DEFAULT_GOOGLE_SERVER "74.125.136.105" #define DEFAULT_MAX_VNODES 5000 char google_server[20] = DEFAULT_GOOGLE_SERVER; int google_server_port = 80; From 49d3cc2a781b1dba912eecaad3a56ad5dda1c45a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 7 Nov 2015 21:17:21 +0100 Subject: [PATCH 125/370] googlefs: error handling Damn this code is ugly! Also dump the header we get to /tmp --- .../kernel/file_systems/googlefs/http_cnx.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/add-ons/kernel/file_systems/googlefs/http_cnx.c b/src/add-ons/kernel/file_systems/googlefs/http_cnx.c index 3bbe3d19aa..d270902152 100644 --- a/src/add-ons/kernel/file_systems/googlefs/http_cnx.c +++ b/src/add-ons/kernel/file_systems/googlefs/http_cnx.c @@ -128,9 +128,10 @@ status_t http_get(struct http_cnx *cnx, const char *url) long contentlen = 0; if (strlen(url) > 4096 - 128) return EINVAL; - req = malloc(4096); + req = malloc(4096+1); if (!req) return B_NO_MEMORY; + req[4096] = '\0'; /* no snprintf in kernel :( */ sprintf(req, "GET %s HTTP/"HTTPVER"\r\nUser-Agent: " GOOGLEFS_UA "\r\nAccept: */*\r\n\r\n", url); reqlen = strlen(req); @@ -140,10 +141,24 @@ status_t http_get(struct http_cnx *cnx, const char *url) reqlen = 4096; err = len = read(cnx->sock, req, reqlen); printf("read(sock) = %d\n", len); + if (err < 0) + goto err0; //write(1, req, len); - err = B_NO_MEMORY; + { + int fd; + // debug output + fd = open("/tmp/google.html_", O_CREAT|O_TRUNC|O_RDWR, 0644); + write(fd, req, len); + close(fd); + } + + err = EINVAL; if (len < 10) goto err0; + if (!strstr(req, "HTTP/1.0 200")) + goto err0; + + err = B_NO_MEMORY; if (!strstr(req, "\r\n\r\n")) { if (!strstr(req, "\n\n")) /* shouldn't happen */ goto err0; From 26b35e649f34422e8904dd9bf7ff420248aa16c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 7 Nov 2015 21:18:29 +0100 Subject: [PATCH 126/370] googlefs: force disabling HTTP redirection from Google We don't really handle HTTP REDIRECT... --- src/add-ons/kernel/file_systems/googlefs/google_request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/add-ons/kernel/file_systems/googlefs/google_request.c b/src/add-ons/kernel/file_systems/googlefs/google_request.c index e28f123663..8780aae503 100644 --- a/src/add-ons/kernel/file_systems/googlefs/google_request.c +++ b/src/add-ons/kernel/file_systems/googlefs/google_request.c @@ -30,7 +30,7 @@ #define TESTURL "http://www.google.com/search?hl=en&ie=UTF-8&num=50&q=beos" //#define BASEURL "http://www.google.com/search?hl=en&ie=UTF-8&num=50&q=" -#define BASEURL "/search?hl=en&ie=UTF-8&oe=UTF-8" +#define BASEURL "/search?hl=en&ie=UTF-8&oe=UTF-8&gws_rd=cr" #define FMT_NUM "&num=%u" #define FMT_Q "&q=%s" From 02487f3c4b539086a9402f5164923db18ee892ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 7 Nov 2015 22:06:50 +0100 Subject: [PATCH 127/370] googlefs: fix parsing --- .../file_systems/googlefs/google_request.c | 4 +- .../file_systems/googlefs/google_request.h | 1 + .../file_systems/googlefs/parse_google_html.c | 40 +++++++------------ 3 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/add-ons/kernel/file_systems/googlefs/google_request.c b/src/add-ons/kernel/file_systems/googlefs/google_request.c index 8780aae503..8acf285cd1 100644 --- a/src/add-ons/kernel/file_systems/googlefs/google_request.c +++ b/src/add-ons/kernel/file_systems/googlefs/google_request.c @@ -35,7 +35,7 @@ #define FMT_Q "&q=%s" /* parse_google_html.c */ -extern int google_parse_results(const char *html, size_t htmlsize, struct google_result **results); +extern int google_parse_results(const char *html, size_t htmlsize, long *nextid, struct google_result **results); // move that to ksocket inlined static int kinet_aton(const char *in, struct in_addr *addr) @@ -150,7 +150,7 @@ status_t google_request_process(struct google_request *req) close(fd); } #endif /* FAKE_INPUT */ - err = count = google_parse_results(req->cnx->data, req->cnx->datalen, &req->results); + err = count = google_parse_results(req->cnx->data, req->cnx->datalen, &req->nextid, &req->results); if (err < 0) goto err_get; #ifdef DO_PUBLISH diff --git a/src/add-ons/kernel/file_systems/googlefs/google_request.h b/src/add-ons/kernel/file_systems/googlefs/google_request.h index 7352bbb7d7..6163eb633e 100644 --- a/src/add-ons/kernel/file_systems/googlefs/google_request.h +++ b/src/add-ons/kernel/file_systems/googlefs/google_request.h @@ -12,6 +12,7 @@ struct google_request { char *query_string; struct http_cnx *cnx; struct google_result *results; + long nextid; }; /* those are quite arbitrary values */ diff --git a/src/add-ons/kernel/file_systems/googlefs/parse_google_html.c b/src/add-ons/kernel/file_systems/googlefs/parse_google_html.c index 881fe6b8cb..3ac2349f86 100644 --- a/src/add-ons/kernel/file_systems/googlefs/parse_google_html.c +++ b/src/add-ons/kernel/file_systems/googlefs/parse_google_html.c @@ -34,9 +34,9 @@ int dbgstep = 0; //#define G_BEGIN_URL "

" -#define G_END_URL "\" class=l>" +#define G_END_URL "\">" //#define G_BEGIN_NAME #define G_END_NAME "" #define G_BEGIN_SNIPSET /*""*/"" @@ -44,15 +44,14 @@ int dbgstep = 0; #define G_BEGIN_CACHESIM " " -int google_parse_results(const char *html, size_t htmlsize, struct google_result **results) +int google_parse_results(const char *html, size_t htmlsize, long *nextid, struct google_result **results) { struct google_result *res = NULL, *nres = NULL, *prev = NULL; char *p, *q; char *nextresult = NULL; long numres = 0; - long maxres = 0; - long startid = 0; - long lastid = 0; + long maxres = 1000; + //long startid = 0; int done = 0; int err = ENOMEM; @@ -63,8 +62,10 @@ int google_parse_results(const char *html, size_t htmlsize, struct google_result PRST; /* google now sends sometimes... */ if (strstr(html, "") != html) { - if (strstr(html, "") != html) - return EINVAL; + if (strstr(html, "") != html) { + if (strstr(html, "Google Search:"); @@ -74,26 +75,12 @@ int google_parse_results(const char *html, size_t htmlsize, struct google_result p = strstr(html, " Results "); - if (!p) return EINVAL; - PRST; - p+= strlen("> Results "); - startid = strtol(p, &p, 10); - if (!p) return EINVAL; - PRST; - p = strstr(html, " - "); - p+= strlen(" - "); - if (!p) return EINVAL; - PRST; - lastid = strtol(p, &p, 10); - if (!p) return EINVAL; - PRST; - maxres = lastid - startid + 1; - printf(DBG"getting %ld results (%ld to %ld)\n", maxres, startid, lastid); + /* p = strstr(html, "Search Results<"); if (!p) return EINVAL; PRST; + */ printf(DBG"parsing...\n"); @@ -111,7 +98,7 @@ int google_parse_results(const char *html, size_t htmlsize, struct google_result goto err0; } memset(nres, 0, sizeof(struct google_result)); - nres->id = startid + numres; //- 1; + nres->id = (*nextid)++; //- 1; PRST; /* find url */ @@ -273,13 +260,14 @@ int main(int argc, char **argv) size_t len; char *p; int err; + long nextid = 0; p = malloc(BUFSZ+8); len = read(0, p+4, BUFSZ); p[BUFSZ+4-1] = '\0'; *(uint32 *)p = 0xa5a5a5a5; *(uint32 *)(&p[BUFSZ+4]) = 0x5a5a5a5a; - err = google_parse_results(p+4, len, &results); + err = google_parse_results(p+4, len, &nextid, &results); printf("error 0x%08lx\n", err); if (err < 0) return 1; From 5aeaaebad9571784ccb352e8292ca7b6beb53db6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 7 Nov 2015 22:26:17 +0100 Subject: [PATCH 128/370] googlefs: fix parsed urls we now get relative URLs it seems... --- .../file_systems/googlefs/parse_google_html.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/add-ons/kernel/file_systems/googlefs/parse_google_html.c b/src/add-ons/kernel/file_systems/googlefs/parse_google_html.c index 3ac2349f86..345238f80d 100644 --- a/src/add-ons/kernel/file_systems/googlefs/parse_google_html.c +++ b/src/add-ons/kernel/file_systems/googlefs/parse_google_html.c @@ -43,6 +43,7 @@ int dbgstep = 0; #define G_END_SNIPSET "
" #define G_BEGIN_CACHESIM "
" +#define G_URL_PREFIX "http://www.google.com" int google_parse_results(const char *html, size_t htmlsize, long *nextid, struct google_result **results) { @@ -88,6 +89,7 @@ int google_parse_results(const char *html, size_t htmlsize, long *nextid, struct char *item; long itemlen; char *tmp; + char *urlp; int i; #ifdef TESTME dbgstep = 0; @@ -119,10 +121,17 @@ int google_parse_results(const char *html, size_t htmlsize, long *nextid, struct PRST; p+= strlen(G_END_URL); //printf(DBG"[%ld] found token 2\n", numres); - itemlen = p - item - strlen(G_END_URL); - itemlen = MIN(GR_MAX_URL-1, itemlen); - strncpy(nres->url, item, itemlen); - nres->url[itemlen] = '\0'; + itemlen = GR_MAX_URL-1; + urlp = nres->url; + if (!strncmp(item, "/url?", 5)) { + strcpy(urlp, G_URL_PREFIX); + itemlen -= strlen(G_URL_PREFIX); + urlp += strlen(G_URL_PREFIX); + printf("plop\n"); + } + itemlen = MIN(itemlen, p - item - strlen(G_END_URL)); + strncpy(urlp, item, itemlen); + urlp[itemlen] = '\0'; /* find name */ //Google Web APIs - FAQ Date: Sat, 7 Nov 2015 23:10:12 +0100 Subject: [PATCH 129/370] googlefs: typo --- src/add-ons/kernel/file_systems/googlefs/googlefs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/add-ons/kernel/file_systems/googlefs/googlefs.c b/src/add-ons/kernel/file_systems/googlefs/googlefs.c index ca085198cf..5f88c9f684 100644 --- a/src/add-ons/kernel/file_systems/googlefs/googlefs.c +++ b/src/add-ons/kernel/file_systems/googlefs/googlefs.c @@ -596,7 +596,7 @@ int googlefs_free_cookie(fs_volume *_volume, fs_vnode *_node, fs_file_cookie *co err = LOCK(&node->l); if (err) return err; - err = SLL_REMOVE(node->opened, next, cookie); /* just to amke sure */ + err = SLL_REMOVE(node->opened, next, cookie); /* just to make sure */ // if (err) // goto err_n_l; if (/*!node->is_perm &&*/ false) { /* not yet */ @@ -1166,7 +1166,7 @@ int googlefs_free_attr_cookie_h(fs_volume *_volume, fs_vnode *_node, fs_file_coo err = LOCK(&node->l); if (err) return err; - err = SLL_REMOVE(node->opened, next, cookie); /* just to amke sure */ + err = SLL_REMOVE(node->opened, next, cookie); /* just to make sure */ // if (err) // goto err_n_l; UNLOCK(&node->l); From 2e04b3a2b99763ffdc419f9b5bf9fc6450b3e6df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 8 Nov 2015 04:44:42 +0100 Subject: [PATCH 130/370] googlefs: fix a possible race condition --- src/add-ons/kernel/file_systems/googlefs/googlefs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/add-ons/kernel/file_systems/googlefs/googlefs.c b/src/add-ons/kernel/file_systems/googlefs/googlefs.c index 5f88c9f684..32be96b0fe 100644 --- a/src/add-ons/kernel/file_systems/googlefs/googlefs.c +++ b/src/add-ons/kernel/file_systems/googlefs/googlefs.c @@ -1365,11 +1365,11 @@ int googlefs_open_query(fs_volume *_volume, const char *query, ulong flags, UNLOCK(&ns->l); reuse: /* put the chocolate on the cookie */ + c->node = qn; LOCK(&qn->l); SLL_INSERT(qn->opened, next, c); UNLOCK(&qn->l); qn->qcompleted = 1; /* tell other cookies we're done */ - c->node = qn; *cookie = c; free(qstring); return B_OK; From 3d58615e3aa99166c51bda4cdeac4d3ff14cd0c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 8 Nov 2015 04:45:58 +0100 Subject: [PATCH 131/370] googlefs: make the close/free hooks more robust --- .../kernel/file_systems/googlefs/googlefs.c | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/add-ons/kernel/file_systems/googlefs/googlefs.c b/src/add-ons/kernel/file_systems/googlefs/googlefs.c index 32be96b0fe..691678cee2 100644 --- a/src/add-ons/kernel/file_systems/googlefs/googlefs.c +++ b/src/add-ons/kernel/file_systems/googlefs/googlefs.c @@ -392,13 +392,15 @@ int googlefs_closedir(fs_volume *_volume, fs_vnode *_node, fs_dir_cookie *cookie fs_nspace *ns = (fs_nspace *)_volume->private_volume; fs_node *node = (fs_node *)_node->private_node; status_t err = B_OK; - TRACE((PFS "closedir(%ld, %Ld)\n", ns->nsid, node->vnid)); +// node = cookie->node; // work around VFS bug + TRACE((PFS "closedir(%ld, %Ld, %p)\n", ns->nsid, node->vnid, cookie)); err = LOCK(&node->l); if (err) return err; SLL_REMOVE(node->opened, next, cookie); UNLOCK(&node->l); + return err; } @@ -470,7 +472,14 @@ int googlefs_free_dircookie(fs_volume *_volume, fs_vnode *_node, fs_dir_cookie * { fs_nspace *ns = (fs_nspace *)_volume->private_volume; fs_node *node = (fs_node *)_node->private_node; - TRACE((PFS"freedircookie(%ld, %Ld)\n", ns->nsid, node?node->vnid:0LL)); + status_t err = B_OK; +// node = cookie->node; // work around VFS bug + TRACE((PFS"freedircookie(%ld, %Ld, %p)\n", ns->nsid, node?node->vnid:0LL, cookie)); + err = LOCK(&node->l); + if (err) + return err; + err = SLL_REMOVE(node->opened, next, cookie); /* just to make sure */ + UNLOCK(&node->l); free(cookie); return B_OK; } @@ -1017,7 +1026,13 @@ int googlefs_free_attrdircookie(fs_volume *_volume, fs_vnode *_node, fs_attr_dir { fs_nspace *ns = (fs_nspace *)_volume->private_volume; fs_node *node = (fs_node *)_node->private_node; + status_t err = B_OK; TRACE((PFS"free_attrdircookie(%ld, %Ld)\n", ns->nsid, node->vnid)); + err = LOCK(&node->l); + if (err) + return err; + SLL_REMOVE(node->opened, next, cookie); /* just to make sure */ + UNLOCK(&node->l); free(cookie); return B_OK; } @@ -1419,7 +1434,23 @@ int googlefs_close_query(fs_volume *_volume, fs_query_cookie *cookie) /* protos are different... */ int googlefs_free_query_cookie(fs_volume *_volume, fs_dir_cookie *cookie) { + status_t err = B_OK; + fs_node *q; TRACE((PFS"free_query_cookie(%ld)\n", _volume->id)); + q = cookie->node; + if (!q) + goto no_node; + err = LOCK(&q->l); + if (err) + return err; + err = SLL_REMOVE(q->opened, next, cookie); /* just to make sure */ + if (q->request /*&& !q->opened*/) { + err = google_request_close(q->request); + } +// if (err) +// goto err_n_l; + UNLOCK(&q->l); +no_node: free(cookie); return B_OK; } From c4ad6501bcd7758bde20d500644195b3762e1673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 8 Nov 2015 04:46:36 +0100 Subject: [PATCH 132/370] googlefs: provide get_vnode_name This works around the VFS bug I just fixed. :D --- src/add-ons/kernel/file_systems/googlefs/googlefs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/add-ons/kernel/file_systems/googlefs/googlefs.c b/src/add-ons/kernel/file_systems/googlefs/googlefs.c index 691678cee2..f8756bb45a 100644 --- a/src/add-ons/kernel/file_systems/googlefs/googlefs.c +++ b/src/add-ons/kernel/file_systems/googlefs/googlefs.c @@ -1628,7 +1628,7 @@ static fs_volume_ops sGoogleFSVolumeOps = { static fs_vnode_ops sGoogleFSVnodeOps = { /* vnode operations */ &googlefs_walk, - NULL, // fs_get_vnode_name + &googlefs_get_vnode_name, //NULL, // fs_get_vnode_name &googlefs_release_vnode, &googlefs_remove_vnode, From 7218744e73cf8797920aaf19e194ca3369618e9c Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Sat, 7 Nov 2015 18:40:06 +0100 Subject: [PATCH 133/370] Network preferences: missing translations. * Some files with localized items were not added to the jamfile. --- src/preferences/network/Jamfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/preferences/network/Jamfile b/src/preferences/network/Jamfile index f4a1db37ab..acbd1df906 100644 --- a/src/preferences/network/Jamfile +++ b/src/preferences/network/Jamfile @@ -34,6 +34,8 @@ Preference Network : DoCatalogs Network : x-vnd.Haiku-Network : + InterfaceListItem.cpp + InterfaceView.cpp Network.cpp NetworkWindow.cpp NetworkProfile.cpp From 60572cc8d023e54f8b549b4703cc01f62197ace3 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Sun, 8 Nov 2015 09:19:59 +0100 Subject: [PATCH 134/370] Add a MIME type to network_settings add-ons * This is required for localization to work. --- .../network_settings/dnsclient/DNSClientService.rdef | 12 ++++++++++++ src/add-ons/network_settings/dnsclient/Jamfile | 2 ++ src/add-ons/network_settings/ftpd/FTPService.rdef | 11 +++++++++++ src/add-ons/network_settings/ftpd/Jamfile | 2 ++ src/add-ons/network_settings/ipv4/IPv4Interface.rdef | 12 ++++++++++++ src/add-ons/network_settings/ipv4/Jamfile | 2 ++ src/add-ons/network_settings/ipv6/IPv6Interface.rdef | 12 ++++++++++++ src/add-ons/network_settings/ipv6/Jamfile | 2 ++ src/add-ons/network_settings/sshd/Jamfile | 2 ++ src/add-ons/network_settings/sshd/SSHService.rdef | 12 ++++++++++++ src/add-ons/network_settings/telnetd/Jamfile | 2 ++ .../network_settings/telnetd/TelnetService.rdef | 12 ++++++++++++ 12 files changed, 83 insertions(+) create mode 100644 src/add-ons/network_settings/dnsclient/DNSClientService.rdef create mode 100644 src/add-ons/network_settings/ftpd/FTPService.rdef create mode 100644 src/add-ons/network_settings/ipv4/IPv4Interface.rdef create mode 100644 src/add-ons/network_settings/ipv6/IPv6Interface.rdef create mode 100644 src/add-ons/network_settings/sshd/SSHService.rdef create mode 100644 src/add-ons/network_settings/telnetd/TelnetService.rdef diff --git a/src/add-ons/network_settings/dnsclient/DNSClientService.rdef b/src/add-ons/network_settings/dnsclient/DNSClientService.rdef new file mode 100644 index 0000000000..4b7974e0e7 --- /dev/null +++ b/src/add-ons/network_settings/dnsclient/DNSClientService.rdef @@ -0,0 +1,12 @@ +resource app_signature "application/x-vnd.Haiku-DNSClientService"; + +resource app_version { + major = 1, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "1.0.0", + long_info = "Haiku DNS Client settings" +}; + diff --git a/src/add-ons/network_settings/dnsclient/Jamfile b/src/add-ons/network_settings/dnsclient/Jamfile index 9cd2991f17..ede6750c01 100644 --- a/src/add-ons/network_settings/dnsclient/Jamfile +++ b/src/add-ons/network_settings/dnsclient/Jamfile @@ -4,6 +4,8 @@ UsePublicHeaders [ FDirName add-ons network_settings ] ; UsePrivateHeaders app libroot kernel net ; UseHeaders [ FDirName $(HAIKU_TOP) src preferences network ] : false ; +AddResources DNSClientService : DNSClientService.rdef ; + Addon DNSClientService : DNSClientServiceAddOn.cpp DNSSettingsView.cpp diff --git a/src/add-ons/network_settings/ftpd/FTPService.rdef b/src/add-ons/network_settings/ftpd/FTPService.rdef new file mode 100644 index 0000000000..8c008c8d88 --- /dev/null +++ b/src/add-ons/network_settings/ftpd/FTPService.rdef @@ -0,0 +1,11 @@ +resource app_signature "application/x-vnd.Haiku-FTPService"; + +resource app_version { + major = 1, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "1.0.0", + long_info = "Haiku FTP server settings" +}; diff --git a/src/add-ons/network_settings/ftpd/Jamfile b/src/add-ons/network_settings/ftpd/Jamfile index ecf681a56c..c774f59423 100644 --- a/src/add-ons/network_settings/ftpd/Jamfile +++ b/src/add-ons/network_settings/ftpd/Jamfile @@ -4,6 +4,8 @@ UsePublicHeaders [ FDirName add-ons network_settings ] ; UsePrivateHeaders app libroot kernel net shared ; UseHeaders [ FDirName $(HAIKU_TOP) src preferences network ] : false ; +AddResources FTPService : FTPService.rdef ; + Addon FTPService : FTPServiceAddOn.cpp diff --git a/src/add-ons/network_settings/ipv4/IPv4Interface.rdef b/src/add-ons/network_settings/ipv4/IPv4Interface.rdef new file mode 100644 index 0000000000..7eab728c88 --- /dev/null +++ b/src/add-ons/network_settings/ipv4/IPv4Interface.rdef @@ -0,0 +1,12 @@ +resource app_signature "application/x-vnd.Haiku-IPv4Interface"; + +resource app_version { + major = 1, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "1.0.0", + long_info = "Haiku IPv4 interface settings" +}; + diff --git a/src/add-ons/network_settings/ipv4/Jamfile b/src/add-ons/network_settings/ipv4/Jamfile index 71fe78d4e4..e8d9c86433 100644 --- a/src/add-ons/network_settings/ipv4/Jamfile +++ b/src/add-ons/network_settings/ipv4/Jamfile @@ -4,6 +4,8 @@ UsePublicHeaders [ FDirName add-ons network_settings ] ; UsePrivateHeaders shared ; UseHeaders [ FDirName $(HAIKU_TOP) src preferences network ] : false ; +AddResources IPv4Interface : IPv4Interface.rdef ; + Addon IPv4Interface : IPv4InterfaceAddOn.cpp diff --git a/src/add-ons/network_settings/ipv6/IPv6Interface.rdef b/src/add-ons/network_settings/ipv6/IPv6Interface.rdef new file mode 100644 index 0000000000..bda4c0ef90 --- /dev/null +++ b/src/add-ons/network_settings/ipv6/IPv6Interface.rdef @@ -0,0 +1,12 @@ +resource app_signature "application/x-vnd.Haiku-IPv6Interface"; + +resource app_version { + major = 1, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "1.0.0", + long_info = "Haiku IPv6 interface settings" +}; + diff --git a/src/add-ons/network_settings/ipv6/Jamfile b/src/add-ons/network_settings/ipv6/Jamfile index 4aa7e36b8e..53df2c986b 100644 --- a/src/add-ons/network_settings/ipv6/Jamfile +++ b/src/add-ons/network_settings/ipv6/Jamfile @@ -6,6 +6,8 @@ UseHeaders [ FDirName $(HAIKU_TOP) src preferences network ] : false ; SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons network_settings ipv4 ] ; +AddResources IPv6Interface : IPv6Interface.rdef ; + Addon IPv6Interface : IPv6InterfaceAddOn.cpp diff --git a/src/add-ons/network_settings/sshd/Jamfile b/src/add-ons/network_settings/sshd/Jamfile index 1868954f83..d0bf64e75a 100644 --- a/src/add-ons/network_settings/sshd/Jamfile +++ b/src/add-ons/network_settings/sshd/Jamfile @@ -4,6 +4,8 @@ UsePublicHeaders [ FDirName add-ons network_settings ] ; UsePrivateHeaders app libroot kernel net shared ; UseHeaders [ FDirName $(HAIKU_TOP) src preferences network ] : false ; +AddResources SSHService : SSHService.rdef ; + Addon SSHService : SSHServiceAddOn.cpp diff --git a/src/add-ons/network_settings/sshd/SSHService.rdef b/src/add-ons/network_settings/sshd/SSHService.rdef new file mode 100644 index 0000000000..ce4514df9f --- /dev/null +++ b/src/add-ons/network_settings/sshd/SSHService.rdef @@ -0,0 +1,12 @@ +resource app_signature "application/x-vnd.Haiku-SSHService"; + +resource app_version { + major = 1, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "1.0.0", + long_info = "Haiku SSH server settings" +}; + diff --git a/src/add-ons/network_settings/telnetd/Jamfile b/src/add-ons/network_settings/telnetd/Jamfile index 22fa137c99..ffdf578d05 100644 --- a/src/add-ons/network_settings/telnetd/Jamfile +++ b/src/add-ons/network_settings/telnetd/Jamfile @@ -4,6 +4,8 @@ UsePublicHeaders [ FDirName add-ons network_settings ] ; UsePrivateHeaders app libroot kernel net shared ; UseHeaders [ FDirName $(HAIKU_TOP) src preferences network ] : false ; +AddResources TelnetService : TelnetService.rdef ; + Addon TelnetService : TelnetServiceAddOn.cpp diff --git a/src/add-ons/network_settings/telnetd/TelnetService.rdef b/src/add-ons/network_settings/telnetd/TelnetService.rdef new file mode 100644 index 0000000000..bd8b11b0ab --- /dev/null +++ b/src/add-ons/network_settings/telnetd/TelnetService.rdef @@ -0,0 +1,12 @@ +resource app_signature "application/x-vnd.Haiku-TelnetService"; + +resource app_version { + major = 1, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "1.0.0", + long_info = "Haiku telnet server settings" +}; + From f761076be50c48ff87da92376d5b8bdc5fa8bb44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 8 Nov 2015 10:33:33 +0100 Subject: [PATCH 135/370] launch_daemon: Fixed DemandEvent::ToString(). * Reported "event" instead of "demand". --- src/servers/launch/Events.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/servers/launch/Events.cpp b/src/servers/launch/Events.cpp index 400fb3566b..af7801880b 100644 --- a/src/servers/launch/Events.cpp +++ b/src/servers/launch/Events.cpp @@ -471,7 +471,7 @@ DemandEvent::Unregister(EventRegistrator& registrator) BString DemandEvent::ToString() const { - return "event"; + return "demand"; } From f0e23c2b9b4547bdd04c059dde5062f03563d08d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 8 Nov 2015 10:55:23 +0100 Subject: [PATCH 136/370] launch_daemon: Fixed missing Event member initialization. * This fixes targets starting seemingly unconditionally. --- src/servers/launch/Events.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/servers/launch/Events.cpp b/src/servers/launch/Events.cpp index af7801880b..316292adba 100644 --- a/src/servers/launch/Events.cpp +++ b/src/servers/launch/Events.cpp @@ -186,7 +186,8 @@ create_event(Event* parent, const char* name, const BMessenger* target, Event::Event(Event* parent) : - fParent(parent) + fParent(parent), + fTriggered(false) { } From a7bddff13e7c06348d7e2c61f884e070dc711ce7 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sun, 8 Nov 2015 15:58:56 +0100 Subject: [PATCH 137/370] configure: Cleaner way for --use-clang --- configure | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/configure b/configure index 76bd602adb..df50d59c09 100755 --- a/configure +++ b/configure @@ -307,16 +307,7 @@ standard_gcc_settings() set_variable HAIKU_CPU_$targetArch $targetCpu get_build_tool_path CC_$targetArch "$gcc" - if [ $useClang = 1 ]; then - # The get_build_tool_path above is needed to get the path to the rest - # of the build tools - local path=`dirname $(get_variable HAIKU_CC_$targetArch)` - set_variable HAIKU_CC_$targetArch \ - "PATH=\\\"$path:\\\$PATH\\\" clang -target $gccMachine" - set_variable HAIKU_CC_IS_CLANG_$targetArch 1 - else - set_variable HAIKU_CC_IS_CLANG_$targetArch 0 - fi + set_variable HAIKU_CC_IS_CLANG_$targetArch $useClang set_variable HAIKU_GCC_RAW_VERSION_$targetArch $gccRawVersion set_variable HAIKU_GCC_MACHINE_$targetArch $gccMachine set_variable HAIKU_GCC_LIB_DIR_$targetArch $gccdir @@ -362,7 +353,8 @@ set_default_value() get_build_tool_path() { local var="HAIKU_$1" - local path=$2 + local cmd=$2 + local path=${2%% *} if [ -f "$path" ]; then # get absolute path @@ -377,7 +369,7 @@ get_build_tool_path() } fi - eval "$var=$path" + eval "$var=\"$path ${cmd#${2%% *}}\"" } is_in_list() @@ -792,7 +784,13 @@ else fi # prepare gcc settings and get the actual target architecture - gcc="${crossToolsPrefix}gcc" + if [ $useClang = 1 ]; then + target=${crossToolsPrefix##*/} + target=${target%-} + gcc="clang -target ${target}" + else + gcc="${crossToolsPrefix}gcc" + fi if [ -z "${crossToolsPrefix}" ]; then gcc=`get_variable HAIKU_CC_$targetArch` fi From 50a1d86c887be20ec08f28ed6d61a26cc4453984 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sun, 8 Nov 2015 16:27:31 +0100 Subject: [PATCH 138/370] byteorder.S: Use flds instead of fld Clang refuses to guess. --- src/system/libroot/os/arch/x86/byteorder.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system/libroot/os/arch/x86/byteorder.S b/src/system/libroot/os/arch/x86/byteorder.S index 62289d371e..3bb3237581 100644 --- a/src/system/libroot/os/arch/x86/byteorder.S +++ b/src/system/libroot/os/arch/x86/byteorder.S @@ -44,7 +44,7 @@ FUNCTION(__swap_float): movl 4(%esp), %eax bswap %eax movl %eax, 4(%esp) - fld 4(%esp) + flds 4(%esp) ret FUNCTION_END(__swap_float) From f7ededa6238be37d860b88a8a4dae7526cdd8cfe Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sun, 8 Nov 2015 16:30:40 +0100 Subject: [PATCH 139/370] shell.S: Add .section .bss to make Clang happy --- src/system/boot/platform/bios_ia32/shell.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/system/boot/platform/bios_ia32/shell.S b/src/system/boot/platform/bios_ia32/shell.S index 2aad4e51d9..39c9a6b601 100644 --- a/src/system/boot/platform/bios_ia32/shell.S +++ b/src/system/boot/platform/bios_ia32/shell.S @@ -442,3 +442,5 @@ GLOBAL(gMultiBootInfo): .long 0 .org 1024 + +.section .bss From bfe60c1e5a5787b9e63d55c83885427b959fdd29 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sun, 8 Nov 2015 16:38:57 +0100 Subject: [PATCH 140/370] Don't define __ARM*__ for Clang I have a patch for Clang ready that I will upstream instead. --- build/jam/ArchitectureRules | 5 +---- build/jam/board/rpi2/BoardSetup | 3 --- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/build/jam/ArchitectureRules b/build/jam/ArchitectureRules index a9d05b67dd..8167199bc1 100644 --- a/build/jam/ArchitectureRules +++ b/build/jam/ArchitectureRules @@ -43,10 +43,7 @@ rule ArchitectureSetup architecture local cpu = $(HAIKU_CPU_$(architecture)) ; if $(cpu) = arm { - if $(HAIKU_CC_IS_CLANG_$(architecture)) = 1 { - # Clang only defines __ARMEL__ when using -target arm-haiku-unknown - gccBaseFlags += -D__ARM__=1 ; - } else { + if $(HAIKU_CC_IS_CLANG_$(architecture)) != 1 { # For stackcrawls - not supported by Clang gccBaseFlags += -mapcs-frame ; } diff --git a/build/jam/board/rpi2/BoardSetup b/build/jam/board/rpi2/BoardSetup index 990774c4d1..e9c285af9f 100644 --- a/build/jam/board/rpi2/BoardSetup +++ b/build/jam/board/rpi2/BoardSetup @@ -59,9 +59,6 @@ HAIKU_BOARD_SDIMAGE_SIZE = 128 ; # local flags = -march=armv7-a -mfloat-abi=hard ; -if $(HAIKU_CC_IS_CLANG_$(architecture)) = 1 { - flags += -D__ARM_ARCH__=7 ; -} HAIKU_ASFLAGS_$(HAIKU_PACKAGING_ARCH) += $(flags) ; HAIKU_CCFLAGS_$(HAIKU_PACKAGING_ARCH) += $(flags) ; From 8719963f488f0ebbff747e66743a0af825a5b66c Mon Sep 17 00:00:00 2001 From: "Joseph R. Prostko" Date: Sun, 8 Nov 2015 15:27:19 -0500 Subject: [PATCH 141/370] Add packages for Fossil 1.34 --- build/jam/repositories/HaikuPorts/x86 | 2 +- build/jam/repositories/HaikuPorts/x86_64 | 2 +- build/jam/repositories/HaikuPorts/x86_gcc2 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/jam/repositories/HaikuPorts/x86 b/build/jam/repositories/HaikuPorts/x86 index bf2273df1c..6157e75fa2 100644 --- a/build/jam/repositories/HaikuPorts/x86 +++ b/build/jam/repositories/HaikuPorts/x86 @@ -92,7 +92,7 @@ RemotePackageRepository HaikuPorts flac-1.3.1-1 flac_devel-1.3.1-1 flex-2.5.39-2 - fossil-1.33-1 + fossil-1.34-1 freetype-2.6-1 freetype_devel-2.6-1 gawk-4.1.3-1 diff --git a/build/jam/repositories/HaikuPorts/x86_64 b/build/jam/repositories/HaikuPorts/x86_64 index 75266080a6..2d6d766db9 100644 --- a/build/jam/repositories/HaikuPorts/x86_64 +++ b/build/jam/repositories/HaikuPorts/x86_64 @@ -101,7 +101,7 @@ RemotePackageRepository HaikuPorts flex-2.5.39-1 fontconfig-2.11.94-1 fontconfig_devel-2.11.94-1 - fossil-1.33-1 + fossil-1.34-1 freeciv-2.5.1-1 freetype-2.6.1-1 freetype_devel-2.6.1-1 diff --git a/build/jam/repositories/HaikuPorts/x86_gcc2 b/build/jam/repositories/HaikuPorts/x86_gcc2 index 3f8c3c6ea5..f7bc01d6ad 100644 --- a/build/jam/repositories/HaikuPorts/x86_gcc2 +++ b/build/jam/repositories/HaikuPorts/x86_gcc2 @@ -127,7 +127,7 @@ RemotePackageRepository HaikuPorts fontboy-0.9.7-3 fontconfig-2.11.1-3 fontconfig_devel-2.11.1-3 - fossil-1.33-1 + fossil-1.34-1 freetype-2.6-1 freetype_devel-2.6-1 fribidi-0.19.6-2 From c6fb0e2c4d1b8f876468e33cd7654cdfca5a73e3 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sun, 8 Nov 2015 22:10:41 +0100 Subject: [PATCH 142/370] configure: Disable Clang's integrated assembler We have too much code that doesn't work with it yet and it makes more sense to get the other parts working with Clang first. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index df50d59c09..02d8ce5473 100755 --- a/configure +++ b/configure @@ -787,7 +787,7 @@ else if [ $useClang = 1 ]; then target=${crossToolsPrefix##*/} target=${target%-} - gcc="clang -target ${target}" + gcc="clang -target ${target} -no-integrated-as" else gcc="${crossToolsPrefix}gcc" fi From c73d13015dd3971f720ab9e9a894fe403e43b579 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 8 Nov 2015 19:51:28 +0100 Subject: [PATCH 143/370] kernel: Use anonymous namespaces to avoid type collisions. The anonymous namespace makes type definitions local to the translation unit (like static does for objects). For pretty much any type not shared across multiple files this is what one wants to happen (and might erroneously expect to happen automatically). This commit solves some actual collisions that were present: * The VFS and the rootfs both used an incompatible VnodeHash struct for their BOpenHashTable. * XSI semaphores and message queues both used queued_thread, Ipc and IpcHashTableDefinition. For release builds these did not cause problems as the types were fully inlined. Debug builds would crash at boot however because parts of a BOpenHashTable from the rootfs meant to operate on struct rootfs_vnode would be applied to one from the VFS expecting struct vnode. As such collisions are violations of the one definition rule, the code is at fault and unfortunatley the compiler isn't required to diagnose such problems across translation units (which isn't actually trivial). This can lead to subtle and hard to debug problems and it's therefore best to avoid leaking types into the global namespace whenever possible. --- src/system/kernel/arch/x86/arch_vm.cpp | 5 ++ src/system/kernel/cache/block_cache.cpp | 4 + src/system/kernel/device_manager/devfs.cpp | 12 +-- .../kernel/device_manager/legacy_drivers.cpp | 41 +++++----- src/system/kernel/elf.cpp | 5 ++ src/system/kernel/fs/rootfs.cpp | 14 ++-- src/system/kernel/fs/vfs.cpp | 25 ++++-- src/system/kernel/image.cpp | 4 + src/system/kernel/module.cpp | 78 +++++++++---------- src/system/kernel/port.cpp | 15 ++-- src/system/kernel/posix/realtime_sem.cpp | 4 + src/system/kernel/posix/xsi_message_queue.cpp | 6 ++ src/system/kernel/posix/xsi_semaphore.cpp | 13 ++++ src/system/kernel/vm/VMAddressSpace.cpp | 5 ++ src/system/kernel/vm/vm.cpp | 4 + 15 files changed, 154 insertions(+), 81 deletions(-) diff --git a/src/system/kernel/arch/x86/arch_vm.cpp b/src/system/kernel/arch/x86/arch_vm.cpp index ae063057a5..95b608d836 100644 --- a/src/system/kernel/arch/x86/arch_vm.cpp +++ b/src/system/kernel/arch/x86/arch_vm.cpp @@ -59,6 +59,8 @@ void *gDmaAddress; +namespace { + struct memory_type_range : DoublyLinkedListLinkImpl { uint64 base; uint64 size; @@ -89,6 +91,9 @@ struct update_mtrr_info { typedef DoublyLinkedList MemoryTypeRangeList; +} // namespace + + static mutex sMemoryTypeLock = MUTEX_INITIALIZER("memory type ranges"); static MemoryTypeRangeList sMemoryTypeRanges; static int32 sMemoryTypeRangeCount = 0; diff --git a/src/system/kernel/cache/block_cache.cpp b/src/system/kernel/cache/block_cache.cpp index ce08c5dba9..9482bec2de 100644 --- a/src/system/kernel/cache/block_cache.cpp +++ b/src/system/kernel/cache/block_cache.cpp @@ -50,6 +50,8 @@ static const bigtime_t kTransactionIdleTime = 2000000LL; // a transaction is considered idle after 2 seconds of inactivity +namespace { + struct cache_transaction; struct cached_block; struct block_cache; @@ -322,6 +324,8 @@ public: typedef AutoLocker TransactionLocker; +} // namespace + #if BLOCK_CACHE_BLOCK_TRACING && !defined(BUILDING_USERLAND_FS_SERVER) namespace BlockTracing { diff --git a/src/system/kernel/device_manager/devfs.cpp b/src/system/kernel/device_manager/devfs.cpp index 9f8c742c89..af6c7f7a89 100644 --- a/src/system/kernel/device_manager/devfs.cpp +++ b/src/system/kernel/device_manager/devfs.cpp @@ -50,6 +50,8 @@ #endif +namespace { + struct devfs_partition { struct devfs_vnode* raw_device; partition_info info; @@ -158,11 +160,11 @@ enum { ITERATION_STATE_BEGIN = ITERATION_STATE_DOT, }; -// extern and in a private namespace only to make forward declaration possible -namespace { - extern fs_volume_ops kVolumeOps; - extern fs_vnode_ops kVnodeOps; -} +// extern only to make forward declaration possible +extern fs_volume_ops kVolumeOps; +extern fs_vnode_ops kVnodeOps; + +} // namespace static status_t get_node_for_path(struct devfs* fs, const char* path, diff --git a/src/system/kernel/device_manager/legacy_drivers.cpp b/src/system/kernel/device_manager/legacy_drivers.cpp index 602e1a26c7..cbd792c2a6 100644 --- a/src/system/kernel/device_manager/legacy_drivers.cpp +++ b/src/system/kernel/device_manager/legacy_drivers.cpp @@ -219,27 +219,6 @@ public: }; -} // unnamed namespace - - -static status_t unload_driver(legacy_driver *driver); -static status_t load_driver(legacy_driver *driver); - - -static DriverWatcher sDriverWatcher; -static int32 sDriverEventsPending; -static DriverEventList sDriverEvents; -static mutex sDriverEventsLock = MUTEX_INITIALIZER("driver events"); - // inner lock, protects the sDriverEvents list only -static DirectoryWatcher sDirectoryWatcher; -static DirectoryNodeHash sDirectoryNodeHash; -static recursive_lock sLock; -static bool sWatching; - - -// #pragma mark - driver private - - struct DriverHash { typedef const char* KeyType; typedef legacy_driver ValueType; @@ -268,9 +247,29 @@ struct DriverHash { typedef BOpenHashTable DriverTable; +} // unnamed namespace + + +static status_t unload_driver(legacy_driver *driver); +static status_t load_driver(legacy_driver *driver); + + +static DriverWatcher sDriverWatcher; +static int32 sDriverEventsPending; +static DriverEventList sDriverEvents; +static mutex sDriverEventsLock = MUTEX_INITIALIZER("driver events"); + // inner lock, protects the sDriverEvents list only +static DirectoryWatcher sDirectoryWatcher; +static DirectoryNodeHash sDirectoryNodeHash; +static recursive_lock sLock; +static bool sWatching; + static DriverTable* sDriverHash; +// #pragma mark - driver private + + /*! Collects all published devices of a driver, compares them to what the driver would publish now, and then publishes/unpublishes the devices as needed. diff --git a/src/system/kernel/elf.cpp b/src/system/kernel/elf.cpp index 2ed0240787..544fb5a8df 100644 --- a/src/system/kernel/elf.cpp +++ b/src/system/kernel/elf.cpp @@ -53,6 +53,8 @@ #endif +namespace { + #define IMAGE_HASH_SIZE 16 struct ImageHashDefinition { @@ -77,6 +79,9 @@ struct ImageHashDefinition { typedef BOpenHashTable ImageHash; +} // namespace + + static ImageHash *sImagesHash; static struct elf_image_info *sKernelImage = NULL; diff --git a/src/system/kernel/fs/rootfs.cpp b/src/system/kernel/fs/rootfs.cpp index 5bfb782fa7..2dbd5b1112 100644 --- a/src/system/kernel/fs/rootfs.cpp +++ b/src/system/kernel/fs/rootfs.cpp @@ -46,6 +46,8 @@ #endif +namespace { + struct rootfs_stream { mode_t type; struct stream_dir { @@ -124,11 +126,13 @@ enum { ITERATION_STATE_BEGIN = ITERATION_STATE_DOT, }; -// extern and in a private namespace only to make forward declaration possible -namespace { - extern fs_volume_ops sVolumeOps; - extern fs_vnode_ops sVnodeOps; -} + +// extern only to make forward declaration possible +extern fs_volume_ops sVolumeOps; +extern fs_vnode_ops sVnodeOps; + +} // namespace + #define ROOTFS_HASH_SIZE 16 diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 963eb371cc..feb3044016 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -111,11 +111,6 @@ const static size_t kMaxPathLength = 65536; // on PATH_MAX -struct vnode_hash_key { - dev_t device; - ino_t vnode; -}; - typedef DoublyLinkedList VnodeList; /*! \brief Structure to manage a mounted file system @@ -171,6 +166,9 @@ struct fs_mount { bool owns_file_device; }; + +namespace { + struct advisory_lock : public DoublyLinkedListLinkImpl { list_link link; team_id team; @@ -182,6 +180,9 @@ struct advisory_lock : public DoublyLinkedListLinkImpl { typedef DoublyLinkedList LockList; +} // namespace + + struct advisory_locking { sem_id lock; sem_id wait_sem; @@ -251,6 +252,13 @@ static rw_lock sVnodeLock = RW_LOCK_INITIALIZER("vfs_vnode_lock"); static mutex sIOContextRootLock = MUTEX_INITIALIZER("io_context::root lock"); +namespace { + +struct vnode_hash_key { + dev_t device; + ino_t vnode; +}; + struct VnodeHash { typedef vnode_hash_key KeyType; typedef struct vnode ValueType; @@ -311,6 +319,8 @@ struct MountHash { typedef BOpenHashTable MountTable; +} // namespace + #define VNODE_HASH_TABLE_SIZE 1024 static VnodeTable* sVnodeTable; @@ -520,7 +530,8 @@ static struct fd_ops sQueryOps = { }; -// VNodePutter +namespace { + class VNodePutter { public: VNodePutter(struct vnode* vnode = NULL) : fVNode(vnode) {} @@ -597,6 +608,8 @@ private: bool fKernel; }; +} // namespace + #if VFS_PAGES_IO_TRACING diff --git a/src/system/kernel/image.cpp b/src/system/kernel/image.cpp index bb89b208b3..58526c0090 100644 --- a/src/system/kernel/image.cpp +++ b/src/system/kernel/image.cpp @@ -33,6 +33,8 @@ #define ADD_DEBUGGER_COMMANDS +namespace { + struct ImageTableDefinition { typedef image_id KeyType; typedef struct image ValueType; @@ -68,6 +70,8 @@ public: } }; +} // namespace + static image_id sNextImageID = 1; static mutex sImageMutex = MUTEX_INITIALIZER("image"); diff --git a/src/system/kernel/module.cpp b/src/system/kernel/module.cpp index af601e2d56..829c2513be 100644 --- a/src/system/kernel/module.cpp +++ b/src/system/kernel/module.cpp @@ -275,45 +275,6 @@ private: NotificationList fNotifications; }; -} // namespace Module - -using namespace Module; - -/* These are the standard base paths where we start to look for modules - * to load. Order is important, the last entry here will be searched - * first. - */ -static const directory_which kModulePaths[] = { - B_BEOS_ADDONS_DIRECTORY, - B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY, - B_USER_ADDONS_DIRECTORY, - B_USER_NONPACKAGED_ADDONS_DIRECTORY, -}; - -static const uint32 kNumModulePaths = sizeof(kModulePaths) - / sizeof(kModulePaths[0]); -static const uint32 kFirstNonSystemModulePath = 1; - - -static ModuleNotificationService sModuleNotificationService; -static bool sDisableUserAddOns = false; - -/* Locking scheme: There is a global lock only; having several locks - makes trouble if dependent modules get loaded concurrently -> - they have to wait for each other, i.e. we need one lock per module; - also we must detect circular references during init and not dead-lock. - - Reference counting: get_module() increments the ref count of a module, - put_module() decrements it. When a B_KEEP_LOADED module is initialized - the ref count is incremented once more, so it never gets - uninitialized/unloaded. A referenced module, unless it's built-in, has a - non-null module_image and owns a reference to the image. When the last - module reference is put, the image's reference is released and module_image - zeroed (as long as the boot volume has not been mounted, it is not zeroed). - An unreferenced module image is unloaded (when the boot volume is mounted). -*/ -static recursive_lock sModulesLock; - struct ModuleHash { typedef const char* KeyType; @@ -364,6 +325,45 @@ struct ImageHash { typedef BOpenHashTable ImageTable; +} // namespace Module + +using namespace Module; + +/* These are the standard base paths where we start to look for modules + * to load. Order is important, the last entry here will be searched + * first. + */ +static const directory_which kModulePaths[] = { + B_BEOS_ADDONS_DIRECTORY, + B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY, + B_USER_ADDONS_DIRECTORY, + B_USER_NONPACKAGED_ADDONS_DIRECTORY, +}; + +static const uint32 kNumModulePaths = sizeof(kModulePaths) + / sizeof(kModulePaths[0]); +static const uint32 kFirstNonSystemModulePath = 1; + + +static ModuleNotificationService sModuleNotificationService; +static bool sDisableUserAddOns = false; + +/* Locking scheme: There is a global lock only; having several locks + makes trouble if dependent modules get loaded concurrently -> + they have to wait for each other, i.e. we need one lock per module; + also we must detect circular references during init and not dead-lock. + + Reference counting: get_module() increments the ref count of a module, + put_module() decrements it. When a B_KEEP_LOADED module is initialized + the ref count is incremented once more, so it never gets + uninitialized/unloaded. A referenced module, unless it's built-in, has a + non-null module_image and owns a reference to the image. When the last + module reference is put, the image's reference is released and module_image + zeroed (as long as the boot volume has not been mounted, it is not zeroed). + An unreferenced module image is unloaded (when the boot volume is mounted). +*/ +static recursive_lock sModulesLock; + /* We store the loaded modules by directory path, and all known modules * by module name in a hash table for quick access diff --git a/src/system/kernel/port.cpp b/src/system/kernel/port.cpp index 278fc924f7..e9dff1780b 100644 --- a/src/system/kernel/port.cpp +++ b/src/system/kernel/port.cpp @@ -86,11 +86,7 @@ // has a reference to a deleted port. -struct port_message; - - -static void put_port_message(port_message* message); - +namespace { struct port_message : DoublyLinkedListLinkImpl { int32 code; @@ -103,6 +99,13 @@ struct port_message : DoublyLinkedListLinkImpl { typedef DoublyLinkedList MessageList; +} // namespace + + +static void put_port_message(port_message* message); + + +namespace { struct Port : public KernelReferenceable { enum State { @@ -233,6 +236,8 @@ public: void Notify(uint32 opcode, port_id team); }; +} // namespace + // #pragma mark - tracing diff --git a/src/system/kernel/posix/realtime_sem.cpp b/src/system/kernel/posix/realtime_sem.cpp index c6442ab020..4bd66525b6 100644 --- a/src/system/kernel/posix/realtime_sem.cpp +++ b/src/system/kernel/posix/realtime_sem.cpp @@ -24,6 +24,8 @@ #include +namespace { + class SemInfo { public: SemInfo() @@ -364,6 +366,8 @@ struct TeamSemHashDefinition { } }; +} // namespace + struct realtime_sem_context { realtime_sem_context() diff --git a/src/system/kernel/posix/xsi_message_queue.cpp b/src/system/kernel/posix/xsi_message_queue.cpp index 00046cb906..b2807ab156 100644 --- a/src/system/kernel/posix/xsi_message_queue.cpp +++ b/src/system/kernel/posix/xsi_message_queue.cpp @@ -33,6 +33,9 @@ # define TRACE_ERROR(x) dprintf x #endif + +namespace { + // Queue for holding blocked threads struct queued_thread : DoublyLinkedListLinkImpl { queued_thread(Thread *_thread, int32 _message_length) @@ -374,6 +377,9 @@ struct IpcHashTableDefinition { } }; +} // namespace + + // Arbitrary limits #define MAX_XSI_MESSAGE 4096 #define MAX_XSI_MESSAGE_QUEUE 1024 diff --git a/src/system/kernel/posix/xsi_semaphore.cpp b/src/system/kernel/posix/xsi_semaphore.cpp index 1cf30cd47f..918d58a8f5 100644 --- a/src/system/kernel/posix/xsi_semaphore.cpp +++ b/src/system/kernel/posix/xsi_semaphore.cpp @@ -34,6 +34,9 @@ # define TRACE_ERROR(x) dprintf x #endif + +namespace { + // Queue for holding blocked threads struct queued_thread : DoublyLinkedListLinkImpl { queued_thread(Thread *thread, int32 count) @@ -72,6 +75,10 @@ typedef DoublyLinkedList UndoList; typedef DoublyLinkedList > TeamList; +} // namespace + + +// Forward declared in global namespace. struct xsi_sem_context { xsi_sem_context() { @@ -87,6 +94,9 @@ struct xsi_sem_context { mutex lock; }; + +namespace { + // Xsi semaphore definition class XsiSemaphore { public: @@ -621,6 +631,9 @@ struct IpcHashTableDefinition { } }; +} // namespace + + // Arbitrary limit #define MAX_XSI_SEMAPHORE 4096 #define MAX_XSI_SEMAPHORE_SET 2048 diff --git a/src/system/kernel/vm/VMAddressSpace.cpp b/src/system/kernel/vm/VMAddressSpace.cpp index cb61239f4d..7c58a05e56 100644 --- a/src/system/kernel/vm/VMAddressSpace.cpp +++ b/src/system/kernel/vm/VMAddressSpace.cpp @@ -42,6 +42,8 @@ // #pragma mark - AddressSpaceHashDefinition +namespace { + struct AddressSpaceHashDefinition { typedef team_id KeyType; typedef VMAddressSpace ValueType; @@ -69,6 +71,9 @@ struct AddressSpaceHashDefinition { typedef BOpenHashTable AddressSpaceTable; +} // namespace + + static AddressSpaceTable sAddressSpaceTable; static rw_lock sAddressSpaceTableLock; diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 8bb5167b0c..553f937ced 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -73,6 +73,8 @@ #endif +namespace { + class AreaCacheLocking { public: inline bool Lock(VMCache* lockable) @@ -229,6 +231,8 @@ private: VMCache* fBottomCache; }; +} // namespace + // The memory reserve an allocation of the certain priority must not touch. static const size_t kMemoryReserveForPriority[] = { From ba307a12db6daf4930149a3e86dccb72a7b7d392 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 8 Nov 2015 21:22:21 +0100 Subject: [PATCH 144/370] vfs: Cleanup: Move functions around for more logical grouping. Move static internal functions out of the API functions block and drop their vfs_ prefix and move an API function into the API functions block. --- src/system/kernel/fs/vfs.cpp | 188 +++++++++++++++++------------------ 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index feb3044016..7e23512c8f 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -1968,51 +1968,6 @@ get_root_vnode(bool kernel) } -/*! \brief Resolves a vnode to the vnode it is covered by, if any. - - Given an arbitrary vnode (identified by mount and node ID), the function - checks, whether the vnode is covered by another vnode. If it is, the - function returns the mount and node ID of the covering vnode. Otherwise - it simply returns the supplied mount and node ID. - - In case of error (e.g. the supplied node could not be found) the variables - for storing the resolved mount and node ID remain untouched and an error - code is returned. - - \param mountID The mount ID of the vnode in question. - \param nodeID The node ID of the vnode in question. - \param resolvedMountID Pointer to storage for the resolved mount ID. - \param resolvedNodeID Pointer to storage for the resolved node ID. - \return - - \c B_OK, if everything went fine, - - another error code, if something went wrong. -*/ -status_t -vfs_resolve_vnode_to_covering_vnode(dev_t mountID, ino_t nodeID, - dev_t* resolvedMountID, ino_t* resolvedNodeID) -{ - // get the node - struct vnode* node; - status_t error = get_vnode(mountID, nodeID, &node, true, false); - if (error != B_OK) - return error; - - // resolve the node - if (Vnode* coveringNode = get_covering_vnode(node)) { - put_vnode(node); - node = coveringNode; - } - - // set the return values - *resolvedMountID = node->device; - *resolvedNodeID = node->id; - - put_vnode(node); - - return B_OK; -} - - /*! \brief Gets the directory path and leaf name for a given path. The supplied \a path is transformed to refer to the directory part of @@ -3613,6 +3568,60 @@ is_user_in_group(gid_t gid) } +static status_t +free_io_context(io_context* context) +{ + uint32 i; + + TIOC(FreeIOContext(context)); + + if (context->root) + put_vnode(context->root); + + if (context->cwd) + put_vnode(context->cwd); + + mutex_lock(&context->io_mutex); + + for (i = 0; i < context->table_size; i++) { + if (struct file_descriptor* descriptor = context->fds[i]) { + close_fd(descriptor); + put_fd(descriptor); + } + } + + mutex_destroy(&context->io_mutex); + + remove_node_monitors(context); + free(context->fds); + free(context); + + return B_OK; +} + + +static status_t +resize_monitor_table(struct io_context* context, const int newSize) +{ + int status = B_OK; + + if (newSize <= 0 || newSize > MAX_NODE_MONITORS) + return B_BAD_VALUE; + + mutex_lock(&context->io_mutex); + + if ((size_t)newSize < context->num_monitors) { + status = B_BUSY; + goto out; + } + context->max_monitors = newSize; + +out: + mutex_unlock(&context->io_mutex); + return status; +} + + // #pragma mark - public API for file systems @@ -4913,38 +4922,6 @@ vfs_new_io_context(io_context* parentContext, bool purgeCloseOnExec) } -static status_t -vfs_free_io_context(io_context* context) -{ - uint32 i; - - TIOC(FreeIOContext(context)); - - if (context->root) - put_vnode(context->root); - - if (context->cwd) - put_vnode(context->cwd); - - mutex_lock(&context->io_mutex); - - for (i = 0; i < context->table_size; i++) { - if (struct file_descriptor* descriptor = context->fds[i]) { - close_fd(descriptor); - put_fd(descriptor); - } - } - - mutex_destroy(&context->io_mutex); - - remove_node_monitors(context); - free(context->fds); - free(context); - - return B_OK; -} - - void vfs_get_io_context(io_context* context) { @@ -4956,7 +4933,7 @@ void vfs_put_io_context(io_context* context) { if (atomic_add(&context->ref_count, -1) == 1) - vfs_free_io_context(context); + free_io_context(context); } @@ -5023,25 +5000,48 @@ vfs_resize_fd_table(struct io_context* context, uint32 newSize) } -static status_t -vfs_resize_monitor_table(struct io_context* context, const int newSize) +/*! \brief Resolves a vnode to the vnode it is covered by, if any. + + Given an arbitrary vnode (identified by mount and node ID), the function + checks, whether the vnode is covered by another vnode. If it is, the + function returns the mount and node ID of the covering vnode. Otherwise + it simply returns the supplied mount and node ID. + + In case of error (e.g. the supplied node could not be found) the variables + for storing the resolved mount and node ID remain untouched and an error + code is returned. + + \param mountID The mount ID of the vnode in question. + \param nodeID The node ID of the vnode in question. + \param resolvedMountID Pointer to storage for the resolved mount ID. + \param resolvedNodeID Pointer to storage for the resolved node ID. + \return + - \c B_OK, if everything went fine, + - another error code, if something went wrong. +*/ +status_t +vfs_resolve_vnode_to_covering_vnode(dev_t mountID, ino_t nodeID, + dev_t* resolvedMountID, ino_t* resolvedNodeID) { - int status = B_OK; + // get the node + struct vnode* node; + status_t error = get_vnode(mountID, nodeID, &node, true, false); + if (error != B_OK) + return error; - if (newSize <= 0 || newSize > MAX_NODE_MONITORS) - return B_BAD_VALUE; - - mutex_lock(&context->io_mutex); - - if ((size_t)newSize < context->num_monitors) { - status = B_BUSY; - goto out; + // resolve the node + if (Vnode* coveringNode = get_covering_vnode(node)) { + put_vnode(node); + node = coveringNode; } - context->max_monitors = newSize; -out: - mutex_unlock(&context->io_mutex); - return status; + // set the return values + *resolvedMountID = node->device; + *resolvedNodeID = node->id; + + put_vnode(node); + + return B_OK; } @@ -5160,7 +5160,7 @@ vfs_setrlimit(int resource, const struct rlimit* rlp) && rlp->rlim_max != MAX_NODE_MONITORS) return B_NOT_ALLOWED; - return vfs_resize_monitor_table(get_current_io_context(false), + return resize_monitor_table(get_current_io_context(false), rlp->rlim_cur); default: From 6c32f50a645c8bbb774ae2cd4f38779dd91c1d2e Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Sun, 8 Nov 2015 23:43:38 +0100 Subject: [PATCH 145/370] BCertificate: fixup the API * Add an operator== and a copy constructor * Make the getters const so they are easier to use --- headers/os/net/Certificate.h | 24 +++---- src/kits/network/libnetapi/Certificate.cpp | 66 ++++++++++++++----- .../network/libnetapi/CertificatePrivate.h | 1 + 3 files changed, 61 insertions(+), 30 deletions(-) diff --git a/headers/os/net/Certificate.h b/headers/os/net/Certificate.h index 7be21b32a1..fe064520d8 100644 --- a/headers/os/net/Certificate.h +++ b/headers/os/net/Certificate.h @@ -12,30 +12,30 @@ class BCertificate { public: + BCertificate(const BCertificate& other); ~BCertificate(); - int Version(); + int Version() const; - time_t StartDate(); - time_t ExpirationDate(); + time_t StartDate() const; + time_t ExpirationDate() const; - bool IsValidAuthority(); - bool IsSelfSigned(); + bool IsValidAuthority() const; + bool IsSelfSigned() const; - BString Issuer(); - BString Subject(); - BString SignatureAlgorithm(); + BString Issuer() const; + BString Subject() const; + BString SignatureAlgorithm() const; - BString String(); + BString String() const; + + bool operator==(const BCertificate& other); private: friend class BSecureSocket::Private; class Private; BCertificate(Private* data); - BCertificate(const BCertificate& other); - // copy-construction not allowed - Private* fPrivate; }; diff --git a/src/kits/network/libnetapi/Certificate.cpp b/src/kits/network/libnetapi/Certificate.cpp index 290a9bb07c..f82decf6f7 100644 --- a/src/kits/network/libnetapi/Certificate.cpp +++ b/src/kits/network/libnetapi/Certificate.cpp @@ -58,6 +58,12 @@ BCertificate::BCertificate(Private* data) } +BCertificate::BCertificate(const BCertificate& other) +{ + fPrivate = newBCertificate::Private(other.fPrivate); +} + + BCertificate::~BCertificate() { delete fPrivate; @@ -65,42 +71,42 @@ BCertificate::~BCertificate() int -BCertificate::Version() +BCertificate::Version() const { return X509_get_version(fPrivate->fX509) + 1; } time_t -BCertificate::StartDate() +BCertificate::StartDate() const { return parse_ASN1(X509_get_notBefore(fPrivate->fX509)); } time_t -BCertificate::ExpirationDate() +BCertificate::ExpirationDate() const { return parse_ASN1(X509_get_notAfter(fPrivate->fX509)); } bool -BCertificate::IsValidAuthority() +BCertificate::IsValidAuthority() const { return X509_check_ca(fPrivate->fX509) > 0; } bool -BCertificate::IsSelfSigned() +BCertificate::IsSelfSigned() const { return X509_check_issued(fPrivate->fX509, fPrivate->fX509) == X509_V_OK; } BString -BCertificate::Issuer() +BCertificate::Issuer() const { X509_NAME* name = X509_get_issuer_name(fPrivate->fX509); return decode_X509_NAME(name); @@ -108,7 +114,7 @@ BCertificate::Issuer() BString -BCertificate::Subject() +BCertificate::Subject() const { X509_NAME* name = X509_get_subject_name(fPrivate->fX509); return decode_X509_NAME(name); @@ -116,7 +122,7 @@ BCertificate::Subject() BString -BCertificate::SignatureAlgorithm() +BCertificate::SignatureAlgorithm() const { int algorithmIdentifier = OBJ_obj2nid( fPrivate->fX509->cert_info->key->algor->algorithm); @@ -130,7 +136,7 @@ BCertificate::SignatureAlgorithm() BString -BCertificate::String() +BCertificate::String() const { BIO *buffer = BIO_new(BIO_s_mem()); X509_print_ex(buffer, fPrivate->fX509, XN_FLAG_COMPAT, X509_FLAG_COMPAT); @@ -144,18 +150,36 @@ BCertificate::String() } +bool +BCertificate::operator==(const BCertificate& other) +{ + return X509_cmp(fPrivate.fX509, other.fPrivate.fX509) == 0; +} + + // #pragma mark - BCertificate::Private BCertificate::Private::Private(X509* data) - : fX509(data) + : fX509(X509_dup(data)) { } +BCertificate::Private::~Private() +{ + sk_X509_pop_free(chain, X509_free) +} + + #else +BCertificate::BCertificate(const BCertificate& other) +{ +} + + BCertificate::BCertificate(Private* data) { } @@ -167,59 +191,65 @@ BCertificate::~BCertificate() time_t -BCertificate::StartDate() +BCertificate::StartDate() const { return B_NOT_SUPPORTED; } time_t -BCertificate::ExpirationDate() +BCertificate::ExpirationDate() const { return B_NOT_SUPPORTED; } bool -BCertificate::IsValidAuthority() +BCertificate::IsValidAuthority() const { return false; } int -BCertificate::Version() +BCertificate::Version() const { return B_NOT_SUPPORTED; } BString -BCertificate::Issuer() +BCertificate::Issuer() const { return BString(); } BString -BCertificate::Subject() +BCertificate::Subject() const { return BString(); } BString -BCertificate::SignatureAlgorithm() +BCertificate::SignatureAlgorithm() const { return BString(); } BString -BCertificate::String() +BCertificate::String() const { return BString(); } +bool +BCertificate::operator==(const BCertificate& other) +{ + return false; +} + #endif diff --git a/src/kits/network/libnetapi/CertificatePrivate.h b/src/kits/network/libnetapi/CertificatePrivate.h index d75495c218..54e13011f4 100644 --- a/src/kits/network/libnetapi/CertificatePrivate.h +++ b/src/kits/network/libnetapi/CertificatePrivate.h @@ -13,6 +13,7 @@ class BCertificate::Private { public: Private(X509* data); + ~Private(); public: X509* fX509; From f26dbfe79bf5d123efc6caf77a413ca4c9de2aee Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Mon, 9 Nov 2015 00:15:19 +0100 Subject: [PATCH 146/370] BCertificate: build fix. --- src/kits/network/libnetapi/Certificate.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/kits/network/libnetapi/Certificate.cpp b/src/kits/network/libnetapi/Certificate.cpp index f82decf6f7..ac2296b049 100644 --- a/src/kits/network/libnetapi/Certificate.cpp +++ b/src/kits/network/libnetapi/Certificate.cpp @@ -60,7 +60,7 @@ BCertificate::BCertificate(Private* data) BCertificate::BCertificate(const BCertificate& other) { - fPrivate = newBCertificate::Private(other.fPrivate); + fPrivate = new(std::nothrow) BCertificate::Private(other.fPrivate); } @@ -153,7 +153,7 @@ BCertificate::String() const bool BCertificate::operator==(const BCertificate& other) { - return X509_cmp(fPrivate.fX509, other.fPrivate.fX509) == 0; + return X509_cmp(fPrivate->fX509, other.fPrivate->fX509) == 0; } @@ -168,7 +168,7 @@ BCertificate::Private::Private(X509* data) BCertificate::Private::~Private() { - sk_X509_pop_free(chain, X509_free) + sk_X509_pop_free(fX509, X509_free); } From 4849ab6c8b4d9443544cfffe108d6ca26660127d Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Mon, 9 Nov 2015 10:46:58 +0100 Subject: [PATCH 147/370] BHttpRequest: add SSL certificate exception management. When an HTTPS request uses an SSL certificate that OpenSSL considers untrusted, and the user decides to continue anyway, add the certificate to an exception list. Match certificates against this list and don't ask the user again if they are already there. Fixes #12004. Thanks to markh for the initial patch and peeking into the WebKit code! --- headers/os/net/Certificate.h | 2 +- headers/os/net/UrlContext.h | 7 ++++- src/kits/network/libnetapi/Certificate.cpp | 8 ++--- src/kits/network/libnetapi/HttpRequest.cpp | 13 +++++--- src/kits/network/libnetapi/UrlContext.cpp | 36 +++++++++++++++++++++- 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/headers/os/net/Certificate.h b/headers/os/net/Certificate.h index fe064520d8..cb3bee4ee0 100644 --- a/headers/os/net/Certificate.h +++ b/headers/os/net/Certificate.h @@ -29,7 +29,7 @@ public: BString String() const; - bool operator==(const BCertificate& other); + bool operator==(const BCertificate& other) const; private: friend class BSecureSocket::Private; diff --git a/headers/os/net/UrlContext.h b/headers/os/net/UrlContext.h index d561ef5115..514c523ea4 100644 --- a/headers/os/net/UrlContext.h +++ b/headers/os/net/UrlContext.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2014 Haiku Inc. All rights reserved. + * Copyright 2010-2015 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. */ @@ -8,6 +8,7 @@ #define _B_URL_CONTEXT_H_ +#include #include #include #include @@ -30,6 +31,7 @@ public: void AddAuthentication(const BUrl& url, const BHttpAuthentication& authentication); void SetProxy(BString host, uint16 port); + void AddCertificateException(const BCertificate& certificate); // Context accessors BNetworkCookieJar& GetCookieJar(); @@ -37,12 +39,15 @@ public: bool UseProxy(); BString GetProxyHost(); uint16 GetProxyPort(); + bool HasCertificateException(const BCertificate& certificate); private: BNetworkCookieJar fCookieJar; typedef BPrivate::SynchronizedHashMap BHttpAuthenticationMap; BHttpAuthenticationMap* fAuthenticationMap; + typedef BObjectList BCertificateSet; + BCertificateSet fCertificates; BString fProxyHost; uint16 fProxyPort; diff --git a/src/kits/network/libnetapi/Certificate.cpp b/src/kits/network/libnetapi/Certificate.cpp index ac2296b049..957790ddb9 100644 --- a/src/kits/network/libnetapi/Certificate.cpp +++ b/src/kits/network/libnetapi/Certificate.cpp @@ -60,7 +60,7 @@ BCertificate::BCertificate(Private* data) BCertificate::BCertificate(const BCertificate& other) { - fPrivate = new(std::nothrow) BCertificate::Private(other.fPrivate); + fPrivate = new(std::nothrow) BCertificate::Private(other.fPrivate->fX509); } @@ -151,7 +151,7 @@ BCertificate::String() const bool -BCertificate::operator==(const BCertificate& other) +BCertificate::operator==(const BCertificate& other) const { return X509_cmp(fPrivate->fX509, other.fPrivate->fX509) == 0; } @@ -168,7 +168,7 @@ BCertificate::Private::Private(X509* data) BCertificate::Private::~Private() { - sk_X509_pop_free(fX509, X509_free); + X509_free(fX509); } @@ -247,7 +247,7 @@ BCertificate::String() const bool -BCertificate::operator==(const BCertificate& other) +BCertificate::operator==(const BCertificate& other) const { return false; } diff --git a/src/kits/network/libnetapi/HttpRequest.cpp b/src/kits/network/libnetapi/HttpRequest.cpp index 972c5ccbea..3c3625007f 100644 --- a/src/kits/network/libnetapi/HttpRequest.cpp +++ b/src/kits/network/libnetapi/HttpRequest.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2010-2014 Haiku Inc. All rights reserved. + * Copyright 2010-2015 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -1083,9 +1083,14 @@ bool BHttpRequest::_CertificateVerificationFailed(BCertificate& certificate, const char* message) { - if (fListener != NULL) { - return fListener->CertificateVerificationFailed(this, certificate, - message); + if (fContext->HasCertificateException(certificate)) + return true; + + if (fListener != NULL + && fListener->CertificateVerificationFailed(this, certificate, message)) { + // User asked us to continue anyway, let's add a temporary exception for this certificate + fContext->AddCertificateException(certificate); + return true; } return false; diff --git a/src/kits/network/libnetapi/UrlContext.cpp b/src/kits/network/libnetapi/UrlContext.cpp index 6a9f6e1028..4a7970a664 100644 --- a/src/kits/network/libnetapi/UrlContext.cpp +++ b/src/kits/network/libnetapi/UrlContext.cpp @@ -1,9 +1,10 @@ /* - * Copyright 2010 Haiku Inc. All rights reserved. + * Copyright 2010-2015 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Christophe Huriaux, c.huriaux@gmail.com + * Adrien Destugues, pulkomandy@pulkomandy.tk */ @@ -19,6 +20,7 @@ BUrlContext::BUrlContext() : fCookieJar(), fAuthenticationMap(NULL), + fCertificates(20, true), fProxyHost(), fProxyPort(0) { @@ -84,6 +86,16 @@ BUrlContext::SetProxy(BString host, uint16 port) } +void +BUrlContext::AddCertificateException(const BCertificate& certificate) +{ + BCertificate* copy = new(std::nothrow) BCertificate(certificate); + if (copy != NULL) { + fCertificates.AddItem(copy); + } +} + + // #pragma mark Context accessors @@ -133,3 +145,25 @@ BUrlContext::GetProxyPort() { return fProxyPort; } + + +bool +BUrlContext::HasCertificateException(const BCertificate& certificate) +{ + struct Equals: public UnaryPredicate { + Equals(const BCertificate& itemToMatch) + : + fItemToMatch(itemToMatch) + { + } + + int operator()(const BCertificate* item) const + { + return *item == fItemToMatch; + } + + const BCertificate& fItemToMatch; + } comparator(certificate); + + return fCertificates.FindIf(comparator) != NULL; +} From 55af491fde46ea60a77a4ea6c37d80f500723729 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Mon, 9 Nov 2015 11:13:00 +0100 Subject: [PATCH 148/370] BUrlContext: fix logic reversal in certificate comparison The Predicate for BObjectList::FindIf must actually be a difference operator, and return 0 if there is a match. --- src/kits/network/libnetapi/UrlContext.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/kits/network/libnetapi/UrlContext.cpp b/src/kits/network/libnetapi/UrlContext.cpp index 4a7970a664..6e7ec48c0e 100644 --- a/src/kits/network/libnetapi/UrlContext.cpp +++ b/src/kits/network/libnetapi/UrlContext.cpp @@ -159,7 +159,8 @@ BUrlContext::HasCertificateException(const BCertificate& certificate) int operator()(const BCertificate* item) const { - return *item == fItemToMatch; + /* Must return 0 if there is a match! */ + return !(*item == fItemToMatch); } const BCertificate& fItemToMatch; From 3df0df95cd4f935e7cafbc3ac500d80a3710a4b1 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Mon, 9 Nov 2015 12:58:51 +0100 Subject: [PATCH 149/370] get_package_dependencies: catch and report exceptions The package kit uses exceptions for error handling, but this tool didn't catch them so all we got in case of error is "Abort" on the error output. Now, the exceptions are caught and reported with the complete error message. --- .../get_package_dependencies/get_package_dependencies.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/tools/get_package_dependencies/get_package_dependencies.cpp b/src/tools/get_package_dependencies/get_package_dependencies.cpp index 22bf9eb459..63d54398ba 100644 --- a/src/tools/get_package_dependencies/get_package_dependencies.cpp +++ b/src/tools/get_package_dependencies/get_package_dependencies.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -83,12 +84,13 @@ main(int argc, const char* const* argv) // add the "installed" repository with the given packages BSolverRepository installedRepository; - { - BRepositoryBuilder installedRepositoryBuilder(installedRepository, - "installed"); + try { + BRepositoryBuilder installedRepositoryBuilder(installedRepository, "installed"); for (int i = 0; i < packageCount; i++) installedRepositoryBuilder.AddPackage(packages[i]); installedRepositoryBuilder.AddToSolver(solver, true); + } catch (BFatalErrorException e) { + DIE(B_OK, "%s", e.Details().String()); } // add external repositories From 0e2547a80df4768e9098c4ee110e0cd276cf6ecb Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Mon, 9 Nov 2015 13:51:11 +0100 Subject: [PATCH 150/370] Import lib/Headers from Clang --- headers/clang/Intrin.h | 958 ++ headers/clang/__stddef_max_align_t.h | 43 + headers/clang/__wmmintrin_aes.h | 66 + headers/clang/__wmmintrin_pclmul.h | 30 + headers/clang/adxintrin.h | 86 + headers/clang/altivec.h | 13919 +++++++++++++++++++++++++ headers/clang/ammintrin.h | 209 + headers/clang/arm_acle.h | 304 + headers/clang/avx2intrin.h | 1258 +++ headers/clang/avx512bwintrin.h | 1542 +++ headers/clang/avx512cdintrin.h | 131 + headers/clang/avx512dqintrin.h | 778 ++ headers/clang/avx512erintrin.h | 285 + headers/clang/avx512fintrin.h | 3084 ++++++ headers/clang/avx512vlbwintrin.h | 2336 +++++ headers/clang/avx512vldqintrin.h | 953 ++ headers/clang/avx512vlintrin.h | 4606 ++++++++ headers/clang/avxintrin.h | 1330 +++ headers/clang/bmi2intrin.h | 95 + headers/clang/bmiintrin.h | 149 + headers/clang/cpuid.h | 209 + headers/clang/cuda_builtin_vars.h | 110 + headers/clang/emmintrin.h | 1491 +++ headers/clang/f16cintrin.h | 59 + headers/clang/float.h | 124 + headers/clang/fma4intrin.h | 230 + headers/clang/fmaintrin.h | 228 + headers/clang/fxsrintrin.h | 55 + headers/clang/htmintrin.h | 226 + headers/clang/htmxlintrin.h | 363 + headers/clang/ia32intrin.h | 101 + headers/clang/immintrin.h | 159 + headers/clang/inttypes.h | 102 + headers/clang/iso646.h | 43 + headers/clang/limits.h | 118 + headers/clang/lzcntintrin.h | 68 + headers/clang/mm3dnow.h | 171 + headers/clang/mm_malloc.h | 75 + headers/clang/mmintrin.h | 501 + headers/clang/module.modulemap | 171 + headers/clang/nmmintrin.h | 30 + headers/clang/pmmintrin.h | 116 + headers/clang/popcntintrin.h | 46 + headers/clang/prfchwintrin.h | 45 + headers/clang/rdseedintrin.h | 56 + headers/clang/rtmintrin.h | 59 + headers/clang/s390intrin.h | 39 + headers/clang/shaintrin.h | 75 + headers/clang/smmintrin.h | 491 + headers/clang/stdalign.h | 35 + headers/clang/stdarg.h | 52 + headers/clang/stdatomic.h | 190 + headers/clang/stdbool.h | 44 + headers/clang/stddef.h | 137 + headers/clang/stdint.h | 707 ++ headers/clang/stdnoreturn.h | 30 + headers/clang/tbmintrin.h | 150 + headers/clang/tgmath.h | 1374 +++ headers/clang/tmmintrin.h | 224 + headers/clang/unwind.h | 282 + headers/clang/vadefs.h | 65 + headers/clang/varargs.h | 26 + headers/clang/vecintrin.h | 8946 ++++++++++++++++ headers/clang/wmmintrin.h | 33 + headers/clang/x86intrin.h | 57 + headers/clang/xmmintrin.h | 1013 ++ headers/clang/xopintrin.h | 803 ++ headers/clang/xsavecintrin.h | 48 + headers/clang/xsaveintrin.h | 58 + headers/clang/xsaveoptintrin.h | 48 + headers/clang/xsavesintrin.h | 58 + headers/clang/xtestintrin.h | 41 + 72 files changed, 52144 insertions(+) create mode 100644 headers/clang/Intrin.h create mode 100644 headers/clang/__stddef_max_align_t.h create mode 100644 headers/clang/__wmmintrin_aes.h create mode 100644 headers/clang/__wmmintrin_pclmul.h create mode 100644 headers/clang/adxintrin.h create mode 100644 headers/clang/altivec.h create mode 100644 headers/clang/ammintrin.h create mode 100644 headers/clang/arm_acle.h create mode 100644 headers/clang/avx2intrin.h create mode 100644 headers/clang/avx512bwintrin.h create mode 100644 headers/clang/avx512cdintrin.h create mode 100644 headers/clang/avx512dqintrin.h create mode 100644 headers/clang/avx512erintrin.h create mode 100644 headers/clang/avx512fintrin.h create mode 100644 headers/clang/avx512vlbwintrin.h create mode 100644 headers/clang/avx512vldqintrin.h create mode 100644 headers/clang/avx512vlintrin.h create mode 100644 headers/clang/avxintrin.h create mode 100644 headers/clang/bmi2intrin.h create mode 100644 headers/clang/bmiintrin.h create mode 100644 headers/clang/cpuid.h create mode 100644 headers/clang/cuda_builtin_vars.h create mode 100644 headers/clang/emmintrin.h create mode 100644 headers/clang/f16cintrin.h create mode 100644 headers/clang/float.h create mode 100644 headers/clang/fma4intrin.h create mode 100644 headers/clang/fmaintrin.h create mode 100644 headers/clang/fxsrintrin.h create mode 100644 headers/clang/htmintrin.h create mode 100644 headers/clang/htmxlintrin.h create mode 100644 headers/clang/ia32intrin.h create mode 100644 headers/clang/immintrin.h create mode 100644 headers/clang/inttypes.h create mode 100644 headers/clang/iso646.h create mode 100644 headers/clang/limits.h create mode 100644 headers/clang/lzcntintrin.h create mode 100644 headers/clang/mm3dnow.h create mode 100644 headers/clang/mm_malloc.h create mode 100644 headers/clang/mmintrin.h create mode 100644 headers/clang/module.modulemap create mode 100644 headers/clang/nmmintrin.h create mode 100644 headers/clang/pmmintrin.h create mode 100644 headers/clang/popcntintrin.h create mode 100644 headers/clang/prfchwintrin.h create mode 100644 headers/clang/rdseedintrin.h create mode 100644 headers/clang/rtmintrin.h create mode 100644 headers/clang/s390intrin.h create mode 100644 headers/clang/shaintrin.h create mode 100644 headers/clang/smmintrin.h create mode 100644 headers/clang/stdalign.h create mode 100644 headers/clang/stdarg.h create mode 100644 headers/clang/stdatomic.h create mode 100644 headers/clang/stdbool.h create mode 100644 headers/clang/stddef.h create mode 100644 headers/clang/stdint.h create mode 100644 headers/clang/stdnoreturn.h create mode 100644 headers/clang/tbmintrin.h create mode 100644 headers/clang/tgmath.h create mode 100644 headers/clang/tmmintrin.h create mode 100644 headers/clang/unwind.h create mode 100644 headers/clang/vadefs.h create mode 100644 headers/clang/varargs.h create mode 100644 headers/clang/vecintrin.h create mode 100644 headers/clang/wmmintrin.h create mode 100644 headers/clang/x86intrin.h create mode 100644 headers/clang/xmmintrin.h create mode 100644 headers/clang/xopintrin.h create mode 100644 headers/clang/xsavecintrin.h create mode 100644 headers/clang/xsaveintrin.h create mode 100644 headers/clang/xsaveoptintrin.h create mode 100644 headers/clang/xsavesintrin.h create mode 100644 headers/clang/xtestintrin.h diff --git a/headers/clang/Intrin.h b/headers/clang/Intrin.h new file mode 100644 index 0000000000..6c1d0d16ea --- /dev/null +++ b/headers/clang/Intrin.h @@ -0,0 +1,958 @@ +/* ===-------- Intrin.h ---------------------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +/* Only include this if we're compiling for the windows platform. */ +#ifndef _MSC_VER +#include_next +#else + +#ifndef __INTRIN_H +#define __INTRIN_H + +/* First include the standard intrinsics. */ +#if defined(__i386__) || defined(__x86_64__) +#include +#endif + +/* For the definition of jmp_buf. */ +#if __STDC_HOSTED__ +#include +#endif + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__MMX__) +/* And the random ones that aren't in those files. */ +__m64 _m_from_float(float); +float _m_to_float(__m64); +#endif + +/* Other assorted instruction intrinsics. */ +void __addfsbyte(unsigned long, unsigned char); +void __addfsdword(unsigned long, unsigned long); +void __addfsword(unsigned long, unsigned short); +void __code_seg(const char *); +static __inline__ +void __cpuid(int[4], int); +static __inline__ +void __cpuidex(int[4], int, int); +void __debugbreak(void); +__int64 __emul(int, int); +unsigned __int64 __emulu(unsigned int, unsigned int); +void __cdecl __fastfail(unsigned int); +unsigned int __getcallerseflags(void); +static __inline__ +void __halt(void); +unsigned char __inbyte(unsigned short); +void __inbytestring(unsigned short, unsigned char *, unsigned long); +void __incfsbyte(unsigned long); +void __incfsdword(unsigned long); +void __incfsword(unsigned long); +unsigned long __indword(unsigned short); +void __indwordstring(unsigned short, unsigned long *, unsigned long); +void __int2c(void); +void __invlpg(void *); +unsigned short __inword(unsigned short); +void __inwordstring(unsigned short, unsigned short *, unsigned long); +void __lidt(void *); +unsigned __int64 __ll_lshift(unsigned __int64, int); +__int64 __ll_rshift(__int64, int); +void __llwpcb(void *); +unsigned char __lwpins32(unsigned int, unsigned int, unsigned int); +void __lwpval32(unsigned int, unsigned int, unsigned int); +unsigned int __lzcnt(unsigned int); +unsigned short __lzcnt16(unsigned short); +static __inline__ +void __movsb(unsigned char *, unsigned char const *, size_t); +static __inline__ +void __movsd(unsigned long *, unsigned long const *, size_t); +static __inline__ +void __movsw(unsigned short *, unsigned short const *, size_t); +void __nop(void); +void __nvreg_restore_fence(void); +void __nvreg_save_fence(void); +void __outbyte(unsigned short, unsigned char); +void __outbytestring(unsigned short, unsigned char *, unsigned long); +void __outdword(unsigned short, unsigned long); +void __outdwordstring(unsigned short, unsigned long *, unsigned long); +void __outword(unsigned short, unsigned short); +void __outwordstring(unsigned short, unsigned short *, unsigned long); +static __inline__ +unsigned int __popcnt(unsigned int); +static __inline__ +unsigned short __popcnt16(unsigned short); +unsigned long __readcr0(void); +unsigned long __readcr2(void); +static __inline__ +unsigned long __readcr3(void); +unsigned long __readcr4(void); +unsigned long __readcr8(void); +unsigned int __readdr(unsigned int); +#ifdef __i386__ +static __inline__ +unsigned char __readfsbyte(unsigned long); +static __inline__ +unsigned long __readfsdword(unsigned long); +static __inline__ +unsigned __int64 __readfsqword(unsigned long); +static __inline__ +unsigned short __readfsword(unsigned long); +#endif +static __inline__ +unsigned __int64 __readmsr(unsigned long); +unsigned __int64 __readpmc(unsigned long); +unsigned long __segmentlimit(unsigned long); +void __sidt(void *); +void *__slwpcb(void); +static __inline__ +void __stosb(unsigned char *, unsigned char, size_t); +static __inline__ +void __stosd(unsigned long *, unsigned long, size_t); +static __inline__ +void __stosw(unsigned short *, unsigned short, size_t); +void __svm_clgi(void); +void __svm_invlpga(void *, int); +void __svm_skinit(int); +void __svm_stgi(void); +void __svm_vmload(size_t); +void __svm_vmrun(size_t); +void __svm_vmsave(size_t); +void __ud2(void); +unsigned __int64 __ull_rshift(unsigned __int64, int); +void __vmx_off(void); +void __vmx_vmptrst(unsigned __int64 *); +void __wbinvd(void); +void __writecr0(unsigned int); +static __inline__ +void __writecr3(unsigned int); +void __writecr4(unsigned int); +void __writecr8(unsigned int); +void __writedr(unsigned int, unsigned int); +void __writefsbyte(unsigned long, unsigned char); +void __writefsdword(unsigned long, unsigned long); +void __writefsqword(unsigned long, unsigned __int64); +void __writefsword(unsigned long, unsigned short); +void __writemsr(unsigned long, unsigned __int64); +static __inline__ +void *_AddressOfReturnAddress(void); +static __inline__ +unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask); +static __inline__ +unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask); +static __inline__ +unsigned char _bittest(long const *, long); +static __inline__ +unsigned char _bittestandcomplement(long *, long); +static __inline__ +unsigned char _bittestandreset(long *, long); +static __inline__ +unsigned char _bittestandset(long *, long); +unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64); +unsigned long __cdecl _byteswap_ulong(unsigned long); +unsigned short __cdecl _byteswap_ushort(unsigned short); +void __cdecl _disable(void); +void __cdecl _enable(void); +long _InterlockedAddLargeStatistic(__int64 volatile *_Addend, long _Value); +static __inline__ +long _InterlockedAnd(long volatile *_Value, long _Mask); +static __inline__ +short _InterlockedAnd16(short volatile *_Value, short _Mask); +static __inline__ +char _InterlockedAnd8(char volatile *_Value, char _Mask); +unsigned char _interlockedbittestandreset(long volatile *, long); +static __inline__ +unsigned char _interlockedbittestandset(long volatile *, long); +static __inline__ +long __cdecl _InterlockedCompareExchange(long volatile *_Destination, + long _Exchange, long _Comparand); +long _InterlockedCompareExchange_HLEAcquire(long volatile *, long, long); +long _InterlockedCompareExchange_HLERelease(long volatile *, long, long); +static __inline__ +short _InterlockedCompareExchange16(short volatile *_Destination, + short _Exchange, short _Comparand); +static __inline__ +__int64 _InterlockedCompareExchange64(__int64 volatile *_Destination, + __int64 _Exchange, __int64 _Comparand); +__int64 _InterlockedcompareExchange64_HLEAcquire(__int64 volatile *, __int64, + __int64); +__int64 _InterlockedCompareExchange64_HLERelease(__int64 volatile *, __int64, + __int64); +static __inline__ +char _InterlockedCompareExchange8(char volatile *_Destination, char _Exchange, + char _Comparand); +void *_InterlockedCompareExchangePointer_HLEAcquire(void *volatile *, void *, + void *); +void *_InterlockedCompareExchangePointer_HLERelease(void *volatile *, void *, + void *); +static __inline__ +long __cdecl _InterlockedDecrement(long volatile *_Addend); +static __inline__ +short _InterlockedDecrement16(short volatile *_Addend); +long _InterlockedExchange(long volatile *_Target, long _Value); +static __inline__ +short _InterlockedExchange16(short volatile *_Target, short _Value); +static __inline__ +char _InterlockedExchange8(char volatile *_Target, char _Value); +static __inline__ +long __cdecl _InterlockedExchangeAdd(long volatile *_Addend, long _Value); +long _InterlockedExchangeAdd_HLEAcquire(long volatile *, long); +long _InterlockedExchangeAdd_HLERelease(long volatile *, long); +static __inline__ +short _InterlockedExchangeAdd16(short volatile *_Addend, short _Value); +__int64 _InterlockedExchangeAdd64_HLEAcquire(__int64 volatile *, __int64); +__int64 _InterlockedExchangeAdd64_HLERelease(__int64 volatile *, __int64); +static __inline__ +char _InterlockedExchangeAdd8(char volatile *_Addend, char _Value); +static __inline__ +long __cdecl _InterlockedIncrement(long volatile *_Addend); +static __inline__ +short _InterlockedIncrement16(short volatile *_Addend); +static __inline__ +long _InterlockedOr(long volatile *_Value, long _Mask); +static __inline__ +short _InterlockedOr16(short volatile *_Value, short _Mask); +static __inline__ +char _InterlockedOr8(char volatile *_Value, char _Mask); +static __inline__ +long _InterlockedXor(long volatile *_Value, long _Mask); +static __inline__ +short _InterlockedXor16(short volatile *_Value, short _Mask); +static __inline__ +char _InterlockedXor8(char volatile *_Value, char _Mask); +void __cdecl _invpcid(unsigned int, void *); +static __inline__ +unsigned long __cdecl _lrotl(unsigned long, int); +static __inline__ +unsigned long __cdecl _lrotr(unsigned long, int); +static __inline__ +static __inline__ +void _ReadBarrier(void); +static __inline__ +void _ReadWriteBarrier(void); +static __inline__ +void *_ReturnAddress(void); +unsigned int _rorx_u32(unsigned int, const unsigned int); +static __inline__ +unsigned int __cdecl _rotl(unsigned int _Value, int _Shift); +static __inline__ +unsigned short _rotl16(unsigned short _Value, unsigned char _Shift); +static __inline__ +unsigned __int64 __cdecl _rotl64(unsigned __int64 _Value, int _Shift); +static __inline__ +unsigned char _rotl8(unsigned char _Value, unsigned char _Shift); +static __inline__ +unsigned int __cdecl _rotr(unsigned int _Value, int _Shift); +static __inline__ +unsigned short _rotr16(unsigned short _Value, unsigned char _Shift); +static __inline__ +unsigned __int64 __cdecl _rotr64(unsigned __int64 _Value, int _Shift); +static __inline__ +unsigned char _rotr8(unsigned char _Value, unsigned char _Shift); +int _sarx_i32(int, unsigned int); +#if __STDC_HOSTED__ +int __cdecl _setjmp(jmp_buf); +#endif +unsigned int _shlx_u32(unsigned int, unsigned int); +unsigned int _shrx_u32(unsigned int, unsigned int); +void _Store_HLERelease(long volatile *, long); +void _Store64_HLERelease(__int64 volatile *, __int64); +void _StorePointer_HLERelease(void *volatile *, void *); +static __inline__ +void _WriteBarrier(void); +unsigned __int32 xbegin(void); +void _xend(void); +static __inline__ +#define _XCR_XFEATURE_ENABLED_MASK 0 +unsigned __int64 __cdecl _xgetbv(unsigned int); +void __cdecl _xsetbv(unsigned int, unsigned __int64); + +/* These additional intrinsics are turned on in x64/amd64/x86_64 mode. */ +#ifdef __x86_64__ +void __addgsbyte(unsigned long, unsigned char); +void __addgsdword(unsigned long, unsigned long); +void __addgsqword(unsigned long, unsigned __int64); +void __addgsword(unsigned long, unsigned short); +static __inline__ +void __faststorefence(void); +void __incgsbyte(unsigned long); +void __incgsdword(unsigned long); +void __incgsqword(unsigned long); +void __incgsword(unsigned long); +unsigned char __lwpins64(unsigned __int64, unsigned int, unsigned int); +void __lwpval64(unsigned __int64, unsigned int, unsigned int); +unsigned __int64 __lzcnt64(unsigned __int64); +static __inline__ +void __movsq(unsigned long long *, unsigned long long const *, size_t); +__int64 __mulh(__int64, __int64); +static __inline__ +unsigned __int64 __popcnt64(unsigned __int64); +static __inline__ +unsigned char __readgsbyte(unsigned long); +static __inline__ +unsigned long __readgsdword(unsigned long); +static __inline__ +unsigned __int64 __readgsqword(unsigned long); +unsigned short __readgsword(unsigned long); +unsigned __int64 __shiftleft128(unsigned __int64 _LowPart, + unsigned __int64 _HighPart, + unsigned char _Shift); +unsigned __int64 __shiftright128(unsigned __int64 _LowPart, + unsigned __int64 _HighPart, + unsigned char _Shift); +static __inline__ +void __stosq(unsigned __int64 *, unsigned __int64, size_t); +unsigned char __vmx_on(unsigned __int64 *); +unsigned char __vmx_vmclear(unsigned __int64 *); +unsigned char __vmx_vmlaunch(void); +unsigned char __vmx_vmptrld(unsigned __int64 *); +unsigned char __vmx_vmread(size_t, size_t *); +unsigned char __vmx_vmresume(void); +unsigned char __vmx_vmwrite(size_t, size_t); +void __writegsbyte(unsigned long, unsigned char); +void __writegsdword(unsigned long, unsigned long); +void __writegsqword(unsigned long, unsigned __int64); +void __writegsword(unsigned long, unsigned short); +static __inline__ +unsigned char _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask); +static __inline__ +unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask); +static __inline__ +unsigned char _bittest64(__int64 const *, __int64); +static __inline__ +unsigned char _bittestandcomplement64(__int64 *, __int64); +static __inline__ +unsigned char _bittestandreset64(__int64 *, __int64); +static __inline__ +unsigned char _bittestandset64(__int64 *, __int64); +unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64); +long _InterlockedAnd_np(long volatile *_Value, long _Mask); +short _InterlockedAnd16_np(short volatile *_Value, short _Mask); +__int64 _InterlockedAnd64_np(__int64 volatile *_Value, __int64 _Mask); +char _InterlockedAnd8_np(char volatile *_Value, char _Mask); +unsigned char _interlockedbittestandreset64(__int64 volatile *, __int64); +static __inline__ +unsigned char _interlockedbittestandset64(__int64 volatile *, __int64); +long _InterlockedCompareExchange_np(long volatile *_Destination, long _Exchange, + long _Comparand); +unsigned char _InterlockedCompareExchange128(__int64 volatile *_Destination, + __int64 _ExchangeHigh, + __int64 _ExchangeLow, + __int64 *_CompareandResult); +unsigned char _InterlockedCompareExchange128_np(__int64 volatile *_Destination, + __int64 _ExchangeHigh, + __int64 _ExchangeLow, + __int64 *_ComparandResult); +short _InterlockedCompareExchange16_np(short volatile *_Destination, + short _Exchange, short _Comparand); +__int64 _InterlockedCompareExchange64_HLEAcquire(__int64 volatile *, __int64, + __int64); +__int64 _InterlockedCompareExchange64_HLERelease(__int64 volatile *, __int64, + __int64); +__int64 _InterlockedCompareExchange64_np(__int64 volatile *_Destination, + __int64 _Exchange, __int64 _Comparand); +void *_InterlockedCompareExchangePointer(void *volatile *_Destination, + void *_Exchange, void *_Comparand); +void *_InterlockedCompareExchangePointer_np(void *volatile *_Destination, + void *_Exchange, void *_Comparand); +static __inline__ +__int64 _InterlockedDecrement64(__int64 volatile *_Addend); +static __inline__ +__int64 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value); +static __inline__ +__int64 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value); +void *_InterlockedExchangePointer(void *volatile *_Target, void *_Value); +static __inline__ +__int64 _InterlockedIncrement64(__int64 volatile *_Addend); +long _InterlockedOr_np(long volatile *_Value, long _Mask); +short _InterlockedOr16_np(short volatile *_Value, short _Mask); +static __inline__ +__int64 _InterlockedOr64(__int64 volatile *_Value, __int64 _Mask); +__int64 _InterlockedOr64_np(__int64 volatile *_Value, __int64 _Mask); +char _InterlockedOr8_np(char volatile *_Value, char _Mask); +long _InterlockedXor_np(long volatile *_Value, long _Mask); +short _InterlockedXor16_np(short volatile *_Value, short _Mask); +static __inline__ +__int64 _InterlockedXor64(__int64 volatile *_Value, __int64 _Mask); +__int64 _InterlockedXor64_np(__int64 volatile *_Value, __int64 _Mask); +char _InterlockedXor8_np(char volatile *_Value, char _Mask); +static __inline__ +__int64 _mul128(__int64 _Multiplier, __int64 _Multiplicand, + __int64 *_HighProduct); +unsigned __int64 _rorx_u64(unsigned __int64, const unsigned int); +__int64 _sarx_i64(__int64, unsigned int); +#if __STDC_HOSTED__ +int __cdecl _setjmpex(jmp_buf); +#endif +unsigned __int64 _shlx_u64(unsigned __int64, unsigned int); +unsigned __int64 _shrx_u64(unsigned __int64, unsigned int); +/* + * Multiply two 64-bit integers and obtain a 64-bit result. + * The low-half is returned directly and the high half is in an out parameter. + */ +static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS +_umul128(unsigned __int64 _Multiplier, unsigned __int64 _Multiplicand, + unsigned __int64 *_HighProduct) { + unsigned __int128 _FullProduct = + (unsigned __int128)_Multiplier * (unsigned __int128)_Multiplicand; + *_HighProduct = _FullProduct >> 64; + return _FullProduct; +} +static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS +__umulh(unsigned __int64 _Multiplier, unsigned __int64 _Multiplicand) { + unsigned __int128 _FullProduct = + (unsigned __int128)_Multiplier * (unsigned __int128)_Multiplicand; + return _FullProduct >> 64; +} + +#endif /* __x86_64__ */ + +/*----------------------------------------------------------------------------*\ +|* Multiplication +\*----------------------------------------------------------------------------*/ +static __inline__ __int64 __DEFAULT_FN_ATTRS +__emul(int __in1, int __in2) { + return (__int64)__in1 * (__int64)__in2; +} +static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS +__emulu(unsigned int __in1, unsigned int __in2) { + return (unsigned __int64)__in1 * (unsigned __int64)__in2; +} +/*----------------------------------------------------------------------------*\ +|* Bit Twiddling +\*----------------------------------------------------------------------------*/ +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_rotl8(unsigned char _Value, unsigned char _Shift) { + _Shift &= 0x7; + return _Shift ? (_Value << _Shift) | (_Value >> (8 - _Shift)) : _Value; +} +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_rotr8(unsigned char _Value, unsigned char _Shift) { + _Shift &= 0x7; + return _Shift ? (_Value >> _Shift) | (_Value << (8 - _Shift)) : _Value; +} +static __inline__ unsigned short __DEFAULT_FN_ATTRS +_rotl16(unsigned short _Value, unsigned char _Shift) { + _Shift &= 0xf; + return _Shift ? (_Value << _Shift) | (_Value >> (16 - _Shift)) : _Value; +} +static __inline__ unsigned short __DEFAULT_FN_ATTRS +_rotr16(unsigned short _Value, unsigned char _Shift) { + _Shift &= 0xf; + return _Shift ? (_Value >> _Shift) | (_Value << (16 - _Shift)) : _Value; +} +static __inline__ unsigned int __DEFAULT_FN_ATTRS +_rotl(unsigned int _Value, int _Shift) { + _Shift &= 0x1f; + return _Shift ? (_Value << _Shift) | (_Value >> (32 - _Shift)) : _Value; +} +static __inline__ unsigned int __DEFAULT_FN_ATTRS +_rotr(unsigned int _Value, int _Shift) { + _Shift &= 0x1f; + return _Shift ? (_Value >> _Shift) | (_Value << (32 - _Shift)) : _Value; +} +static __inline__ unsigned long __DEFAULT_FN_ATTRS +_lrotl(unsigned long _Value, int _Shift) { + _Shift &= 0x1f; + return _Shift ? (_Value << _Shift) | (_Value >> (32 - _Shift)) : _Value; +} +static __inline__ unsigned long __DEFAULT_FN_ATTRS +_lrotr(unsigned long _Value, int _Shift) { + _Shift &= 0x1f; + return _Shift ? (_Value >> _Shift) | (_Value << (32 - _Shift)) : _Value; +} +static +__inline__ unsigned __int64 __DEFAULT_FN_ATTRS +_rotl64(unsigned __int64 _Value, int _Shift) { + _Shift &= 0x3f; + return _Shift ? (_Value << _Shift) | (_Value >> (64 - _Shift)) : _Value; +} +static +__inline__ unsigned __int64 __DEFAULT_FN_ATTRS +_rotr64(unsigned __int64 _Value, int _Shift) { + _Shift &= 0x3f; + return _Shift ? (_Value >> _Shift) | (_Value << (64 - _Shift)) : _Value; +} +/*----------------------------------------------------------------------------*\ +|* Bit Counting and Testing +\*----------------------------------------------------------------------------*/ +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_BitScanForward(unsigned long *_Index, unsigned long _Mask) { + if (!_Mask) + return 0; + *_Index = __builtin_ctzl(_Mask); + return 1; +} +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_BitScanReverse(unsigned long *_Index, unsigned long _Mask) { + if (!_Mask) + return 0; + *_Index = 31 - __builtin_clzl(_Mask); + return 1; +} +static __inline__ unsigned short __DEFAULT_FN_ATTRS +__popcnt16(unsigned short _Value) { + return __builtin_popcount((int)_Value); +} +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__popcnt(unsigned int _Value) { + return __builtin_popcount(_Value); +} +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_bittest(long const *_BitBase, long _BitPos) { + return (*_BitBase >> _BitPos) & 1; +} +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_bittestandcomplement(long *_BitBase, long _BitPos) { + unsigned char _Res = (*_BitBase >> _BitPos) & 1; + *_BitBase = *_BitBase ^ (1 << _BitPos); + return _Res; +} +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_bittestandreset(long *_BitBase, long _BitPos) { + unsigned char _Res = (*_BitBase >> _BitPos) & 1; + *_BitBase = *_BitBase & ~(1 << _BitPos); + return _Res; +} +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_bittestandset(long *_BitBase, long _BitPos) { + unsigned char _Res = (*_BitBase >> _BitPos) & 1; + *_BitBase = *_BitBase | (1 << _BitPos); + return _Res; +} +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_interlockedbittestandset(long volatile *_BitBase, long _BitPos) { + long _PrevVal = __atomic_fetch_or(_BitBase, 1l << _BitPos, __ATOMIC_SEQ_CST); + return (_PrevVal >> _BitPos) & 1; +} +#ifdef __x86_64__ +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask) { + if (!_Mask) + return 0; + *_Index = __builtin_ctzll(_Mask); + return 1; +} +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask) { + if (!_Mask) + return 0; + *_Index = 63 - __builtin_clzll(_Mask); + return 1; +} +static __inline__ +unsigned __int64 __DEFAULT_FN_ATTRS +__popcnt64(unsigned __int64 _Value) { + return __builtin_popcountll(_Value); +} +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_bittest64(__int64 const *_BitBase, __int64 _BitPos) { + return (*_BitBase >> _BitPos) & 1; +} +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_bittestandcomplement64(__int64 *_BitBase, __int64 _BitPos) { + unsigned char _Res = (*_BitBase >> _BitPos) & 1; + *_BitBase = *_BitBase ^ (1ll << _BitPos); + return _Res; +} +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_bittestandreset64(__int64 *_BitBase, __int64 _BitPos) { + unsigned char _Res = (*_BitBase >> _BitPos) & 1; + *_BitBase = *_BitBase & ~(1ll << _BitPos); + return _Res; +} +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_bittestandset64(__int64 *_BitBase, __int64 _BitPos) { + unsigned char _Res = (*_BitBase >> _BitPos) & 1; + *_BitBase = *_BitBase | (1ll << _BitPos); + return _Res; +} +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_interlockedbittestandset64(__int64 volatile *_BitBase, __int64 _BitPos) { + long long _PrevVal = + __atomic_fetch_or(_BitBase, 1ll << _BitPos, __ATOMIC_SEQ_CST); + return (_PrevVal >> _BitPos) & 1; +} +#endif +/*----------------------------------------------------------------------------*\ +|* Interlocked Exchange Add +\*----------------------------------------------------------------------------*/ +static __inline__ char __DEFAULT_FN_ATTRS +_InterlockedExchangeAdd8(char volatile *_Addend, char _Value) { + return __atomic_fetch_add(_Addend, _Value, __ATOMIC_SEQ_CST); +} +static __inline__ short __DEFAULT_FN_ATTRS +_InterlockedExchangeAdd16(short volatile *_Addend, short _Value) { + return __atomic_fetch_add(_Addend, _Value, __ATOMIC_SEQ_CST); +} +#ifdef __x86_64__ +static __inline__ __int64 __DEFAULT_FN_ATTRS +_InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value) { + return __atomic_fetch_add(_Addend, _Value, __ATOMIC_SEQ_CST); +} +#endif +/*----------------------------------------------------------------------------*\ +|* Interlocked Exchange Sub +\*----------------------------------------------------------------------------*/ +static __inline__ char __DEFAULT_FN_ATTRS +_InterlockedExchangeSub8(char volatile *_Subend, char _Value) { + return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); +} +static __inline__ short __DEFAULT_FN_ATTRS +_InterlockedExchangeSub16(short volatile *_Subend, short _Value) { + return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); +} +static __inline__ long __DEFAULT_FN_ATTRS +_InterlockedExchangeSub(long volatile *_Subend, long _Value) { + return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); +} +#ifdef __x86_64__ +static __inline__ __int64 __DEFAULT_FN_ATTRS +_InterlockedExchangeSub64(__int64 volatile *_Subend, __int64 _Value) { + return __atomic_fetch_sub(_Subend, _Value, __ATOMIC_SEQ_CST); +} +#endif +/*----------------------------------------------------------------------------*\ +|* Interlocked Increment +\*----------------------------------------------------------------------------*/ +static __inline__ short __DEFAULT_FN_ATTRS +_InterlockedIncrement16(short volatile *_Value) { + return __atomic_add_fetch(_Value, 1, __ATOMIC_SEQ_CST); +} +#ifdef __x86_64__ +static __inline__ __int64 __DEFAULT_FN_ATTRS +_InterlockedIncrement64(__int64 volatile *_Value) { + return __atomic_add_fetch(_Value, 1, __ATOMIC_SEQ_CST); +} +#endif +/*----------------------------------------------------------------------------*\ +|* Interlocked Decrement +\*----------------------------------------------------------------------------*/ +static __inline__ short __DEFAULT_FN_ATTRS +_InterlockedDecrement16(short volatile *_Value) { + return __atomic_sub_fetch(_Value, 1, __ATOMIC_SEQ_CST); +} +#ifdef __x86_64__ +static __inline__ __int64 __DEFAULT_FN_ATTRS +_InterlockedDecrement64(__int64 volatile *_Value) { + return __atomic_sub_fetch(_Value, 1, __ATOMIC_SEQ_CST); +} +#endif +/*----------------------------------------------------------------------------*\ +|* Interlocked And +\*----------------------------------------------------------------------------*/ +static __inline__ char __DEFAULT_FN_ATTRS +_InterlockedAnd8(char volatile *_Value, char _Mask) { + return __atomic_and_fetch(_Value, _Mask, __ATOMIC_SEQ_CST); +} +static __inline__ short __DEFAULT_FN_ATTRS +_InterlockedAnd16(short volatile *_Value, short _Mask) { + return __atomic_and_fetch(_Value, _Mask, __ATOMIC_SEQ_CST); +} +static __inline__ long __DEFAULT_FN_ATTRS +_InterlockedAnd(long volatile *_Value, long _Mask) { + return __atomic_and_fetch(_Value, _Mask, __ATOMIC_SEQ_CST); +} +#ifdef __x86_64__ +static __inline__ __int64 __DEFAULT_FN_ATTRS +_InterlockedAnd64(__int64 volatile *_Value, __int64 _Mask) { + return __atomic_and_fetch(_Value, _Mask, __ATOMIC_SEQ_CST); +} +#endif +/*----------------------------------------------------------------------------*\ +|* Interlocked Or +\*----------------------------------------------------------------------------*/ +static __inline__ char __DEFAULT_FN_ATTRS +_InterlockedOr8(char volatile *_Value, char _Mask) { + return __atomic_or_fetch(_Value, _Mask, __ATOMIC_SEQ_CST); +} +static __inline__ short __DEFAULT_FN_ATTRS +_InterlockedOr16(short volatile *_Value, short _Mask) { + return __atomic_or_fetch(_Value, _Mask, __ATOMIC_SEQ_CST); +} +static __inline__ long __DEFAULT_FN_ATTRS +_InterlockedOr(long volatile *_Value, long _Mask) { + return __atomic_or_fetch(_Value, _Mask, __ATOMIC_SEQ_CST); +} +#ifdef __x86_64__ +static __inline__ __int64 __DEFAULT_FN_ATTRS +_InterlockedOr64(__int64 volatile *_Value, __int64 _Mask) { + return __atomic_or_fetch(_Value, _Mask, __ATOMIC_SEQ_CST); +} +#endif +/*----------------------------------------------------------------------------*\ +|* Interlocked Xor +\*----------------------------------------------------------------------------*/ +static __inline__ char __DEFAULT_FN_ATTRS +_InterlockedXor8(char volatile *_Value, char _Mask) { + return __atomic_xor_fetch(_Value, _Mask, __ATOMIC_SEQ_CST); +} +static __inline__ short __DEFAULT_FN_ATTRS +_InterlockedXor16(short volatile *_Value, short _Mask) { + return __atomic_xor_fetch(_Value, _Mask, __ATOMIC_SEQ_CST); +} +static __inline__ long __DEFAULT_FN_ATTRS +_InterlockedXor(long volatile *_Value, long _Mask) { + return __atomic_xor_fetch(_Value, _Mask, __ATOMIC_SEQ_CST); +} +#ifdef __x86_64__ +static __inline__ __int64 __DEFAULT_FN_ATTRS +_InterlockedXor64(__int64 volatile *_Value, __int64 _Mask) { + return __atomic_xor_fetch(_Value, _Mask, __ATOMIC_SEQ_CST); +} +#endif +/*----------------------------------------------------------------------------*\ +|* Interlocked Exchange +\*----------------------------------------------------------------------------*/ +static __inline__ char __DEFAULT_FN_ATTRS +_InterlockedExchange8(char volatile *_Target, char _Value) { + __atomic_exchange(_Target, &_Value, &_Value, __ATOMIC_SEQ_CST); + return _Value; +} +static __inline__ short __DEFAULT_FN_ATTRS +_InterlockedExchange16(short volatile *_Target, short _Value) { + __atomic_exchange(_Target, &_Value, &_Value, __ATOMIC_SEQ_CST); + return _Value; +} +#ifdef __x86_64__ +static __inline__ __int64 __DEFAULT_FN_ATTRS +_InterlockedExchange64(__int64 volatile *_Target, __int64 _Value) { + __atomic_exchange(_Target, &_Value, &_Value, __ATOMIC_SEQ_CST); + return _Value; +} +#endif +/*----------------------------------------------------------------------------*\ +|* Interlocked Compare Exchange +\*----------------------------------------------------------------------------*/ +static __inline__ char __DEFAULT_FN_ATTRS +_InterlockedCompareExchange8(char volatile *_Destination, + char _Exchange, char _Comparand) { + __atomic_compare_exchange(_Destination, &_Comparand, &_Exchange, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + return _Comparand; +} +static __inline__ short __DEFAULT_FN_ATTRS +_InterlockedCompareExchange16(short volatile *_Destination, + short _Exchange, short _Comparand) { + __atomic_compare_exchange(_Destination, &_Comparand, &_Exchange, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + return _Comparand; +} +static __inline__ __int64 __DEFAULT_FN_ATTRS +_InterlockedCompareExchange64(__int64 volatile *_Destination, + __int64 _Exchange, __int64 _Comparand) { + __atomic_compare_exchange(_Destination, &_Comparand, &_Exchange, 0, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + return _Comparand; +} +/*----------------------------------------------------------------------------*\ +|* Barriers +\*----------------------------------------------------------------------------*/ +static __inline__ void __DEFAULT_FN_ATTRS +__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead"))) +_ReadWriteBarrier(void) { + __atomic_signal_fence(__ATOMIC_SEQ_CST); +} +static __inline__ void __DEFAULT_FN_ATTRS +__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead"))) +_ReadBarrier(void) { + __atomic_signal_fence(__ATOMIC_SEQ_CST); +} +static __inline__ void __DEFAULT_FN_ATTRS +__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead"))) +_WriteBarrier(void) { + __atomic_signal_fence(__ATOMIC_SEQ_CST); +} +#ifdef __x86_64__ +static __inline__ void __DEFAULT_FN_ATTRS +__faststorefence(void) { + __atomic_thread_fence(__ATOMIC_SEQ_CST); +} +#endif +/*----------------------------------------------------------------------------*\ +|* readfs, readgs +|* (Pointers in address space #256 and #257 are relative to the GS and FS +|* segment registers, respectively.) +\*----------------------------------------------------------------------------*/ +#define __ptr_to_addr_space(__addr_space_nbr, __type, __offset) \ + ((volatile __type __attribute__((__address_space__(__addr_space_nbr)))*) \ + (__offset)) + +#ifdef __i386__ +static __inline__ unsigned char __DEFAULT_FN_ATTRS +__readfsbyte(unsigned long __offset) { + return *__ptr_to_addr_space(257, unsigned char, __offset); +} +static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS +__readfsqword(unsigned long __offset) { + return *__ptr_to_addr_space(257, unsigned __int64, __offset); +} +static __inline__ unsigned short __DEFAULT_FN_ATTRS +__readfsword(unsigned long __offset) { + return *__ptr_to_addr_space(257, unsigned short, __offset); +} +#endif +#ifdef __x86_64__ +static __inline__ unsigned char __DEFAULT_FN_ATTRS +__readgsbyte(unsigned long __offset) { + return *__ptr_to_addr_space(256, unsigned char, __offset); +} +static __inline__ unsigned long __DEFAULT_FN_ATTRS +__readgsdword(unsigned long __offset) { + return *__ptr_to_addr_space(256, unsigned long, __offset); +} +static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS +__readgsqword(unsigned long __offset) { + return *__ptr_to_addr_space(256, unsigned __int64, __offset); +} +static __inline__ unsigned short __DEFAULT_FN_ATTRS +__readgsword(unsigned long __offset) { + return *__ptr_to_addr_space(256, unsigned short, __offset); +} +#endif +#undef __ptr_to_addr_space +/*----------------------------------------------------------------------------*\ +|* movs, stos +\*----------------------------------------------------------------------------*/ +#if defined(__i386__) || defined(__x86_64__) +static __inline__ void __DEFAULT_FN_ATTRS +__movsb(unsigned char *__dst, unsigned char const *__src, size_t __n) { + __asm__("rep movsb" : : "D"(__dst), "S"(__src), "c"(__n) + : "%edi", "%esi", "%ecx"); +} +static __inline__ void __DEFAULT_FN_ATTRS +__movsd(unsigned long *__dst, unsigned long const *__src, size_t __n) { + __asm__("rep movsl" : : "D"(__dst), "S"(__src), "c"(__n) + : "%edi", "%esi", "%ecx"); +} +static __inline__ void __DEFAULT_FN_ATTRS +__movsw(unsigned short *__dst, unsigned short const *__src, size_t __n) { + __asm__("rep movsw" : : "D"(__dst), "S"(__src), "c"(__n) + : "%edi", "%esi", "%ecx"); +} +static __inline__ void __DEFAULT_FN_ATTRS +__stosb(unsigned char *__dst, unsigned char __x, size_t __n) { + __asm__("rep stosb" : : "D"(__dst), "a"(__x), "c"(__n) + : "%edi", "%ecx"); +} +static __inline__ void __DEFAULT_FN_ATTRS +__stosd(unsigned long *__dst, unsigned long __x, size_t __n) { + __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n) + : "%edi", "%ecx"); +} +static __inline__ void __DEFAULT_FN_ATTRS +__stosw(unsigned short *__dst, unsigned short __x, size_t __n) { + __asm__("rep stosw" : : "D"(__dst), "a"(__x), "c"(__n) + : "%edi", "%ecx"); +} +#endif +#ifdef __x86_64__ +static __inline__ void __DEFAULT_FN_ATTRS +__movsq(unsigned long long *__dst, unsigned long long const *__src, size_t __n) { + __asm__("rep movsq" : : "D"(__dst), "S"(__src), "c"(__n) + : "%edi", "%esi", "%ecx"); +} +static __inline__ void __DEFAULT_FN_ATTRS +__stosq(unsigned __int64 *__dst, unsigned __int64 __x, size_t __n) { + __asm__("rep stosq" : : "D"(__dst), "a"(__x), "c"(__n) + : "%edi", "%ecx"); +} +#endif + +/*----------------------------------------------------------------------------*\ +|* Misc +\*----------------------------------------------------------------------------*/ +static __inline__ void * __DEFAULT_FN_ATTRS +_AddressOfReturnAddress(void) { + return (void*)((char*)__builtin_frame_address(0) + sizeof(void*)); +} +static __inline__ void * __DEFAULT_FN_ATTRS +_ReturnAddress(void) { + return __builtin_return_address(0); +} +#if defined(__i386__) || defined(__x86_64__) +static __inline__ void __DEFAULT_FN_ATTRS +__cpuid(int __info[4], int __level) { + __asm__ ("cpuid" : "=a"(__info[0]), "=b" (__info[1]), "=c"(__info[2]), "=d"(__info[3]) + : "a"(__level)); +} +static __inline__ void __DEFAULT_FN_ATTRS +__cpuidex(int __info[4], int __level, int __ecx) { + __asm__ ("cpuid" : "=a"(__info[0]), "=b" (__info[1]), "=c"(__info[2]), "=d"(__info[3]) + : "a"(__level), "c"(__ecx)); +} +static __inline__ unsigned __int64 __cdecl __DEFAULT_FN_ATTRS +_xgetbv(unsigned int __xcr_no) { + unsigned int __eax, __edx; + __asm__ ("xgetbv" : "=a" (__eax), "=d" (__edx) : "c" (__xcr_no)); + return ((unsigned __int64)__edx << 32) | __eax; +} +static __inline__ void __DEFAULT_FN_ATTRS +__halt(void) { + __asm__ volatile ("hlt"); +} +#endif + +/*----------------------------------------------------------------------------*\ +|* Privileged intrinsics +\*----------------------------------------------------------------------------*/ +#if defined(__i386__) || defined(__x86_64__) +static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS +__readmsr(unsigned long __register) { + // Loads the contents of a 64-bit model specific register (MSR) specified in + // the ECX register into registers EDX:EAX. The EDX register is loaded with + // the high-order 32 bits of the MSR and the EAX register is loaded with the + // low-order 32 bits. If less than 64 bits are implemented in the MSR being + // read, the values returned to EDX:EAX in unimplemented bit locations are + // undefined. + unsigned long __edx; + unsigned long __eax; + __asm__ ("rdmsr" : "=d"(__edx), "=a"(__eax) : "c"(__register)); + return (((unsigned __int64)__edx) << 32) | (unsigned __int64)__eax; +} + +static __inline__ unsigned long __DEFAULT_FN_ATTRS +__readcr3(void) { + unsigned long __cr3_val; + __asm__ __volatile__ ("mov %%cr3, %0" : "=q"(__cr3_val) : : "memory"); + return __cr3_val; +} + +static __inline__ void __DEFAULT_FN_ATTRS +__writecr3(unsigned int __cr3_val) { + __asm__ ("mov %0, %%cr3" : : "q"(__cr3_val) : "memory"); +} +#endif + +#ifdef __cplusplus +} +#endif + +#undef __DEFAULT_FN_ATTRS + +#endif /* __INTRIN_H */ +#endif /* _MSC_VER */ diff --git a/headers/clang/__stddef_max_align_t.h b/headers/clang/__stddef_max_align_t.h new file mode 100644 index 0000000000..1e10ca9865 --- /dev/null +++ b/headers/clang/__stddef_max_align_t.h @@ -0,0 +1,43 @@ +/*===---- __stddef_max_align_t.h - Definition of max_align_t for modules ---=== + * + * Copyright (c) 2014 Chandler Carruth + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __CLANG_MAX_ALIGN_T_DEFINED +#define __CLANG_MAX_ALIGN_T_DEFINED + +#if defined(_MSC_VER) +typedef double max_align_t; +#elif defined(__APPLE__) +typedef long double max_align_t; +#else +// Define 'max_align_t' to match the GCC definition. +typedef struct { + long long __clang_max_align_nonce1 + __attribute__((__aligned__(__alignof__(long long)))); + long double __clang_max_align_nonce2 + __attribute__((__aligned__(__alignof__(long double)))); +} max_align_t; +#endif + +#endif diff --git a/headers/clang/__wmmintrin_aes.h b/headers/clang/__wmmintrin_aes.h new file mode 100644 index 0000000000..81b2b8d0b0 --- /dev/null +++ b/headers/clang/__wmmintrin_aes.h @@ -0,0 +1,66 @@ +/*===---- __wmmintrin_aes.h - AES intrinsics -------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ +#ifndef _WMMINTRIN_AES_H +#define _WMMINTRIN_AES_H + +#include + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("aes"))) + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_aesenc_si128(__m128i __V, __m128i __R) +{ + return (__m128i)__builtin_ia32_aesenc128(__V, __R); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_aesenclast_si128(__m128i __V, __m128i __R) +{ + return (__m128i)__builtin_ia32_aesenclast128(__V, __R); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_aesdec_si128(__m128i __V, __m128i __R) +{ + return (__m128i)__builtin_ia32_aesdec128(__V, __R); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_aesdeclast_si128(__m128i __V, __m128i __R) +{ + return (__m128i)__builtin_ia32_aesdeclast128(__V, __R); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_aesimc_si128(__m128i __V) +{ + return (__m128i)__builtin_ia32_aesimc128(__V); +} + +#define _mm_aeskeygenassist_si128(C, R) \ + __builtin_ia32_aeskeygenassist128((C), (R)) + +#undef __DEFAULT_FN_ATTRS + +#endif /* _WMMINTRIN_AES_H */ diff --git a/headers/clang/__wmmintrin_pclmul.h b/headers/clang/__wmmintrin_pclmul.h new file mode 100644 index 0000000000..48a85d24ee --- /dev/null +++ b/headers/clang/__wmmintrin_pclmul.h @@ -0,0 +1,30 @@ +/*===---- __wmmintrin_pclmul.h - AES intrinsics ----------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ +#ifndef _WMMINTRIN_PCLMUL_H +#define _WMMINTRIN_PCLMUL_H + +#define _mm_clmulepi64_si128(__X, __Y, __I) \ + ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(__X), \ + (__v2di)(__m128i)(__Y), (char)(__I))) + +#endif /* _WMMINTRIN_PCLMUL_H */ diff --git a/headers/clang/adxintrin.h b/headers/clang/adxintrin.h new file mode 100644 index 0000000000..ee34728417 --- /dev/null +++ b/headers/clang/adxintrin.h @@ -0,0 +1,86 @@ +/*===---- adxintrin.h - ADX intrinsics -------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __ADXINTRIN_H +#define __ADXINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) + +/* Intrinsics that are available only if __ADX__ defined */ +static __inline unsigned char __attribute__((__always_inline__, __nodebug__, __target__("adx"))) +_addcarryx_u32(unsigned char __cf, unsigned int __x, unsigned int __y, + unsigned int *__p) +{ + return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p); +} + +#ifdef __x86_64__ +static __inline unsigned char __attribute__((__always_inline__, __nodebug__, __target__("adx"))) +_addcarryx_u64(unsigned char __cf, unsigned long long __x, + unsigned long long __y, unsigned long long *__p) +{ + return __builtin_ia32_addcarryx_u64(__cf, __x, __y, __p); +} +#endif + +/* Intrinsics that are also available if __ADX__ undefined */ +static __inline unsigned char __DEFAULT_FN_ATTRS +_addcarry_u32(unsigned char __cf, unsigned int __x, unsigned int __y, + unsigned int *__p) +{ + return __builtin_ia32_addcarry_u32(__cf, __x, __y, __p); +} + +#ifdef __x86_64__ +static __inline unsigned char __DEFAULT_FN_ATTRS +_addcarry_u64(unsigned char __cf, unsigned long long __x, + unsigned long long __y, unsigned long long *__p) +{ + return __builtin_ia32_addcarry_u64(__cf, __x, __y, __p); +} +#endif + +static __inline unsigned char __DEFAULT_FN_ATTRS +_subborrow_u32(unsigned char __cf, unsigned int __x, unsigned int __y, + unsigned int *__p) +{ + return __builtin_ia32_subborrow_u32(__cf, __x, __y, __p); +} + +#ifdef __x86_64__ +static __inline unsigned char __DEFAULT_FN_ATTRS +_subborrow_u64(unsigned char __cf, unsigned long long __x, + unsigned long long __y, unsigned long long *__p) +{ + return __builtin_ia32_subborrow_u64(__cf, __x, __y, __p); +} +#endif + +#undef __DEFAULT_FN_ATTRS + +#endif /* __ADXINTRIN_H */ diff --git a/headers/clang/altivec.h b/headers/clang/altivec.h new file mode 100644 index 0000000000..c39156eff8 --- /dev/null +++ b/headers/clang/altivec.h @@ -0,0 +1,13919 @@ +/*===---- altivec.h - Standard header for type generic math ---------------===*\ + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * +\*===----------------------------------------------------------------------===*/ + +#ifndef __ALTIVEC_H +#define __ALTIVEC_H + +#ifndef __ALTIVEC__ +#error "AltiVec support not enabled" +#endif + +/* constants for mapping CR6 bits to predicate result. */ + +#define __CR6_EQ 0 +#define __CR6_EQ_REV 1 +#define __CR6_LT 2 +#define __CR6_LT_REV 3 + +#define __ATTRS_o_ai __attribute__((__overloadable__, __always_inline__)) + +static vector signed char __ATTRS_o_ai vec_perm(vector signed char __a, + vector signed char __b, + vector unsigned char __c); + +static vector unsigned char __ATTRS_o_ai vec_perm(vector unsigned char __a, + vector unsigned char __b, + vector unsigned char __c); + +static vector bool char __ATTRS_o_ai vec_perm(vector bool char __a, + vector bool char __b, + vector unsigned char __c); + +static vector short __ATTRS_o_ai vec_perm(vector signed short __a, + vector signed short __b, + vector unsigned char __c); + +static vector unsigned short __ATTRS_o_ai vec_perm(vector unsigned short __a, + vector unsigned short __b, + vector unsigned char __c); + +static vector bool short __ATTRS_o_ai vec_perm(vector bool short __a, + vector bool short __b, + vector unsigned char __c); + +static vector pixel __ATTRS_o_ai vec_perm(vector pixel __a, vector pixel __b, + vector unsigned char __c); + +static vector int __ATTRS_o_ai vec_perm(vector signed int __a, + vector signed int __b, + vector unsigned char __c); + +static vector unsigned int __ATTRS_o_ai vec_perm(vector unsigned int __a, + vector unsigned int __b, + vector unsigned char __c); + +static vector bool int __ATTRS_o_ai vec_perm(vector bool int __a, + vector bool int __b, + vector unsigned char __c); + +static vector float __ATTRS_o_ai vec_perm(vector float __a, vector float __b, + vector unsigned char __c); + +#ifdef __VSX__ +static vector long long __ATTRS_o_ai vec_perm(vector signed long long __a, + vector signed long long __b, + vector unsigned char __c); + +static vector unsigned long long __ATTRS_o_ai +vec_perm(vector unsigned long long __a, vector unsigned long long __b, + vector unsigned char __c); + +static vector bool long long __ATTRS_o_ai +vec_perm(vector bool long long __a, vector bool long long __b, + vector unsigned char __c); + +static vector double __ATTRS_o_ai vec_perm(vector double __a, vector double __b, + vector unsigned char __c); +#endif + +static vector unsigned char __ATTRS_o_ai vec_xor(vector unsigned char __a, + vector unsigned char __b); + +/* vec_abs */ + +#define __builtin_altivec_abs_v16qi vec_abs +#define __builtin_altivec_abs_v8hi vec_abs +#define __builtin_altivec_abs_v4si vec_abs + +static vector signed char __ATTRS_o_ai vec_abs(vector signed char __a) { + return __builtin_altivec_vmaxsb(__a, -__a); +} + +static vector signed short __ATTRS_o_ai vec_abs(vector signed short __a) { + return __builtin_altivec_vmaxsh(__a, -__a); +} + +static vector signed int __ATTRS_o_ai vec_abs(vector signed int __a) { + return __builtin_altivec_vmaxsw(__a, -__a); +} + +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector signed long long __ATTRS_o_ai +vec_abs(vector signed long long __a) { + return __builtin_altivec_vmaxsd(__a, -__a); +} +#endif + +static vector float __ATTRS_o_ai vec_abs(vector float __a) { + vector unsigned int __res = + (vector unsigned int)__a & (vector unsigned int)(0x7FFFFFFF); + return (vector float)__res; +} + +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector double __ATTRS_o_ai vec_abs(vector double __a) { + vector unsigned long long __res = { 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF }; + __res &= (vector unsigned int)__a; + return (vector double)__res; +} +#endif + +/* vec_abss */ +#define __builtin_altivec_abss_v16qi vec_abss +#define __builtin_altivec_abss_v8hi vec_abss +#define __builtin_altivec_abss_v4si vec_abss + +static vector signed char __ATTRS_o_ai vec_abss(vector signed char __a) { + return __builtin_altivec_vmaxsb( + __a, __builtin_altivec_vsubsbs((vector signed char)(0), __a)); +} + +static vector signed short __ATTRS_o_ai vec_abss(vector signed short __a) { + return __builtin_altivec_vmaxsh( + __a, __builtin_altivec_vsubshs((vector signed short)(0), __a)); +} + +static vector signed int __ATTRS_o_ai vec_abss(vector signed int __a) { + return __builtin_altivec_vmaxsw( + __a, __builtin_altivec_vsubsws((vector signed int)(0), __a)); +} + +/* vec_add */ + +static vector signed char __ATTRS_o_ai vec_add(vector signed char __a, + vector signed char __b) { + return __a + __b; +} + +static vector signed char __ATTRS_o_ai vec_add(vector bool char __a, + vector signed char __b) { + return (vector signed char)__a + __b; +} + +static vector signed char __ATTRS_o_ai vec_add(vector signed char __a, + vector bool char __b) { + return __a + (vector signed char)__b; +} + +static vector unsigned char __ATTRS_o_ai vec_add(vector unsigned char __a, + vector unsigned char __b) { + return __a + __b; +} + +static vector unsigned char __ATTRS_o_ai vec_add(vector bool char __a, + vector unsigned char __b) { + return (vector unsigned char)__a + __b; +} + +static vector unsigned char __ATTRS_o_ai vec_add(vector unsigned char __a, + vector bool char __b) { + return __a + (vector unsigned char)__b; +} + +static vector short __ATTRS_o_ai vec_add(vector short __a, vector short __b) { + return __a + __b; +} + +static vector short __ATTRS_o_ai vec_add(vector bool short __a, + vector short __b) { + return (vector short)__a + __b; +} + +static vector short __ATTRS_o_ai vec_add(vector short __a, + vector bool short __b) { + return __a + (vector short)__b; +} + +static vector unsigned short __ATTRS_o_ai vec_add(vector unsigned short __a, + vector unsigned short __b) { + return __a + __b; +} + +static vector unsigned short __ATTRS_o_ai vec_add(vector bool short __a, + vector unsigned short __b) { + return (vector unsigned short)__a + __b; +} + +static vector unsigned short __ATTRS_o_ai vec_add(vector unsigned short __a, + vector bool short __b) { + return __a + (vector unsigned short)__b; +} + +static vector int __ATTRS_o_ai vec_add(vector int __a, vector int __b) { + return __a + __b; +} + +static vector int __ATTRS_o_ai vec_add(vector bool int __a, vector int __b) { + return (vector int)__a + __b; +} + +static vector int __ATTRS_o_ai vec_add(vector int __a, vector bool int __b) { + return __a + (vector int)__b; +} + +static vector unsigned int __ATTRS_o_ai vec_add(vector unsigned int __a, + vector unsigned int __b) { + return __a + __b; +} + +static vector unsigned int __ATTRS_o_ai vec_add(vector bool int __a, + vector unsigned int __b) { + return (vector unsigned int)__a + __b; +} + +static vector unsigned int __ATTRS_o_ai vec_add(vector unsigned int __a, + vector bool int __b) { + return __a + (vector unsigned int)__b; +} + +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector signed long long __ATTRS_o_ai +vec_add(vector signed long long __a, vector signed long long __b) { + return __a + __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_add(vector unsigned long long __a, vector unsigned long long __b) { + return __a + __b; +} + +static vector signed __int128 __ATTRS_o_ai vec_add(vector signed __int128 __a, + vector signed __int128 __b) { + return __a + __b; +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_add(vector unsigned __int128 __a, vector unsigned __int128 __b) { + return __a + __b; +} +#endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) + +static vector float __ATTRS_o_ai vec_add(vector float __a, vector float __b) { + return __a + __b; +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai +vec_add(vector double __a, vector double __b) { + return __a + __b; +} +#endif // __VSX__ + +/* vec_adde */ + +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector signed __int128 __ATTRS_o_ai +vec_adde(vector signed __int128 __a, vector signed __int128 __b, + vector signed __int128 __c) { + return __builtin_altivec_vaddeuqm(__a, __b, __c); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_adde(vector unsigned __int128 __a, vector unsigned __int128 __b, + vector unsigned __int128 __c) { + return __builtin_altivec_vaddeuqm(__a, __b, __c); +} +#endif + +/* vec_addec */ + +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector signed __int128 __ATTRS_o_ai +vec_addec(vector signed __int128 __a, vector signed __int128 __b, + vector signed __int128 __c) { + return __builtin_altivec_vaddecuq(__a, __b, __c); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_addec(vector unsigned __int128 __a, vector unsigned __int128 __b, + vector unsigned __int128 __c) { + return __builtin_altivec_vaddecuq(__a, __b, __c); +} +#endif + +/* vec_vaddubm */ + +#define __builtin_altivec_vaddubm vec_vaddubm + +static vector signed char __ATTRS_o_ai vec_vaddubm(vector signed char __a, + vector signed char __b) { + return __a + __b; +} + +static vector signed char __ATTRS_o_ai vec_vaddubm(vector bool char __a, + vector signed char __b) { + return (vector signed char)__a + __b; +} + +static vector signed char __ATTRS_o_ai vec_vaddubm(vector signed char __a, + vector bool char __b) { + return __a + (vector signed char)__b; +} + +static vector unsigned char __ATTRS_o_ai vec_vaddubm(vector unsigned char __a, + vector unsigned char __b) { + return __a + __b; +} + +static vector unsigned char __ATTRS_o_ai vec_vaddubm(vector bool char __a, + vector unsigned char __b) { + return (vector unsigned char)__a + __b; +} + +static vector unsigned char __ATTRS_o_ai vec_vaddubm(vector unsigned char __a, + vector bool char __b) { + return __a + (vector unsigned char)__b; +} + +/* vec_vadduhm */ + +#define __builtin_altivec_vadduhm vec_vadduhm + +static vector short __ATTRS_o_ai vec_vadduhm(vector short __a, + vector short __b) { + return __a + __b; +} + +static vector short __ATTRS_o_ai vec_vadduhm(vector bool short __a, + vector short __b) { + return (vector short)__a + __b; +} + +static vector short __ATTRS_o_ai vec_vadduhm(vector short __a, + vector bool short __b) { + return __a + (vector short)__b; +} + +static vector unsigned short __ATTRS_o_ai +vec_vadduhm(vector unsigned short __a, vector unsigned short __b) { + return __a + __b; +} + +static vector unsigned short __ATTRS_o_ai +vec_vadduhm(vector bool short __a, vector unsigned short __b) { + return (vector unsigned short)__a + __b; +} + +static vector unsigned short __ATTRS_o_ai vec_vadduhm(vector unsigned short __a, + vector bool short __b) { + return __a + (vector unsigned short)__b; +} + +/* vec_vadduwm */ + +#define __builtin_altivec_vadduwm vec_vadduwm + +static vector int __ATTRS_o_ai vec_vadduwm(vector int __a, vector int __b) { + return __a + __b; +} + +static vector int __ATTRS_o_ai vec_vadduwm(vector bool int __a, + vector int __b) { + return (vector int)__a + __b; +} + +static vector int __ATTRS_o_ai vec_vadduwm(vector int __a, + vector bool int __b) { + return __a + (vector int)__b; +} + +static vector unsigned int __ATTRS_o_ai vec_vadduwm(vector unsigned int __a, + vector unsigned int __b) { + return __a + __b; +} + +static vector unsigned int __ATTRS_o_ai vec_vadduwm(vector bool int __a, + vector unsigned int __b) { + return (vector unsigned int)__a + __b; +} + +static vector unsigned int __ATTRS_o_ai vec_vadduwm(vector unsigned int __a, + vector bool int __b) { + return __a + (vector unsigned int)__b; +} + +/* vec_vaddfp */ + +#define __builtin_altivec_vaddfp vec_vaddfp + +static vector float __attribute__((__always_inline__)) +vec_vaddfp(vector float __a, vector float __b) { + return __a + __b; +} + +/* vec_addc */ + +static vector signed int __ATTRS_o_ai vec_addc(vector signed int __a, + vector signed int __b) { + return (vector signed int)__builtin_altivec_vaddcuw((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_addc(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vaddcuw(__a, __b); +} + +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector signed __int128 __ATTRS_o_ai +vec_addc(vector signed __int128 __a, vector signed __int128 __b) { + return (vector signed __int128)__builtin_altivec_vaddcuq( + (vector unsigned __int128)__a, + (vector unsigned __int128)__b); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_addc(vector unsigned __int128 __a, vector unsigned __int128 __b) { + return __builtin_altivec_vaddcuq(__a, __b); +} +#endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) + +/* vec_vaddcuw */ + +static vector unsigned int __attribute__((__always_inline__)) +vec_vaddcuw(vector unsigned int __a, vector unsigned int __b) { + return __builtin_altivec_vaddcuw(__a, __b); +} + +/* vec_adds */ + +static vector signed char __ATTRS_o_ai vec_adds(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vaddsbs(__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_adds(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vaddsbs((vector signed char)__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_adds(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vaddsbs(__a, (vector signed char)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_adds(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vaddubs(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_adds(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vaddubs((vector unsigned char)__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_adds(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vaddubs(__a, (vector unsigned char)__b); +} + +static vector short __ATTRS_o_ai vec_adds(vector short __a, vector short __b) { + return __builtin_altivec_vaddshs(__a, __b); +} + +static vector short __ATTRS_o_ai vec_adds(vector bool short __a, + vector short __b) { + return __builtin_altivec_vaddshs((vector short)__a, __b); +} + +static vector short __ATTRS_o_ai vec_adds(vector short __a, + vector bool short __b) { + return __builtin_altivec_vaddshs(__a, (vector short)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_adds(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vadduhs(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_adds(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vadduhs((vector unsigned short)__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_adds(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vadduhs(__a, (vector unsigned short)__b); +} + +static vector int __ATTRS_o_ai vec_adds(vector int __a, vector int __b) { + return __builtin_altivec_vaddsws(__a, __b); +} + +static vector int __ATTRS_o_ai vec_adds(vector bool int __a, vector int __b) { + return __builtin_altivec_vaddsws((vector int)__a, __b); +} + +static vector int __ATTRS_o_ai vec_adds(vector int __a, vector bool int __b) { + return __builtin_altivec_vaddsws(__a, (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_adds(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vadduws(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_adds(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vadduws((vector unsigned int)__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_adds(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vadduws(__a, (vector unsigned int)__b); +} + +/* vec_vaddsbs */ + +static vector signed char __ATTRS_o_ai vec_vaddsbs(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vaddsbs(__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_vaddsbs(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vaddsbs((vector signed char)__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_vaddsbs(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vaddsbs(__a, (vector signed char)__b); +} + +/* vec_vaddubs */ + +static vector unsigned char __ATTRS_o_ai vec_vaddubs(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vaddubs(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_vaddubs(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vaddubs((vector unsigned char)__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_vaddubs(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vaddubs(__a, (vector unsigned char)__b); +} + +/* vec_vaddshs */ + +static vector short __ATTRS_o_ai vec_vaddshs(vector short __a, + vector short __b) { + return __builtin_altivec_vaddshs(__a, __b); +} + +static vector short __ATTRS_o_ai vec_vaddshs(vector bool short __a, + vector short __b) { + return __builtin_altivec_vaddshs((vector short)__a, __b); +} + +static vector short __ATTRS_o_ai vec_vaddshs(vector short __a, + vector bool short __b) { + return __builtin_altivec_vaddshs(__a, (vector short)__b); +} + +/* vec_vadduhs */ + +static vector unsigned short __ATTRS_o_ai +vec_vadduhs(vector unsigned short __a, vector unsigned short __b) { + return __builtin_altivec_vadduhs(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai +vec_vadduhs(vector bool short __a, vector unsigned short __b) { + return __builtin_altivec_vadduhs((vector unsigned short)__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_vadduhs(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vadduhs(__a, (vector unsigned short)__b); +} + +/* vec_vaddsws */ + +static vector int __ATTRS_o_ai vec_vaddsws(vector int __a, vector int __b) { + return __builtin_altivec_vaddsws(__a, __b); +} + +static vector int __ATTRS_o_ai vec_vaddsws(vector bool int __a, + vector int __b) { + return __builtin_altivec_vaddsws((vector int)__a, __b); +} + +static vector int __ATTRS_o_ai vec_vaddsws(vector int __a, + vector bool int __b) { + return __builtin_altivec_vaddsws(__a, (vector int)__b); +} + +/* vec_vadduws */ + +static vector unsigned int __ATTRS_o_ai vec_vadduws(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vadduws(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_vadduws(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vadduws((vector unsigned int)__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_vadduws(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vadduws(__a, (vector unsigned int)__b); +} + +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +/* vec_vadduqm */ + +static vector signed __int128 __ATTRS_o_ai +vec_vadduqm(vector signed __int128 __a, vector signed __int128 __b) { + return __a + __b; +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vadduqm(vector unsigned __int128 __a, vector unsigned __int128 __b) { + return __a + __b; +} + +/* vec_vaddeuqm */ + +static vector signed __int128 __ATTRS_o_ai +vec_vaddeuqm(vector signed __int128 __a, vector signed __int128 __b, + vector signed __int128 __c) { + return __builtin_altivec_vaddeuqm(__a, __b, __c); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vaddeuqm(vector unsigned __int128 __a, vector unsigned __int128 __b, + vector unsigned __int128 __c) { + return __builtin_altivec_vaddeuqm(__a, __b, __c); +} + +/* vec_vaddcuq */ + +static vector signed __int128 __ATTRS_o_ai +vec_vaddcuq(vector signed __int128 __a, vector signed __int128 __b) { + return __builtin_altivec_vaddcuq(__a, __b); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vaddcuq(vector unsigned __int128 __a, vector unsigned __int128 __b) { + return __builtin_altivec_vaddcuq(__a, __b); +} + +/* vec_vaddecuq */ + +static vector signed __int128 __ATTRS_o_ai +vec_vaddecuq(vector signed __int128 __a, vector signed __int128 __b, + vector signed __int128 __c) { + return __builtin_altivec_vaddecuq(__a, __b, __c); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vaddecuq(vector unsigned __int128 __a, vector unsigned __int128 __b, + vector unsigned __int128 __c) { + return __builtin_altivec_vaddecuq(__a, __b, __c); +} +#endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) + +/* vec_and */ + +#define __builtin_altivec_vand vec_and + +static vector signed char __ATTRS_o_ai vec_and(vector signed char __a, + vector signed char __b) { + return __a & __b; +} + +static vector signed char __ATTRS_o_ai vec_and(vector bool char __a, + vector signed char __b) { + return (vector signed char)__a & __b; +} + +static vector signed char __ATTRS_o_ai vec_and(vector signed char __a, + vector bool char __b) { + return __a & (vector signed char)__b; +} + +static vector unsigned char __ATTRS_o_ai vec_and(vector unsigned char __a, + vector unsigned char __b) { + return __a & __b; +} + +static vector unsigned char __ATTRS_o_ai vec_and(vector bool char __a, + vector unsigned char __b) { + return (vector unsigned char)__a & __b; +} + +static vector unsigned char __ATTRS_o_ai vec_and(vector unsigned char __a, + vector bool char __b) { + return __a & (vector unsigned char)__b; +} + +static vector bool char __ATTRS_o_ai vec_and(vector bool char __a, + vector bool char __b) { + return __a & __b; +} + +static vector short __ATTRS_o_ai vec_and(vector short __a, vector short __b) { + return __a & __b; +} + +static vector short __ATTRS_o_ai vec_and(vector bool short __a, + vector short __b) { + return (vector short)__a & __b; +} + +static vector short __ATTRS_o_ai vec_and(vector short __a, + vector bool short __b) { + return __a & (vector short)__b; +} + +static vector unsigned short __ATTRS_o_ai vec_and(vector unsigned short __a, + vector unsigned short __b) { + return __a & __b; +} + +static vector unsigned short __ATTRS_o_ai vec_and(vector bool short __a, + vector unsigned short __b) { + return (vector unsigned short)__a & __b; +} + +static vector unsigned short __ATTRS_o_ai vec_and(vector unsigned short __a, + vector bool short __b) { + return __a & (vector unsigned short)__b; +} + +static vector bool short __ATTRS_o_ai vec_and(vector bool short __a, + vector bool short __b) { + return __a & __b; +} + +static vector int __ATTRS_o_ai vec_and(vector int __a, vector int __b) { + return __a & __b; +} + +static vector int __ATTRS_o_ai vec_and(vector bool int __a, vector int __b) { + return (vector int)__a & __b; +} + +static vector int __ATTRS_o_ai vec_and(vector int __a, vector bool int __b) { + return __a & (vector int)__b; +} + +static vector unsigned int __ATTRS_o_ai vec_and(vector unsigned int __a, + vector unsigned int __b) { + return __a & __b; +} + +static vector unsigned int __ATTRS_o_ai vec_and(vector bool int __a, + vector unsigned int __b) { + return (vector unsigned int)__a & __b; +} + +static vector unsigned int __ATTRS_o_ai vec_and(vector unsigned int __a, + vector bool int __b) { + return __a & (vector unsigned int)__b; +} + +static vector bool int __ATTRS_o_ai vec_and(vector bool int __a, + vector bool int __b) { + return __a & __b; +} + +static vector float __ATTRS_o_ai vec_and(vector float __a, vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a & (vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_and(vector bool int __a, + vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a & (vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_and(vector float __a, + vector bool int __b) { + vector unsigned int __res = + (vector unsigned int)__a & (vector unsigned int)__b; + return (vector float)__res; +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai vec_and(vector bool long long __a, vector double __b) { + vector unsigned long long __res = + (vector unsigned long long)__a & (vector unsigned long long)__b; + return (vector double)__res; +} + +static vector double __ATTRS_o_ai vec_and(vector double __a, vector bool long long __b) { + vector unsigned long long __res = + (vector unsigned long long)__a & (vector unsigned long long)__b; + return (vector double)__res; +} + +static vector double __ATTRS_o_ai vec_and(vector double __a, vector double __b) { + vector unsigned long long __res = + (vector unsigned long long)__a & (vector unsigned long long)__b; + return (vector double)__res; +} + +static vector signed long long __ATTRS_o_ai +vec_and(vector signed long long __a, vector signed long long __b) { + return __a & __b; +} + +static vector signed long long __ATTRS_o_ai +vec_and(vector bool long long __a, vector signed long long __b) { + return (vector signed long long)__a & __b; +} + +static vector signed long long __ATTRS_o_ai vec_and(vector signed long long __a, + vector bool long long __b) { + return __a & (vector signed long long)__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_and(vector unsigned long long __a, vector unsigned long long __b) { + return __a & __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_and(vector bool long long __a, vector unsigned long long __b) { + return (vector unsigned long long)__a & __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_and(vector unsigned long long __a, vector bool long long __b) { + return __a & (vector unsigned long long)__b; +} + +static vector bool long long __ATTRS_o_ai vec_and(vector bool long long __a, + vector bool long long __b) { + return __a & __b; +} +#endif + +/* vec_vand */ + +static vector signed char __ATTRS_o_ai vec_vand(vector signed char __a, + vector signed char __b) { + return __a & __b; +} + +static vector signed char __ATTRS_o_ai vec_vand(vector bool char __a, + vector signed char __b) { + return (vector signed char)__a & __b; +} + +static vector signed char __ATTRS_o_ai vec_vand(vector signed char __a, + vector bool char __b) { + return __a & (vector signed char)__b; +} + +static vector unsigned char __ATTRS_o_ai vec_vand(vector unsigned char __a, + vector unsigned char __b) { + return __a & __b; +} + +static vector unsigned char __ATTRS_o_ai vec_vand(vector bool char __a, + vector unsigned char __b) { + return (vector unsigned char)__a & __b; +} + +static vector unsigned char __ATTRS_o_ai vec_vand(vector unsigned char __a, + vector bool char __b) { + return __a & (vector unsigned char)__b; +} + +static vector bool char __ATTRS_o_ai vec_vand(vector bool char __a, + vector bool char __b) { + return __a & __b; +} + +static vector short __ATTRS_o_ai vec_vand(vector short __a, vector short __b) { + return __a & __b; +} + +static vector short __ATTRS_o_ai vec_vand(vector bool short __a, + vector short __b) { + return (vector short)__a & __b; +} + +static vector short __ATTRS_o_ai vec_vand(vector short __a, + vector bool short __b) { + return __a & (vector short)__b; +} + +static vector unsigned short __ATTRS_o_ai vec_vand(vector unsigned short __a, + vector unsigned short __b) { + return __a & __b; +} + +static vector unsigned short __ATTRS_o_ai vec_vand(vector bool short __a, + vector unsigned short __b) { + return (vector unsigned short)__a & __b; +} + +static vector unsigned short __ATTRS_o_ai vec_vand(vector unsigned short __a, + vector bool short __b) { + return __a & (vector unsigned short)__b; +} + +static vector bool short __ATTRS_o_ai vec_vand(vector bool short __a, + vector bool short __b) { + return __a & __b; +} + +static vector int __ATTRS_o_ai vec_vand(vector int __a, vector int __b) { + return __a & __b; +} + +static vector int __ATTRS_o_ai vec_vand(vector bool int __a, vector int __b) { + return (vector int)__a & __b; +} + +static vector int __ATTRS_o_ai vec_vand(vector int __a, vector bool int __b) { + return __a & (vector int)__b; +} + +static vector unsigned int __ATTRS_o_ai vec_vand(vector unsigned int __a, + vector unsigned int __b) { + return __a & __b; +} + +static vector unsigned int __ATTRS_o_ai vec_vand(vector bool int __a, + vector unsigned int __b) { + return (vector unsigned int)__a & __b; +} + +static vector unsigned int __ATTRS_o_ai vec_vand(vector unsigned int __a, + vector bool int __b) { + return __a & (vector unsigned int)__b; +} + +static vector bool int __ATTRS_o_ai vec_vand(vector bool int __a, + vector bool int __b) { + return __a & __b; +} + +static vector float __ATTRS_o_ai vec_vand(vector float __a, vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a & (vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_vand(vector bool int __a, + vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a & (vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_vand(vector float __a, + vector bool int __b) { + vector unsigned int __res = + (vector unsigned int)__a & (vector unsigned int)__b; + return (vector float)__res; +} + +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai +vec_vand(vector signed long long __a, vector signed long long __b) { + return __a & __b; +} + +static vector signed long long __ATTRS_o_ai +vec_vand(vector bool long long __a, vector signed long long __b) { + return (vector signed long long)__a & __b; +} + +static vector signed long long __ATTRS_o_ai +vec_vand(vector signed long long __a, vector bool long long __b) { + return __a & (vector signed long long)__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_vand(vector unsigned long long __a, vector unsigned long long __b) { + return __a & __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_vand(vector bool long long __a, vector unsigned long long __b) { + return (vector unsigned long long)__a & __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_vand(vector unsigned long long __a, vector bool long long __b) { + return __a & (vector unsigned long long)__b; +} + +static vector bool long long __ATTRS_o_ai vec_vand(vector bool long long __a, + vector bool long long __b) { + return __a & __b; +} +#endif + +/* vec_andc */ + +#define __builtin_altivec_vandc vec_andc + +static vector signed char __ATTRS_o_ai vec_andc(vector signed char __a, + vector signed char __b) { + return __a & ~__b; +} + +static vector signed char __ATTRS_o_ai vec_andc(vector bool char __a, + vector signed char __b) { + return (vector signed char)__a & ~__b; +} + +static vector signed char __ATTRS_o_ai vec_andc(vector signed char __a, + vector bool char __b) { + return __a & ~(vector signed char)__b; +} + +static vector unsigned char __ATTRS_o_ai vec_andc(vector unsigned char __a, + vector unsigned char __b) { + return __a & ~__b; +} + +static vector unsigned char __ATTRS_o_ai vec_andc(vector bool char __a, + vector unsigned char __b) { + return (vector unsigned char)__a & ~__b; +} + +static vector unsigned char __ATTRS_o_ai vec_andc(vector unsigned char __a, + vector bool char __b) { + return __a & ~(vector unsigned char)__b; +} + +static vector bool char __ATTRS_o_ai vec_andc(vector bool char __a, + vector bool char __b) { + return __a & ~__b; +} + +static vector short __ATTRS_o_ai vec_andc(vector short __a, vector short __b) { + return __a & ~__b; +} + +static vector short __ATTRS_o_ai vec_andc(vector bool short __a, + vector short __b) { + return (vector short)__a & ~__b; +} + +static vector short __ATTRS_o_ai vec_andc(vector short __a, + vector bool short __b) { + return __a & ~(vector short)__b; +} + +static vector unsigned short __ATTRS_o_ai vec_andc(vector unsigned short __a, + vector unsigned short __b) { + return __a & ~__b; +} + +static vector unsigned short __ATTRS_o_ai vec_andc(vector bool short __a, + vector unsigned short __b) { + return (vector unsigned short)__a & ~__b; +} + +static vector unsigned short __ATTRS_o_ai vec_andc(vector unsigned short __a, + vector bool short __b) { + return __a & ~(vector unsigned short)__b; +} + +static vector bool short __ATTRS_o_ai vec_andc(vector bool short __a, + vector bool short __b) { + return __a & ~__b; +} + +static vector int __ATTRS_o_ai vec_andc(vector int __a, vector int __b) { + return __a & ~__b; +} + +static vector int __ATTRS_o_ai vec_andc(vector bool int __a, vector int __b) { + return (vector int)__a & ~__b; +} + +static vector int __ATTRS_o_ai vec_andc(vector int __a, vector bool int __b) { + return __a & ~(vector int)__b; +} + +static vector unsigned int __ATTRS_o_ai vec_andc(vector unsigned int __a, + vector unsigned int __b) { + return __a & ~__b; +} + +static vector unsigned int __ATTRS_o_ai vec_andc(vector bool int __a, + vector unsigned int __b) { + return (vector unsigned int)__a & ~__b; +} + +static vector unsigned int __ATTRS_o_ai vec_andc(vector unsigned int __a, + vector bool int __b) { + return __a & ~(vector unsigned int)__b; +} + +static vector bool int __ATTRS_o_ai vec_andc(vector bool int __a, + vector bool int __b) { + return __a & ~__b; +} + +static vector float __ATTRS_o_ai vec_andc(vector float __a, vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a & ~(vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_andc(vector bool int __a, + vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a & ~(vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_andc(vector float __a, + vector bool int __b) { + vector unsigned int __res = + (vector unsigned int)__a & ~(vector unsigned int)__b; + return (vector float)__res; +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai +vec_andc(vector bool long long __a, vector double __b) { + vector unsigned long long __res = + (vector unsigned long long)__a & ~(vector unsigned long long)__b; + return (vector double)__res; +} + +static vector double __ATTRS_o_ai +vec_andc(vector double __a, vector bool long long __b) { + vector unsigned long long __res = + (vector unsigned long long)__a & ~(vector unsigned long long)__b; + return (vector double)__res; +} + +static vector double __ATTRS_o_ai vec_andc(vector double __a, vector double __b) { + vector unsigned long long __res = + (vector unsigned long long)__a & ~(vector unsigned long long)__b; + return (vector double)__res; +} + +static vector signed long long __ATTRS_o_ai +vec_andc(vector signed long long __a, vector signed long long __b) { + return __a & ~__b; +} + +static vector signed long long __ATTRS_o_ai +vec_andc(vector bool long long __a, vector signed long long __b) { + return (vector signed long long)__a & ~__b; +} + +static vector signed long long __ATTRS_o_ai +vec_andc(vector signed long long __a, vector bool long long __b) { + return __a & ~(vector signed long long)__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_andc(vector unsigned long long __a, vector unsigned long long __b) { + return __a & ~__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_andc(vector bool long long __a, vector unsigned long long __b) { + return (vector unsigned long long)__a & ~__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_andc(vector unsigned long long __a, vector bool long long __b) { + return __a & ~(vector unsigned long long)__b; +} + +static vector bool long long __ATTRS_o_ai vec_andc(vector bool long long __a, + vector bool long long __b) { + return __a & ~__b; +} +#endif + +/* vec_vandc */ + +static vector signed char __ATTRS_o_ai vec_vandc(vector signed char __a, + vector signed char __b) { + return __a & ~__b; +} + +static vector signed char __ATTRS_o_ai vec_vandc(vector bool char __a, + vector signed char __b) { + return (vector signed char)__a & ~__b; +} + +static vector signed char __ATTRS_o_ai vec_vandc(vector signed char __a, + vector bool char __b) { + return __a & ~(vector signed char)__b; +} + +static vector unsigned char __ATTRS_o_ai vec_vandc(vector unsigned char __a, + vector unsigned char __b) { + return __a & ~__b; +} + +static vector unsigned char __ATTRS_o_ai vec_vandc(vector bool char __a, + vector unsigned char __b) { + return (vector unsigned char)__a & ~__b; +} + +static vector unsigned char __ATTRS_o_ai vec_vandc(vector unsigned char __a, + vector bool char __b) { + return __a & ~(vector unsigned char)__b; +} + +static vector bool char __ATTRS_o_ai vec_vandc(vector bool char __a, + vector bool char __b) { + return __a & ~__b; +} + +static vector short __ATTRS_o_ai vec_vandc(vector short __a, vector short __b) { + return __a & ~__b; +} + +static vector short __ATTRS_o_ai vec_vandc(vector bool short __a, + vector short __b) { + return (vector short)__a & ~__b; +} + +static vector short __ATTRS_o_ai vec_vandc(vector short __a, + vector bool short __b) { + return __a & ~(vector short)__b; +} + +static vector unsigned short __ATTRS_o_ai vec_vandc(vector unsigned short __a, + vector unsigned short __b) { + return __a & ~__b; +} + +static vector unsigned short __ATTRS_o_ai vec_vandc(vector bool short __a, + vector unsigned short __b) { + return (vector unsigned short)__a & ~__b; +} + +static vector unsigned short __ATTRS_o_ai vec_vandc(vector unsigned short __a, + vector bool short __b) { + return __a & ~(vector unsigned short)__b; +} + +static vector bool short __ATTRS_o_ai vec_vandc(vector bool short __a, + vector bool short __b) { + return __a & ~__b; +} + +static vector int __ATTRS_o_ai vec_vandc(vector int __a, vector int __b) { + return __a & ~__b; +} + +static vector int __ATTRS_o_ai vec_vandc(vector bool int __a, vector int __b) { + return (vector int)__a & ~__b; +} + +static vector int __ATTRS_o_ai vec_vandc(vector int __a, vector bool int __b) { + return __a & ~(vector int)__b; +} + +static vector unsigned int __ATTRS_o_ai vec_vandc(vector unsigned int __a, + vector unsigned int __b) { + return __a & ~__b; +} + +static vector unsigned int __ATTRS_o_ai vec_vandc(vector bool int __a, + vector unsigned int __b) { + return (vector unsigned int)__a & ~__b; +} + +static vector unsigned int __ATTRS_o_ai vec_vandc(vector unsigned int __a, + vector bool int __b) { + return __a & ~(vector unsigned int)__b; +} + +static vector bool int __ATTRS_o_ai vec_vandc(vector bool int __a, + vector bool int __b) { + return __a & ~__b; +} + +static vector float __ATTRS_o_ai vec_vandc(vector float __a, vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a & ~(vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_vandc(vector bool int __a, + vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a & ~(vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_vandc(vector float __a, + vector bool int __b) { + vector unsigned int __res = + (vector unsigned int)__a & ~(vector unsigned int)__b; + return (vector float)__res; +} + +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai +vec_vandc(vector signed long long __a, vector signed long long __b) { + return __a & ~__b; +} + +static vector signed long long __ATTRS_o_ai +vec_vandc(vector bool long long __a, vector signed long long __b) { + return (vector signed long long)__a & ~__b; +} + +static vector signed long long __ATTRS_o_ai +vec_vandc(vector signed long long __a, vector bool long long __b) { + return __a & ~(vector signed long long)__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_vandc(vector unsigned long long __a, vector unsigned long long __b) { + return __a & ~__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_vandc(vector bool long long __a, vector unsigned long long __b) { + return (vector unsigned long long)__a & ~__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_vandc(vector unsigned long long __a, vector bool long long __b) { + return __a & ~(vector unsigned long long)__b; +} + +static vector bool long long __ATTRS_o_ai vec_vandc(vector bool long long __a, + vector bool long long __b) { + return __a & ~__b; +} +#endif + +/* vec_avg */ + +static vector signed char __ATTRS_o_ai vec_avg(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vavgsb(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_avg(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vavgub(__a, __b); +} + +static vector short __ATTRS_o_ai vec_avg(vector short __a, vector short __b) { + return __builtin_altivec_vavgsh(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_avg(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vavguh(__a, __b); +} + +static vector int __ATTRS_o_ai vec_avg(vector int __a, vector int __b) { + return __builtin_altivec_vavgsw(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_avg(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vavguw(__a, __b); +} + +/* vec_vavgsb */ + +static vector signed char __attribute__((__always_inline__)) +vec_vavgsb(vector signed char __a, vector signed char __b) { + return __builtin_altivec_vavgsb(__a, __b); +} + +/* vec_vavgub */ + +static vector unsigned char __attribute__((__always_inline__)) +vec_vavgub(vector unsigned char __a, vector unsigned char __b) { + return __builtin_altivec_vavgub(__a, __b); +} + +/* vec_vavgsh */ + +static vector short __attribute__((__always_inline__)) +vec_vavgsh(vector short __a, vector short __b) { + return __builtin_altivec_vavgsh(__a, __b); +} + +/* vec_vavguh */ + +static vector unsigned short __attribute__((__always_inline__)) +vec_vavguh(vector unsigned short __a, vector unsigned short __b) { + return __builtin_altivec_vavguh(__a, __b); +} + +/* vec_vavgsw */ + +static vector int __attribute__((__always_inline__)) +vec_vavgsw(vector int __a, vector int __b) { + return __builtin_altivec_vavgsw(__a, __b); +} + +/* vec_vavguw */ + +static vector unsigned int __attribute__((__always_inline__)) +vec_vavguw(vector unsigned int __a, vector unsigned int __b) { + return __builtin_altivec_vavguw(__a, __b); +} + +/* vec_ceil */ + +static vector float __ATTRS_o_ai vec_ceil(vector float __a) { +#ifdef __VSX__ + return __builtin_vsx_xvrspip(__a); +#else + return __builtin_altivec_vrfip(__a); +#endif +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai vec_ceil(vector double __a) { + return __builtin_vsx_xvrdpip(__a); +} +#endif + +/* vec_vrfip */ + +static vector float __attribute__((__always_inline__)) +vec_vrfip(vector float __a) { + return __builtin_altivec_vrfip(__a); +} + +/* vec_cmpb */ + +static vector int __attribute__((__always_inline__)) +vec_cmpb(vector float __a, vector float __b) { + return __builtin_altivec_vcmpbfp(__a, __b); +} + +/* vec_vcmpbfp */ + +static vector int __attribute__((__always_inline__)) +vec_vcmpbfp(vector float __a, vector float __b) { + return __builtin_altivec_vcmpbfp(__a, __b); +} + +/* vec_cmpeq */ + +static vector bool char __ATTRS_o_ai vec_cmpeq(vector signed char __a, + vector signed char __b) { + return (vector bool char)__builtin_altivec_vcmpequb((vector char)__a, + (vector char)__b); +} + +static vector bool char __ATTRS_o_ai vec_cmpeq(vector unsigned char __a, + vector unsigned char __b) { + return (vector bool char)__builtin_altivec_vcmpequb((vector char)__a, + (vector char)__b); +} + +static vector bool short __ATTRS_o_ai vec_cmpeq(vector short __a, + vector short __b) { + return (vector bool short)__builtin_altivec_vcmpequh(__a, __b); +} + +static vector bool short __ATTRS_o_ai vec_cmpeq(vector unsigned short __a, + vector unsigned short __b) { + return (vector bool short)__builtin_altivec_vcmpequh((vector short)__a, + (vector short)__b); +} + +static vector bool int __ATTRS_o_ai vec_cmpeq(vector int __a, vector int __b) { + return (vector bool int)__builtin_altivec_vcmpequw(__a, __b); +} + +static vector bool int __ATTRS_o_ai vec_cmpeq(vector unsigned int __a, + vector unsigned int __b) { + return (vector bool int)__builtin_altivec_vcmpequw((vector int)__a, + (vector int)__b); +} + +#ifdef __POWER8_VECTOR__ +static vector bool long long __ATTRS_o_ai +vec_cmpeq(vector signed long long __a, vector signed long long __b) { + return (vector bool long long)__builtin_altivec_vcmpequd(__a, __b); +} + +static vector bool long long __ATTRS_o_ai +vec_cmpeq(vector unsigned long long __a, vector unsigned long long __b) { + return (vector bool long long)__builtin_altivec_vcmpequd( + (vector long long)__a, (vector long long)__b); +} +#endif + +static vector bool int __ATTRS_o_ai vec_cmpeq(vector float __a, + vector float __b) { +#ifdef __VSX__ + return (vector bool int)__builtin_vsx_xvcmpeqsp(__a, __b); +#else + return (vector bool int)__builtin_altivec_vcmpeqfp(__a, __b); +#endif +} + +#ifdef __VSX__ +static vector bool long long __ATTRS_o_ai +vec_cmpeq(vector double __a, vector double __b) { + return (vector bool long long)__builtin_vsx_xvcmpeqdp(__a, __b); +} +#endif + + +/* vec_cmpgt */ + +static vector bool char __ATTRS_o_ai vec_cmpgt(vector signed char __a, + vector signed char __b) { + return (vector bool char)__builtin_altivec_vcmpgtsb(__a, __b); +} + +static vector bool char __ATTRS_o_ai vec_cmpgt(vector unsigned char __a, + vector unsigned char __b) { + return (vector bool char)__builtin_altivec_vcmpgtub(__a, __b); +} + +static vector bool short __ATTRS_o_ai vec_cmpgt(vector short __a, + vector short __b) { + return (vector bool short)__builtin_altivec_vcmpgtsh(__a, __b); +} + +static vector bool short __ATTRS_o_ai vec_cmpgt(vector unsigned short __a, + vector unsigned short __b) { + return (vector bool short)__builtin_altivec_vcmpgtuh(__a, __b); +} + +static vector bool int __ATTRS_o_ai vec_cmpgt(vector int __a, vector int __b) { + return (vector bool int)__builtin_altivec_vcmpgtsw(__a, __b); +} + +static vector bool int __ATTRS_o_ai vec_cmpgt(vector unsigned int __a, + vector unsigned int __b) { + return (vector bool int)__builtin_altivec_vcmpgtuw(__a, __b); +} + +#ifdef __POWER8_VECTOR__ +static vector bool long long __ATTRS_o_ai +vec_cmpgt(vector signed long long __a, vector signed long long __b) { + return (vector bool long long)__builtin_altivec_vcmpgtsd(__a, __b); +} + +static vector bool long long __ATTRS_o_ai +vec_cmpgt(vector unsigned long long __a, vector unsigned long long __b) { + return (vector bool long long)__builtin_altivec_vcmpgtud(__a, __b); +} +#endif + +static vector bool int __ATTRS_o_ai vec_cmpgt(vector float __a, + vector float __b) { +#ifdef __VSX__ + return (vector bool int)__builtin_vsx_xvcmpgtsp(__a, __b); +#else + return (vector bool int)__builtin_altivec_vcmpgtfp(__a, __b); +#endif +} + +#ifdef __VSX__ +static vector bool long long __ATTRS_o_ai +vec_cmpgt(vector double __a, vector double __b) { + return (vector bool long long)__builtin_vsx_xvcmpgtdp(__a, __b); +} +#endif + +/* vec_cmpge */ + +static vector bool char __ATTRS_o_ai +vec_cmpge (vector signed char __a, vector signed char __b) { + return ~(vec_cmpgt(__b, __a)); +} + +static vector bool char __ATTRS_o_ai +vec_cmpge (vector unsigned char __a, vector unsigned char __b) { + return ~(vec_cmpgt(__b, __a)); +} + +static vector bool short __ATTRS_o_ai +vec_cmpge (vector signed short __a, vector signed short __b) { + return ~(vec_cmpgt(__b, __a)); +} + +static vector bool short __ATTRS_o_ai +vec_cmpge (vector unsigned short __a, vector unsigned short __b) { + return ~(vec_cmpgt(__b, __a)); +} + +static vector bool int __ATTRS_o_ai +vec_cmpge (vector signed int __a, vector signed int __b) { + return ~(vec_cmpgt(__b, __a)); +} + +static vector bool int __ATTRS_o_ai +vec_cmpge (vector unsigned int __a, vector unsigned int __b) { + return ~(vec_cmpgt(__b, __a)); +} + +static vector bool int __ATTRS_o_ai +vec_cmpge(vector float __a, vector float __b) { +#ifdef __VSX__ + return (vector bool int)__builtin_vsx_xvcmpgesp(__a, __b); +#else + return (vector bool int)__builtin_altivec_vcmpgefp(__a, __b); +#endif +} + +#ifdef __VSX__ +static vector bool long long __ATTRS_o_ai +vec_cmpge(vector double __a, vector double __b) { + return (vector bool long long)__builtin_vsx_xvcmpgedp(__a, __b); +} +#endif + +#ifdef __POWER8_VECTOR__ +static vector bool long long __ATTRS_o_ai +vec_cmpge(vector signed long long __a, vector signed long long __b) { + return ~(vec_cmpgt(__b, __a)); +} + +static vector bool long long __ATTRS_o_ai +vec_cmpge(vector unsigned long long __a, vector unsigned long long __b) { + return ~(vec_cmpgt(__b, __a)); +} +#endif + +/* vec_vcmpgefp */ + +static vector bool int __attribute__((__always_inline__)) +vec_vcmpgefp(vector float __a, vector float __b) { + return (vector bool int)__builtin_altivec_vcmpgefp(__a, __b); +} + +/* vec_vcmpgtsb */ + +static vector bool char __attribute__((__always_inline__)) +vec_vcmpgtsb(vector signed char __a, vector signed char __b) { + return (vector bool char)__builtin_altivec_vcmpgtsb(__a, __b); +} + +/* vec_vcmpgtub */ + +static vector bool char __attribute__((__always_inline__)) +vec_vcmpgtub(vector unsigned char __a, vector unsigned char __b) { + return (vector bool char)__builtin_altivec_vcmpgtub(__a, __b); +} + +/* vec_vcmpgtsh */ + +static vector bool short __attribute__((__always_inline__)) +vec_vcmpgtsh(vector short __a, vector short __b) { + return (vector bool short)__builtin_altivec_vcmpgtsh(__a, __b); +} + +/* vec_vcmpgtuh */ + +static vector bool short __attribute__((__always_inline__)) +vec_vcmpgtuh(vector unsigned short __a, vector unsigned short __b) { + return (vector bool short)__builtin_altivec_vcmpgtuh(__a, __b); +} + +/* vec_vcmpgtsw */ + +static vector bool int __attribute__((__always_inline__)) +vec_vcmpgtsw(vector int __a, vector int __b) { + return (vector bool int)__builtin_altivec_vcmpgtsw(__a, __b); +} + +/* vec_vcmpgtuw */ + +static vector bool int __attribute__((__always_inline__)) +vec_vcmpgtuw(vector unsigned int __a, vector unsigned int __b) { + return (vector bool int)__builtin_altivec_vcmpgtuw(__a, __b); +} + +/* vec_vcmpgtfp */ + +static vector bool int __attribute__((__always_inline__)) +vec_vcmpgtfp(vector float __a, vector float __b) { + return (vector bool int)__builtin_altivec_vcmpgtfp(__a, __b); +} + +/* vec_cmple */ + +static vector bool char __ATTRS_o_ai +vec_cmple (vector signed char __a, vector signed char __b) { + return vec_cmpge(__b, __a); +} + +static vector bool char __ATTRS_o_ai +vec_cmple (vector unsigned char __a, vector unsigned char __b) { + return vec_cmpge(__b, __a); +} + +static vector bool short __ATTRS_o_ai +vec_cmple (vector signed short __a, vector signed short __b) { + return vec_cmpge(__b, __a); +} + +static vector bool short __ATTRS_o_ai +vec_cmple (vector unsigned short __a, vector unsigned short __b) { + return vec_cmpge(__b, __a); +} + +static vector bool int __ATTRS_o_ai +vec_cmple (vector signed int __a, vector signed int __b) { + return vec_cmpge(__b, __a); +} + +static vector bool int __ATTRS_o_ai +vec_cmple (vector unsigned int __a, vector unsigned int __b) { + return vec_cmpge(__b, __a); +} + +static vector bool int __ATTRS_o_ai +vec_cmple(vector float __a, vector float __b) { + return vec_cmpge(__b, __a); +} + +#ifdef __VSX__ +static vector bool long long __ATTRS_o_ai +vec_cmple(vector double __a, vector double __b) { + return vec_cmpge(__b, __a); +} +#endif + +#ifdef __POWER8_VECTOR__ +static vector bool long long __ATTRS_o_ai +vec_cmple(vector signed long long __a, vector signed long long __b) { + return vec_cmpge(__b, __a); +} + +static vector bool long long __ATTRS_o_ai +vec_cmple(vector unsigned long long __a, vector unsigned long long __b) { + return vec_cmpge(__b, __a); +} +#endif + +/* vec_cmplt */ + +static vector bool char __ATTRS_o_ai vec_cmplt(vector signed char __a, + vector signed char __b) { + return vec_cmpgt(__b, __a); +} + +static vector bool char __ATTRS_o_ai vec_cmplt(vector unsigned char __a, + vector unsigned char __b) { + return vec_cmpgt(__b, __a); +} + +static vector bool short __ATTRS_o_ai vec_cmplt(vector short __a, + vector short __b) { + return vec_cmpgt(__b, __a); +} + +static vector bool short __ATTRS_o_ai vec_cmplt(vector unsigned short __a, + vector unsigned short __b) { + return vec_cmpgt(__b, __a); +} + +static vector bool int __ATTRS_o_ai vec_cmplt(vector int __a, vector int __b) { + return vec_cmpgt(__b, __a); +} + +static vector bool int __ATTRS_o_ai vec_cmplt(vector unsigned int __a, + vector unsigned int __b) { + return vec_cmpgt(__b, __a); +} + +static vector bool int __ATTRS_o_ai vec_cmplt(vector float __a, + vector float __b) { + return vec_cmpgt(__b, __a); +} + +#ifdef __VSX__ +static vector bool long long __ATTRS_o_ai +vec_cmplt(vector double __a, vector double __b) { + return vec_cmpgt(__b, __a); +} +#endif + +#ifdef __POWER8_VECTOR__ +static vector bool long long __ATTRS_o_ai +vec_cmplt(vector signed long long __a, vector signed long long __b) { + return vec_cmpgt(__b, __a); +} + +static vector bool long long __ATTRS_o_ai +vec_cmplt(vector unsigned long long __a, vector unsigned long long __b) { + return vec_cmpgt(__b, __a); +} + +/* vec_cntlz */ + +static vector signed char __ATTRS_o_ai vec_cntlz(vector signed char __a) { + return __builtin_altivec_vclzb(__a); +} +static vector unsigned char __ATTRS_o_ai vec_cntlz(vector unsigned char __a) { + return __builtin_altivec_vclzb(__a); +} +static vector signed short __ATTRS_o_ai vec_cntlz(vector signed short __a) { + return __builtin_altivec_vclzh(__a); +} +static vector unsigned short __ATTRS_o_ai vec_cntlz(vector unsigned short __a) { + return __builtin_altivec_vclzh(__a); +} +static vector signed int __ATTRS_o_ai vec_cntlz(vector signed int __a) { + return __builtin_altivec_vclzw(__a); +} +static vector unsigned int __ATTRS_o_ai vec_cntlz(vector unsigned int __a) { + return __builtin_altivec_vclzw(__a); +} +static vector signed long long __ATTRS_o_ai +vec_cntlz(vector signed long long __a) { + return __builtin_altivec_vclzd(__a); +} +static vector unsigned long long __ATTRS_o_ai +vec_cntlz(vector unsigned long long __a) { + return __builtin_altivec_vclzd(__a); +} +#endif + +/* vec_cpsgn */ + +#ifdef __VSX__ +static vector float __ATTRS_o_ai vec_cpsgn(vector float __a, vector float __b) { + return __builtin_vsx_xvcpsgnsp(__a, __b); +} + +static vector double __ATTRS_o_ai vec_cpsgn(vector double __a, + vector double __b) { + return __builtin_vsx_xvcpsgndp(__a, __b); +} +#endif + +/* vec_ctf */ + +static vector float __ATTRS_o_ai vec_ctf(vector int __a, int __b) { + return __builtin_altivec_vcfsx(__a, __b); +} + +static vector float __ATTRS_o_ai vec_ctf(vector unsigned int __a, int __b) { + return __builtin_altivec_vcfux((vector int)__a, __b); +} + +/* vec_vcfsx */ + +static vector float __attribute__((__always_inline__)) +vec_vcfsx(vector int __a, int __b) { + return __builtin_altivec_vcfsx(__a, __b); +} + +/* vec_vcfux */ + +static vector float __attribute__((__always_inline__)) +vec_vcfux(vector unsigned int __a, int __b) { + return __builtin_altivec_vcfux((vector int)__a, __b); +} + +/* vec_cts */ + +static vector int __attribute__((__always_inline__)) +vec_cts(vector float __a, int __b) { + return __builtin_altivec_vctsxs(__a, __b); +} + +/* vec_vctsxs */ + +static vector int __attribute__((__always_inline__)) +vec_vctsxs(vector float __a, int __b) { + return __builtin_altivec_vctsxs(__a, __b); +} + +/* vec_ctu */ + +static vector unsigned int __attribute__((__always_inline__)) +vec_ctu(vector float __a, int __b) { + return __builtin_altivec_vctuxs(__a, __b); +} + +/* vec_vctuxs */ + +static vector unsigned int __attribute__((__always_inline__)) +vec_vctuxs(vector float __a, int __b) { + return __builtin_altivec_vctuxs(__a, __b); +} + +/* vec_double */ + +#ifdef __VSX__ +static vector double __ATTRS_o_ai vec_double (vector signed long long __a) { + vector double __ret = { __a[0], __a[1] }; + return __ret; +} + +static vector double __ATTRS_o_ai vec_double (vector unsigned long long __a) { + vector double __ret = { __a[0], __a[1] }; + return __ret; +} +#endif + +/* vec_div */ + +/* Integer vector divides (vectors are scalarized, elements divided + and the vectors reassembled). +*/ +static vector signed char __ATTRS_o_ai vec_div(vector signed char __a, + vector signed char __b) { + return __a / __b; +} + +static vector unsigned char __ATTRS_o_ai vec_div(vector unsigned char __a, + vector unsigned char __b) { + return __a / __b; +} + +static vector signed short __ATTRS_o_ai vec_div(vector signed short __a, + vector signed short __b) { + return __a / __b; +} + +static vector unsigned short __ATTRS_o_ai vec_div(vector unsigned short __a, + vector unsigned short __b) { + return __a / __b; +} + +static vector signed int __ATTRS_o_ai vec_div(vector signed int __a, + vector signed int __b) { + return __a / __b; +} + +static vector unsigned int __ATTRS_o_ai vec_div(vector unsigned int __a, + vector unsigned int __b) { + return __a / __b; +} + +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai +vec_div(vector signed long long __a, vector signed long long __b) { + return __a / __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_div(vector unsigned long long __a, vector unsigned long long __b) { + return __a / __b; +} + +static vector float __ATTRS_o_ai vec_div(vector float __a, vector float __b) { + return __a / __b; +} + +static vector double __ATTRS_o_ai vec_div(vector double __a, + vector double __b) { + return __a / __b; +} +#endif + +/* vec_dss */ + +static void __attribute__((__always_inline__)) vec_dss(int __a) { + __builtin_altivec_dss(__a); +} + +/* vec_dssall */ + +static void __attribute__((__always_inline__)) vec_dssall(void) { + __builtin_altivec_dssall(); +} + +/* vec_dst */ + +static void __attribute__((__always_inline__)) +vec_dst(const void *__a, int __b, int __c) { + __builtin_altivec_dst(__a, __b, __c); +} + +/* vec_dstst */ + +static void __attribute__((__always_inline__)) +vec_dstst(const void *__a, int __b, int __c) { + __builtin_altivec_dstst(__a, __b, __c); +} + +/* vec_dststt */ + +static void __attribute__((__always_inline__)) +vec_dststt(const void *__a, int __b, int __c) { + __builtin_altivec_dststt(__a, __b, __c); +} + +/* vec_dstt */ + +static void __attribute__((__always_inline__)) +vec_dstt(const void *__a, int __b, int __c) { + __builtin_altivec_dstt(__a, __b, __c); +} + +/* vec_eqv */ + +#ifdef __POWER8_VECTOR__ +static vector signed char __ATTRS_o_ai vec_eqv(vector signed char __a, + vector signed char __b) { + return (vector signed char)__builtin_vsx_xxleqv((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_eqv(vector unsigned char __a, + vector unsigned char __b) { + return (vector unsigned char)__builtin_vsx_xxleqv((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static vector bool char __ATTRS_o_ai vec_eqv(vector bool char __a, + vector bool char __b) { + return (vector bool char)__builtin_vsx_xxleqv((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static vector signed short __ATTRS_o_ai vec_eqv(vector signed short __a, + vector signed short __b) { + return (vector signed short)__builtin_vsx_xxleqv((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_eqv(vector unsigned short __a, + vector unsigned short __b) { + return (vector unsigned short)__builtin_vsx_xxleqv((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static vector bool short __ATTRS_o_ai vec_eqv(vector bool short __a, + vector bool short __b) { + return (vector bool short)__builtin_vsx_xxleqv((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static vector signed int __ATTRS_o_ai vec_eqv(vector signed int __a, + vector signed int __b) { + return (vector signed int)__builtin_vsx_xxleqv((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_eqv(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_vsx_xxleqv(__a, __b); +} + +static vector bool int __ATTRS_o_ai vec_eqv(vector bool int __a, + vector bool int __b) { + return (vector bool int)__builtin_vsx_xxleqv((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static vector signed long long __ATTRS_o_ai +vec_eqv(vector signed long long __a, vector signed long long __b) { + return (vector signed long long) + __builtin_vsx_xxleqv((vector unsigned int)__a, (vector unsigned int)__b); +} + +static vector unsigned long long __ATTRS_o_ai +vec_eqv(vector unsigned long long __a, vector unsigned long long __b) { + return (vector unsigned long long) + __builtin_vsx_xxleqv((vector unsigned int)__a, (vector unsigned int)__b); +} + +static vector bool long long __ATTRS_o_ai +vec_eqv(vector bool long long __a, vector bool long long __b) { + return (vector bool long long) + __builtin_vsx_xxleqv((vector unsigned int)__a, (vector unsigned int)__b); +} + +static vector float __ATTRS_o_ai vec_eqv(vector float __a, vector float __b) { + return (vector float)__builtin_vsx_xxleqv((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static vector double __ATTRS_o_ai vec_eqv(vector double __a, + vector double __b) { + return (vector double)__builtin_vsx_xxleqv((vector unsigned int)__a, + (vector unsigned int)__b); +} +#endif + +/* vec_expte */ + +static vector float __attribute__((__always_inline__)) +vec_expte(vector float __a) { + return __builtin_altivec_vexptefp(__a); +} + +/* vec_vexptefp */ + +static vector float __attribute__((__always_inline__)) +vec_vexptefp(vector float __a) { + return __builtin_altivec_vexptefp(__a); +} + +/* vec_floor */ + +static vector float __ATTRS_o_ai vec_floor(vector float __a) { +#ifdef __VSX__ + return __builtin_vsx_xvrspim(__a); +#else + return __builtin_altivec_vrfim(__a); +#endif +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai vec_floor(vector double __a) { + return __builtin_vsx_xvrdpim(__a); +} +#endif + +/* vec_vrfim */ + +static vector float __attribute__((__always_inline__)) +vec_vrfim(vector float __a) { + return __builtin_altivec_vrfim(__a); +} + +/* vec_ld */ + +static vector signed char __ATTRS_o_ai vec_ld(int __a, + const vector signed char *__b) { + return (vector signed char)__builtin_altivec_lvx(__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_ld(int __a, const signed char *__b) { + return (vector signed char)__builtin_altivec_lvx(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai +vec_ld(int __a, const vector unsigned char *__b) { + return (vector unsigned char)__builtin_altivec_lvx(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_ld(int __a, + const unsigned char *__b) { + return (vector unsigned char)__builtin_altivec_lvx(__a, __b); +} + +static vector bool char __ATTRS_o_ai vec_ld(int __a, + const vector bool char *__b) { + return (vector bool char)__builtin_altivec_lvx(__a, __b); +} + +static vector short __ATTRS_o_ai vec_ld(int __a, const vector short *__b) { + return (vector short)__builtin_altivec_lvx(__a, __b); +} + +static vector short __ATTRS_o_ai vec_ld(int __a, const short *__b) { + return (vector short)__builtin_altivec_lvx(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai +vec_ld(int __a, const vector unsigned short *__b) { + return (vector unsigned short)__builtin_altivec_lvx(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_ld(int __a, + const unsigned short *__b) { + return (vector unsigned short)__builtin_altivec_lvx(__a, __b); +} + +static vector bool short __ATTRS_o_ai vec_ld(int __a, + const vector bool short *__b) { + return (vector bool short)__builtin_altivec_lvx(__a, __b); +} + +static vector pixel __ATTRS_o_ai vec_ld(int __a, const vector pixel *__b) { + return (vector pixel)__builtin_altivec_lvx(__a, __b); +} + +static vector int __ATTRS_o_ai vec_ld(int __a, const vector int *__b) { + return (vector int)__builtin_altivec_lvx(__a, __b); +} + +static vector int __ATTRS_o_ai vec_ld(int __a, const int *__b) { + return (vector int)__builtin_altivec_lvx(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_ld(int __a, + const vector unsigned int *__b) { + return (vector unsigned int)__builtin_altivec_lvx(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_ld(int __a, + const unsigned int *__b) { + return (vector unsigned int)__builtin_altivec_lvx(__a, __b); +} + +static vector bool int __ATTRS_o_ai vec_ld(int __a, + const vector bool int *__b) { + return (vector bool int)__builtin_altivec_lvx(__a, __b); +} + +static vector float __ATTRS_o_ai vec_ld(int __a, const vector float *__b) { + return (vector float)__builtin_altivec_lvx(__a, __b); +} + +static vector float __ATTRS_o_ai vec_ld(int __a, const float *__b) { + return (vector float)__builtin_altivec_lvx(__a, __b); +} + +/* vec_lvx */ + +static vector signed char __ATTRS_o_ai vec_lvx(int __a, + const vector signed char *__b) { + return (vector signed char)__builtin_altivec_lvx(__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_lvx(int __a, + const signed char *__b) { + return (vector signed char)__builtin_altivec_lvx(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai +vec_lvx(int __a, const vector unsigned char *__b) { + return (vector unsigned char)__builtin_altivec_lvx(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_lvx(int __a, + const unsigned char *__b) { + return (vector unsigned char)__builtin_altivec_lvx(__a, __b); +} + +static vector bool char __ATTRS_o_ai vec_lvx(int __a, + const vector bool char *__b) { + return (vector bool char)__builtin_altivec_lvx(__a, __b); +} + +static vector short __ATTRS_o_ai vec_lvx(int __a, const vector short *__b) { + return (vector short)__builtin_altivec_lvx(__a, __b); +} + +static vector short __ATTRS_o_ai vec_lvx(int __a, const short *__b) { + return (vector short)__builtin_altivec_lvx(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai +vec_lvx(int __a, const vector unsigned short *__b) { + return (vector unsigned short)__builtin_altivec_lvx(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_lvx(int __a, + const unsigned short *__b) { + return (vector unsigned short)__builtin_altivec_lvx(__a, __b); +} + +static vector bool short __ATTRS_o_ai vec_lvx(int __a, + const vector bool short *__b) { + return (vector bool short)__builtin_altivec_lvx(__a, __b); +} + +static vector pixel __ATTRS_o_ai vec_lvx(int __a, const vector pixel *__b) { + return (vector pixel)__builtin_altivec_lvx(__a, __b); +} + +static vector int __ATTRS_o_ai vec_lvx(int __a, const vector int *__b) { + return (vector int)__builtin_altivec_lvx(__a, __b); +} + +static vector int __ATTRS_o_ai vec_lvx(int __a, const int *__b) { + return (vector int)__builtin_altivec_lvx(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai +vec_lvx(int __a, const vector unsigned int *__b) { + return (vector unsigned int)__builtin_altivec_lvx(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_lvx(int __a, + const unsigned int *__b) { + return (vector unsigned int)__builtin_altivec_lvx(__a, __b); +} + +static vector bool int __ATTRS_o_ai vec_lvx(int __a, + const vector bool int *__b) { + return (vector bool int)__builtin_altivec_lvx(__a, __b); +} + +static vector float __ATTRS_o_ai vec_lvx(int __a, const vector float *__b) { + return (vector float)__builtin_altivec_lvx(__a, __b); +} + +static vector float __ATTRS_o_ai vec_lvx(int __a, const float *__b) { + return (vector float)__builtin_altivec_lvx(__a, __b); +} + +/* vec_lde */ + +static vector signed char __ATTRS_o_ai vec_lde(int __a, + const signed char *__b) { + return (vector signed char)__builtin_altivec_lvebx(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_lde(int __a, + const unsigned char *__b) { + return (vector unsigned char)__builtin_altivec_lvebx(__a, __b); +} + +static vector short __ATTRS_o_ai vec_lde(int __a, const short *__b) { + return (vector short)__builtin_altivec_lvehx(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_lde(int __a, + const unsigned short *__b) { + return (vector unsigned short)__builtin_altivec_lvehx(__a, __b); +} + +static vector int __ATTRS_o_ai vec_lde(int __a, const int *__b) { + return (vector int)__builtin_altivec_lvewx(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_lde(int __a, + const unsigned int *__b) { + return (vector unsigned int)__builtin_altivec_lvewx(__a, __b); +} + +static vector float __ATTRS_o_ai vec_lde(int __a, const float *__b) { + return (vector float)__builtin_altivec_lvewx(__a, __b); +} + +/* vec_lvebx */ + +static vector signed char __ATTRS_o_ai vec_lvebx(int __a, + const signed char *__b) { + return (vector signed char)__builtin_altivec_lvebx(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_lvebx(int __a, + const unsigned char *__b) { + return (vector unsigned char)__builtin_altivec_lvebx(__a, __b); +} + +/* vec_lvehx */ + +static vector short __ATTRS_o_ai vec_lvehx(int __a, const short *__b) { + return (vector short)__builtin_altivec_lvehx(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_lvehx(int __a, + const unsigned short *__b) { + return (vector unsigned short)__builtin_altivec_lvehx(__a, __b); +} + +/* vec_lvewx */ + +static vector int __ATTRS_o_ai vec_lvewx(int __a, const int *__b) { + return (vector int)__builtin_altivec_lvewx(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_lvewx(int __a, + const unsigned int *__b) { + return (vector unsigned int)__builtin_altivec_lvewx(__a, __b); +} + +static vector float __ATTRS_o_ai vec_lvewx(int __a, const float *__b) { + return (vector float)__builtin_altivec_lvewx(__a, __b); +} + +/* vec_ldl */ + +static vector signed char __ATTRS_o_ai vec_ldl(int __a, + const vector signed char *__b) { + return (vector signed char)__builtin_altivec_lvxl(__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_ldl(int __a, + const signed char *__b) { + return (vector signed char)__builtin_altivec_lvxl(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai +vec_ldl(int __a, const vector unsigned char *__b) { + return (vector unsigned char)__builtin_altivec_lvxl(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_ldl(int __a, + const unsigned char *__b) { + return (vector unsigned char)__builtin_altivec_lvxl(__a, __b); +} + +static vector bool char __ATTRS_o_ai vec_ldl(int __a, + const vector bool char *__b) { + return (vector bool char)__builtin_altivec_lvxl(__a, __b); +} + +static vector short __ATTRS_o_ai vec_ldl(int __a, const vector short *__b) { + return (vector short)__builtin_altivec_lvxl(__a, __b); +} + +static vector short __ATTRS_o_ai vec_ldl(int __a, const short *__b) { + return (vector short)__builtin_altivec_lvxl(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai +vec_ldl(int __a, const vector unsigned short *__b) { + return (vector unsigned short)__builtin_altivec_lvxl(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_ldl(int __a, + const unsigned short *__b) { + return (vector unsigned short)__builtin_altivec_lvxl(__a, __b); +} + +static vector bool short __ATTRS_o_ai vec_ldl(int __a, + const vector bool short *__b) { + return (vector bool short)__builtin_altivec_lvxl(__a, __b); +} + +static vector pixel __ATTRS_o_ai vec_ldl(int __a, const vector pixel *__b) { + return (vector pixel short)__builtin_altivec_lvxl(__a, __b); +} + +static vector int __ATTRS_o_ai vec_ldl(int __a, const vector int *__b) { + return (vector int)__builtin_altivec_lvxl(__a, __b); +} + +static vector int __ATTRS_o_ai vec_ldl(int __a, const int *__b) { + return (vector int)__builtin_altivec_lvxl(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai +vec_ldl(int __a, const vector unsigned int *__b) { + return (vector unsigned int)__builtin_altivec_lvxl(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_ldl(int __a, + const unsigned int *__b) { + return (vector unsigned int)__builtin_altivec_lvxl(__a, __b); +} + +static vector bool int __ATTRS_o_ai vec_ldl(int __a, + const vector bool int *__b) { + return (vector bool int)__builtin_altivec_lvxl(__a, __b); +} + +static vector float __ATTRS_o_ai vec_ldl(int __a, const vector float *__b) { + return (vector float)__builtin_altivec_lvxl(__a, __b); +} + +static vector float __ATTRS_o_ai vec_ldl(int __a, const float *__b) { + return (vector float)__builtin_altivec_lvxl(__a, __b); +} + +/* vec_lvxl */ + +static vector signed char __ATTRS_o_ai vec_lvxl(int __a, + const vector signed char *__b) { + return (vector signed char)__builtin_altivec_lvxl(__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_lvxl(int __a, + const signed char *__b) { + return (vector signed char)__builtin_altivec_lvxl(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai +vec_lvxl(int __a, const vector unsigned char *__b) { + return (vector unsigned char)__builtin_altivec_lvxl(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_lvxl(int __a, + const unsigned char *__b) { + return (vector unsigned char)__builtin_altivec_lvxl(__a, __b); +} + +static vector bool char __ATTRS_o_ai vec_lvxl(int __a, + const vector bool char *__b) { + return (vector bool char)__builtin_altivec_lvxl(__a, __b); +} + +static vector short __ATTRS_o_ai vec_lvxl(int __a, const vector short *__b) { + return (vector short)__builtin_altivec_lvxl(__a, __b); +} + +static vector short __ATTRS_o_ai vec_lvxl(int __a, const short *__b) { + return (vector short)__builtin_altivec_lvxl(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai +vec_lvxl(int __a, const vector unsigned short *__b) { + return (vector unsigned short)__builtin_altivec_lvxl(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_lvxl(int __a, + const unsigned short *__b) { + return (vector unsigned short)__builtin_altivec_lvxl(__a, __b); +} + +static vector bool short __ATTRS_o_ai vec_lvxl(int __a, + const vector bool short *__b) { + return (vector bool short)__builtin_altivec_lvxl(__a, __b); +} + +static vector pixel __ATTRS_o_ai vec_lvxl(int __a, const vector pixel *__b) { + return (vector pixel)__builtin_altivec_lvxl(__a, __b); +} + +static vector int __ATTRS_o_ai vec_lvxl(int __a, const vector int *__b) { + return (vector int)__builtin_altivec_lvxl(__a, __b); +} + +static vector int __ATTRS_o_ai vec_lvxl(int __a, const int *__b) { + return (vector int)__builtin_altivec_lvxl(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai +vec_lvxl(int __a, const vector unsigned int *__b) { + return (vector unsigned int)__builtin_altivec_lvxl(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_lvxl(int __a, + const unsigned int *__b) { + return (vector unsigned int)__builtin_altivec_lvxl(__a, __b); +} + +static vector bool int __ATTRS_o_ai vec_lvxl(int __a, + const vector bool int *__b) { + return (vector bool int)__builtin_altivec_lvxl(__a, __b); +} + +static vector float __ATTRS_o_ai vec_lvxl(int __a, const vector float *__b) { + return (vector float)__builtin_altivec_lvxl(__a, __b); +} + +static vector float __ATTRS_o_ai vec_lvxl(int __a, const float *__b) { + return (vector float)__builtin_altivec_lvxl(__a, __b); +} + +/* vec_loge */ + +static vector float __attribute__((__always_inline__)) +vec_loge(vector float __a) { + return __builtin_altivec_vlogefp(__a); +} + +/* vec_vlogefp */ + +static vector float __attribute__((__always_inline__)) +vec_vlogefp(vector float __a) { + return __builtin_altivec_vlogefp(__a); +} + +/* vec_lvsl */ + +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai + __attribute__((__deprecated__("use assignment for unaligned little endian \ +loads/stores"))) vec_lvsl(int __a, const signed char *__b) { + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsl(__a, __b); + vector unsigned char reverse = {15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0}; + return vec_perm(mask, mask, reverse); +} +#else +static vector unsigned char __ATTRS_o_ai vec_lvsl(int __a, + const signed char *__b) { + return (vector unsigned char)__builtin_altivec_lvsl(__a, __b); +} +#endif + +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai + __attribute__((__deprecated__("use assignment for unaligned little endian \ +loads/stores"))) vec_lvsl(int __a, const unsigned char *__b) { + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsl(__a, __b); + vector unsigned char reverse = {15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0}; + return vec_perm(mask, mask, reverse); +} +#else +static vector unsigned char __ATTRS_o_ai vec_lvsl(int __a, + const unsigned char *__b) { + return (vector unsigned char)__builtin_altivec_lvsl(__a, __b); +} +#endif + +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai + __attribute__((__deprecated__("use assignment for unaligned little endian \ +loads/stores"))) vec_lvsl(int __a, const short *__b) { + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsl(__a, __b); + vector unsigned char reverse = {15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0}; + return vec_perm(mask, mask, reverse); +} +#else +static vector unsigned char __ATTRS_o_ai vec_lvsl(int __a, const short *__b) { + return (vector unsigned char)__builtin_altivec_lvsl(__a, __b); +} +#endif + +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai + __attribute__((__deprecated__("use assignment for unaligned little endian \ +loads/stores"))) vec_lvsl(int __a, const unsigned short *__b) { + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsl(__a, __b); + vector unsigned char reverse = {15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0}; + return vec_perm(mask, mask, reverse); +} +#else +static vector unsigned char __ATTRS_o_ai vec_lvsl(int __a, + const unsigned short *__b) { + return (vector unsigned char)__builtin_altivec_lvsl(__a, __b); +} +#endif + +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai + __attribute__((__deprecated__("use assignment for unaligned little endian \ +loads/stores"))) vec_lvsl(int __a, const int *__b) { + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsl(__a, __b); + vector unsigned char reverse = {15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0}; + return vec_perm(mask, mask, reverse); +} +#else +static vector unsigned char __ATTRS_o_ai vec_lvsl(int __a, const int *__b) { + return (vector unsigned char)__builtin_altivec_lvsl(__a, __b); +} +#endif + +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai + __attribute__((__deprecated__("use assignment for unaligned little endian \ +loads/stores"))) vec_lvsl(int __a, const unsigned int *__b) { + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsl(__a, __b); + vector unsigned char reverse = {15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0}; + return vec_perm(mask, mask, reverse); +} +#else +static vector unsigned char __ATTRS_o_ai vec_lvsl(int __a, + const unsigned int *__b) { + return (vector unsigned char)__builtin_altivec_lvsl(__a, __b); +} +#endif + +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai + __attribute__((__deprecated__("use assignment for unaligned little endian \ +loads/stores"))) vec_lvsl(int __a, const float *__b) { + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsl(__a, __b); + vector unsigned char reverse = {15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0}; + return vec_perm(mask, mask, reverse); +} +#else +static vector unsigned char __ATTRS_o_ai vec_lvsl(int __a, const float *__b) { + return (vector unsigned char)__builtin_altivec_lvsl(__a, __b); +} +#endif + +/* vec_lvsr */ + +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai + __attribute__((__deprecated__("use assignment for unaligned little endian \ +loads/stores"))) vec_lvsr(int __a, const signed char *__b) { + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsr(__a, __b); + vector unsigned char reverse = {15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0}; + return vec_perm(mask, mask, reverse); +} +#else +static vector unsigned char __ATTRS_o_ai vec_lvsr(int __a, + const signed char *__b) { + return (vector unsigned char)__builtin_altivec_lvsr(__a, __b); +} +#endif + +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai + __attribute__((__deprecated__("use assignment for unaligned little endian \ +loads/stores"))) vec_lvsr(int __a, const unsigned char *__b) { + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsr(__a, __b); + vector unsigned char reverse = {15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0}; + return vec_perm(mask, mask, reverse); +} +#else +static vector unsigned char __ATTRS_o_ai vec_lvsr(int __a, + const unsigned char *__b) { + return (vector unsigned char)__builtin_altivec_lvsr(__a, __b); +} +#endif + +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai + __attribute__((__deprecated__("use assignment for unaligned little endian \ +loads/stores"))) vec_lvsr(int __a, const short *__b) { + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsr(__a, __b); + vector unsigned char reverse = {15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0}; + return vec_perm(mask, mask, reverse); +} +#else +static vector unsigned char __ATTRS_o_ai vec_lvsr(int __a, const short *__b) { + return (vector unsigned char)__builtin_altivec_lvsr(__a, __b); +} +#endif + +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai + __attribute__((__deprecated__("use assignment for unaligned little endian \ +loads/stores"))) vec_lvsr(int __a, const unsigned short *__b) { + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsr(__a, __b); + vector unsigned char reverse = {15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0}; + return vec_perm(mask, mask, reverse); +} +#else +static vector unsigned char __ATTRS_o_ai vec_lvsr(int __a, + const unsigned short *__b) { + return (vector unsigned char)__builtin_altivec_lvsr(__a, __b); +} +#endif + +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai + __attribute__((__deprecated__("use assignment for unaligned little endian \ +loads/stores"))) vec_lvsr(int __a, const int *__b) { + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsr(__a, __b); + vector unsigned char reverse = {15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0}; + return vec_perm(mask, mask, reverse); +} +#else +static vector unsigned char __ATTRS_o_ai vec_lvsr(int __a, const int *__b) { + return (vector unsigned char)__builtin_altivec_lvsr(__a, __b); +} +#endif + +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai + __attribute__((__deprecated__("use assignment for unaligned little endian \ +loads/stores"))) vec_lvsr(int __a, const unsigned int *__b) { + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsr(__a, __b); + vector unsigned char reverse = {15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0}; + return vec_perm(mask, mask, reverse); +} +#else +static vector unsigned char __ATTRS_o_ai vec_lvsr(int __a, + const unsigned int *__b) { + return (vector unsigned char)__builtin_altivec_lvsr(__a, __b); +} +#endif + +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai + __attribute__((__deprecated__("use assignment for unaligned little endian \ +loads/stores"))) vec_lvsr(int __a, const float *__b) { + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsr(__a, __b); + vector unsigned char reverse = {15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0}; + return vec_perm(mask, mask, reverse); +} +#else +static vector unsigned char __ATTRS_o_ai vec_lvsr(int __a, const float *__b) { + return (vector unsigned char)__builtin_altivec_lvsr(__a, __b); +} +#endif + +/* vec_madd */ +static vector signed short __ATTRS_o_ai +vec_mladd(vector signed short, vector signed short, vector signed short); +static vector signed short __ATTRS_o_ai +vec_mladd(vector signed short, vector unsigned short, vector unsigned short); +static vector signed short __ATTRS_o_ai +vec_mladd(vector unsigned short, vector signed short, vector signed short); +static vector unsigned short __ATTRS_o_ai +vec_mladd(vector unsigned short, vector unsigned short, vector unsigned short); + +static vector signed short __ATTRS_o_ai +vec_madd(vector signed short __a, vector signed short __b, + vector signed short __c) { + return vec_mladd(__a, __b, __c); +} + +static vector signed short __ATTRS_o_ai +vec_madd(vector signed short __a, vector unsigned short __b, + vector unsigned short __c) { + return vec_mladd(__a, __b, __c); +} + +static vector signed short __ATTRS_o_ai +vec_madd(vector unsigned short __a, vector signed short __b, + vector signed short __c) { + return vec_mladd(__a, __b, __c); +} + +static vector unsigned short __ATTRS_o_ai +vec_madd(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c) { + return vec_mladd(__a, __b, __c); +} + +static vector float __ATTRS_o_ai +vec_madd(vector float __a, vector float __b, vector float __c) { +#ifdef __VSX__ + return __builtin_vsx_xvmaddasp(__a, __b, __c); +#else + return __builtin_altivec_vmaddfp(__a, __b, __c); +#endif +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai +vec_madd(vector double __a, vector double __b, vector double __c) { + return __builtin_vsx_xvmaddadp(__a, __b, __c); +} +#endif + +/* vec_vmaddfp */ + +static vector float __attribute__((__always_inline__)) +vec_vmaddfp(vector float __a, vector float __b, vector float __c) { + return __builtin_altivec_vmaddfp(__a, __b, __c); +} + +/* vec_madds */ + +static vector signed short __attribute__((__always_inline__)) +vec_madds(vector signed short __a, vector signed short __b, + vector signed short __c) { + return __builtin_altivec_vmhaddshs(__a, __b, __c); +} + +/* vec_vmhaddshs */ +static vector signed short __attribute__((__always_inline__)) +vec_vmhaddshs(vector signed short __a, vector signed short __b, + vector signed short __c) { + return __builtin_altivec_vmhaddshs(__a, __b, __c); +} + +/* vec_msub */ + +#ifdef __VSX__ +static vector float __ATTRS_o_ai +vec_msub(vector float __a, vector float __b, vector float __c) { + return __builtin_vsx_xvmsubasp(__a, __b, __c); +} + +static vector double __ATTRS_o_ai +vec_msub(vector double __a, vector double __b, vector double __c) { + return __builtin_vsx_xvmsubadp(__a, __b, __c); +} +#endif + +/* vec_max */ + +static vector signed char __ATTRS_o_ai vec_max(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vmaxsb(__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_max(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vmaxsb((vector signed char)__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_max(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vmaxsb(__a, (vector signed char)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_max(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vmaxub(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_max(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vmaxub((vector unsigned char)__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_max(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vmaxub(__a, (vector unsigned char)__b); +} + +static vector short __ATTRS_o_ai vec_max(vector short __a, vector short __b) { + return __builtin_altivec_vmaxsh(__a, __b); +} + +static vector short __ATTRS_o_ai vec_max(vector bool short __a, + vector short __b) { + return __builtin_altivec_vmaxsh((vector short)__a, __b); +} + +static vector short __ATTRS_o_ai vec_max(vector short __a, + vector bool short __b) { + return __builtin_altivec_vmaxsh(__a, (vector short)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_max(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vmaxuh(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_max(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vmaxuh((vector unsigned short)__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_max(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vmaxuh(__a, (vector unsigned short)__b); +} + +static vector int __ATTRS_o_ai vec_max(vector int __a, vector int __b) { + return __builtin_altivec_vmaxsw(__a, __b); +} + +static vector int __ATTRS_o_ai vec_max(vector bool int __a, vector int __b) { + return __builtin_altivec_vmaxsw((vector int)__a, __b); +} + +static vector int __ATTRS_o_ai vec_max(vector int __a, vector bool int __b) { + return __builtin_altivec_vmaxsw(__a, (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_max(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vmaxuw(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_max(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vmaxuw((vector unsigned int)__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_max(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vmaxuw(__a, (vector unsigned int)__b); +} + +#ifdef __POWER8_VECTOR__ +static vector signed long long __ATTRS_o_ai +vec_max(vector signed long long __a, vector signed long long __b) { + return __builtin_altivec_vmaxsd(__a, __b); +} + +static vector signed long long __ATTRS_o_ai +vec_max(vector bool long long __a, vector signed long long __b) { + return __builtin_altivec_vmaxsd((vector signed long long)__a, __b); +} + +static vector signed long long __ATTRS_o_ai vec_max(vector signed long long __a, + vector bool long long __b) { + return __builtin_altivec_vmaxsd(__a, (vector signed long long)__b); +} + +static vector unsigned long long __ATTRS_o_ai +vec_max(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_altivec_vmaxud(__a, __b); +} + +static vector unsigned long long __ATTRS_o_ai +vec_max(vector bool long long __a, vector unsigned long long __b) { + return __builtin_altivec_vmaxud((vector unsigned long long)__a, __b); +} + +static vector unsigned long long __ATTRS_o_ai +vec_max(vector unsigned long long __a, vector bool long long __b) { + return __builtin_altivec_vmaxud(__a, (vector unsigned long long)__b); +} +#endif + +static vector float __ATTRS_o_ai vec_max(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvmaxsp(__a, __b); +#else + return __builtin_altivec_vmaxfp(__a, __b); +#endif +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai vec_max(vector double __a, + vector double __b) { + return __builtin_vsx_xvmaxdp(__a, __b); +} +#endif + +/* vec_vmaxsb */ + +static vector signed char __ATTRS_o_ai vec_vmaxsb(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vmaxsb(__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_vmaxsb(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vmaxsb((vector signed char)__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_vmaxsb(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vmaxsb(__a, (vector signed char)__b); +} + +/* vec_vmaxub */ + +static vector unsigned char __ATTRS_o_ai vec_vmaxub(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vmaxub(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_vmaxub(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vmaxub((vector unsigned char)__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_vmaxub(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vmaxub(__a, (vector unsigned char)__b); +} + +/* vec_vmaxsh */ + +static vector short __ATTRS_o_ai vec_vmaxsh(vector short __a, + vector short __b) { + return __builtin_altivec_vmaxsh(__a, __b); +} + +static vector short __ATTRS_o_ai vec_vmaxsh(vector bool short __a, + vector short __b) { + return __builtin_altivec_vmaxsh((vector short)__a, __b); +} + +static vector short __ATTRS_o_ai vec_vmaxsh(vector short __a, + vector bool short __b) { + return __builtin_altivec_vmaxsh(__a, (vector short)__b); +} + +/* vec_vmaxuh */ + +static vector unsigned short __ATTRS_o_ai +vec_vmaxuh(vector unsigned short __a, vector unsigned short __b) { + return __builtin_altivec_vmaxuh(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai +vec_vmaxuh(vector bool short __a, vector unsigned short __b) { + return __builtin_altivec_vmaxuh((vector unsigned short)__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_vmaxuh(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vmaxuh(__a, (vector unsigned short)__b); +} + +/* vec_vmaxsw */ + +static vector int __ATTRS_o_ai vec_vmaxsw(vector int __a, vector int __b) { + return __builtin_altivec_vmaxsw(__a, __b); +} + +static vector int __ATTRS_o_ai vec_vmaxsw(vector bool int __a, vector int __b) { + return __builtin_altivec_vmaxsw((vector int)__a, __b); +} + +static vector int __ATTRS_o_ai vec_vmaxsw(vector int __a, vector bool int __b) { + return __builtin_altivec_vmaxsw(__a, (vector int)__b); +} + +/* vec_vmaxuw */ + +static vector unsigned int __ATTRS_o_ai vec_vmaxuw(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vmaxuw(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_vmaxuw(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vmaxuw((vector unsigned int)__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_vmaxuw(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vmaxuw(__a, (vector unsigned int)__b); +} + +/* vec_vmaxfp */ + +static vector float __attribute__((__always_inline__)) +vec_vmaxfp(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvmaxsp(__a, __b); +#else + return __builtin_altivec_vmaxfp(__a, __b); +#endif +} + +/* vec_mergeh */ + +static vector signed char __ATTRS_o_ai vec_mergeh(vector signed char __a, + vector signed char __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x10, 0x01, 0x11, 0x02, 0x12, + 0x03, 0x13, 0x04, 0x14, 0x05, 0x15, + 0x06, 0x16, 0x07, 0x17)); +} + +static vector unsigned char __ATTRS_o_ai vec_mergeh(vector unsigned char __a, + vector unsigned char __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x10, 0x01, 0x11, 0x02, 0x12, + 0x03, 0x13, 0x04, 0x14, 0x05, 0x15, + 0x06, 0x16, 0x07, 0x17)); +} + +static vector bool char __ATTRS_o_ai vec_mergeh(vector bool char __a, + vector bool char __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x10, 0x01, 0x11, 0x02, 0x12, + 0x03, 0x13, 0x04, 0x14, 0x05, 0x15, + 0x06, 0x16, 0x07, 0x17)); +} + +static vector short __ATTRS_o_ai vec_mergeh(vector short __a, + vector short __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x10, 0x11, 0x02, 0x03, + 0x12, 0x13, 0x04, 0x05, 0x14, 0x15, + 0x06, 0x07, 0x16, 0x17)); +} + +static vector unsigned short __ATTRS_o_ai +vec_mergeh(vector unsigned short __a, vector unsigned short __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x10, 0x11, 0x02, 0x03, + 0x12, 0x13, 0x04, 0x05, 0x14, 0x15, + 0x06, 0x07, 0x16, 0x17)); +} + +static vector bool short __ATTRS_o_ai vec_mergeh(vector bool short __a, + vector bool short __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x10, 0x11, 0x02, 0x03, + 0x12, 0x13, 0x04, 0x05, 0x14, 0x15, + 0x06, 0x07, 0x16, 0x17)); +} + +static vector pixel __ATTRS_o_ai vec_mergeh(vector pixel __a, + vector pixel __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x10, 0x11, 0x02, 0x03, + 0x12, 0x13, 0x04, 0x05, 0x14, 0x15, + 0x06, 0x07, 0x16, 0x17)); +} + +static vector int __ATTRS_o_ai vec_mergeh(vector int __a, vector int __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, 0x10, 0x11, + 0x12, 0x13, 0x04, 0x05, 0x06, 0x07, + 0x14, 0x15, 0x16, 0x17)); +} + +static vector unsigned int __ATTRS_o_ai vec_mergeh(vector unsigned int __a, + vector unsigned int __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, 0x10, 0x11, + 0x12, 0x13, 0x04, 0x05, 0x06, 0x07, + 0x14, 0x15, 0x16, 0x17)); +} + +static vector bool int __ATTRS_o_ai vec_mergeh(vector bool int __a, + vector bool int __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, 0x10, 0x11, + 0x12, 0x13, 0x04, 0x05, 0x06, 0x07, + 0x14, 0x15, 0x16, 0x17)); +} + +static vector float __ATTRS_o_ai vec_mergeh(vector float __a, + vector float __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, 0x10, 0x11, + 0x12, 0x13, 0x04, 0x05, 0x06, 0x07, + 0x14, 0x15, 0x16, 0x17)); +} + +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai +vec_mergeh(vector signed long long __a, vector signed long long __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17)); +} + +static vector signed long long __ATTRS_o_ai +vec_mergeh(vector signed long long __a, vector bool long long __b) { + return vec_perm(__a, (vector signed long long)__b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17)); +} + +static vector signed long long __ATTRS_o_ai +vec_mergeh(vector bool long long __a, vector signed long long __b) { + return vec_perm((vector signed long long)__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17)); +} + +static vector unsigned long long __ATTRS_o_ai +vec_mergeh(vector unsigned long long __a, vector unsigned long long __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17)); +} + +static vector unsigned long long __ATTRS_o_ai +vec_mergeh(vector unsigned long long __a, vector bool long long __b) { + return vec_perm(__a, (vector unsigned long long)__b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17)); +} + +static vector unsigned long long __ATTRS_o_ai +vec_mergeh(vector bool long long __a, vector unsigned long long __b) { + return vec_perm((vector unsigned long long)__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17)); +} + +static vector bool long long __ATTRS_o_ai +vec_mergeh(vector bool long long __a, vector bool long long __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17)); +} + +static vector double __ATTRS_o_ai vec_mergeh(vector double __a, + vector double __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17)); +} +static vector double __ATTRS_o_ai vec_mergeh(vector double __a, + vector bool long long __b) { + return vec_perm(__a, (vector double)__b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17)); +} +static vector double __ATTRS_o_ai vec_mergeh(vector bool long long __a, + vector double __b) { + return vec_perm((vector double)__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17)); +} +#endif + +/* vec_vmrghb */ + +#define __builtin_altivec_vmrghb vec_vmrghb + +static vector signed char __ATTRS_o_ai vec_vmrghb(vector signed char __a, + vector signed char __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x10, 0x01, 0x11, 0x02, 0x12, + 0x03, 0x13, 0x04, 0x14, 0x05, 0x15, + 0x06, 0x16, 0x07, 0x17)); +} + +static vector unsigned char __ATTRS_o_ai vec_vmrghb(vector unsigned char __a, + vector unsigned char __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x10, 0x01, 0x11, 0x02, 0x12, + 0x03, 0x13, 0x04, 0x14, 0x05, 0x15, + 0x06, 0x16, 0x07, 0x17)); +} + +static vector bool char __ATTRS_o_ai vec_vmrghb(vector bool char __a, + vector bool char __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x10, 0x01, 0x11, 0x02, 0x12, + 0x03, 0x13, 0x04, 0x14, 0x05, 0x15, + 0x06, 0x16, 0x07, 0x17)); +} + +/* vec_vmrghh */ + +#define __builtin_altivec_vmrghh vec_vmrghh + +static vector short __ATTRS_o_ai vec_vmrghh(vector short __a, + vector short __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x10, 0x11, 0x02, 0x03, + 0x12, 0x13, 0x04, 0x05, 0x14, 0x15, + 0x06, 0x07, 0x16, 0x17)); +} + +static vector unsigned short __ATTRS_o_ai +vec_vmrghh(vector unsigned short __a, vector unsigned short __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x10, 0x11, 0x02, 0x03, + 0x12, 0x13, 0x04, 0x05, 0x14, 0x15, + 0x06, 0x07, 0x16, 0x17)); +} + +static vector bool short __ATTRS_o_ai vec_vmrghh(vector bool short __a, + vector bool short __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x10, 0x11, 0x02, 0x03, + 0x12, 0x13, 0x04, 0x05, 0x14, 0x15, + 0x06, 0x07, 0x16, 0x17)); +} + +static vector pixel __ATTRS_o_ai vec_vmrghh(vector pixel __a, + vector pixel __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x10, 0x11, 0x02, 0x03, + 0x12, 0x13, 0x04, 0x05, 0x14, 0x15, + 0x06, 0x07, 0x16, 0x17)); +} + +/* vec_vmrghw */ + +#define __builtin_altivec_vmrghw vec_vmrghw + +static vector int __ATTRS_o_ai vec_vmrghw(vector int __a, vector int __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, 0x10, 0x11, + 0x12, 0x13, 0x04, 0x05, 0x06, 0x07, + 0x14, 0x15, 0x16, 0x17)); +} + +static vector unsigned int __ATTRS_o_ai vec_vmrghw(vector unsigned int __a, + vector unsigned int __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, 0x10, 0x11, + 0x12, 0x13, 0x04, 0x05, 0x06, 0x07, + 0x14, 0x15, 0x16, 0x17)); +} + +static vector bool int __ATTRS_o_ai vec_vmrghw(vector bool int __a, + vector bool int __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, 0x10, 0x11, + 0x12, 0x13, 0x04, 0x05, 0x06, 0x07, + 0x14, 0x15, 0x16, 0x17)); +} + +static vector float __ATTRS_o_ai vec_vmrghw(vector float __a, + vector float __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, 0x10, 0x11, + 0x12, 0x13, 0x04, 0x05, 0x06, 0x07, + 0x14, 0x15, 0x16, 0x17)); +} + +/* vec_mergel */ + +static vector signed char __ATTRS_o_ai vec_mergel(vector signed char __a, + vector signed char __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, + 0x0B, 0x1B, 0x0C, 0x1C, 0x0D, 0x1D, + 0x0E, 0x1E, 0x0F, 0x1F)); +} + +static vector unsigned char __ATTRS_o_ai vec_mergel(vector unsigned char __a, + vector unsigned char __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, + 0x0B, 0x1B, 0x0C, 0x1C, 0x0D, 0x1D, + 0x0E, 0x1E, 0x0F, 0x1F)); +} + +static vector bool char __ATTRS_o_ai vec_mergel(vector bool char __a, + vector bool char __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, + 0x0B, 0x1B, 0x0C, 0x1C, 0x0D, 0x1D, + 0x0E, 0x1E, 0x0F, 0x1F)); +} + +static vector short __ATTRS_o_ai vec_mergel(vector short __a, + vector short __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, + 0x1A, 0x1B, 0x0C, 0x0D, 0x1C, 0x1D, + 0x0E, 0x0F, 0x1E, 0x1F)); +} + +static vector unsigned short __ATTRS_o_ai +vec_mergel(vector unsigned short __a, vector unsigned short __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, + 0x1A, 0x1B, 0x0C, 0x0D, 0x1C, 0x1D, + 0x0E, 0x0F, 0x1E, 0x1F)); +} + +static vector bool short __ATTRS_o_ai vec_mergel(vector bool short __a, + vector bool short __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, + 0x1A, 0x1B, 0x0C, 0x0D, 0x1C, 0x1D, + 0x0E, 0x0F, 0x1E, 0x1F)); +} + +static vector pixel __ATTRS_o_ai vec_mergel(vector pixel __a, + vector pixel __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, + 0x1A, 0x1B, 0x0C, 0x0D, 0x1C, 0x1D, + 0x0E, 0x0F, 0x1E, 0x1F)); +} + +static vector int __ATTRS_o_ai vec_mergel(vector int __a, vector int __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, + 0x1A, 0x1B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x1C, 0x1D, 0x1E, 0x1F)); +} + +static vector unsigned int __ATTRS_o_ai vec_mergel(vector unsigned int __a, + vector unsigned int __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, + 0x1A, 0x1B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x1C, 0x1D, 0x1E, 0x1F)); +} + +static vector bool int __ATTRS_o_ai vec_mergel(vector bool int __a, + vector bool int __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, + 0x1A, 0x1B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x1C, 0x1D, 0x1E, 0x1F)); +} + +static vector float __ATTRS_o_ai vec_mergel(vector float __a, + vector float __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, + 0x1A, 0x1B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x1C, 0x1D, 0x1E, 0x1F)); +} + +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai +vec_mergel(vector signed long long __a, vector signed long long __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, + 0x18, 0X19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F)); +} +static vector signed long long __ATTRS_o_ai +vec_mergel(vector signed long long __a, vector bool long long __b) { + return vec_perm(__a, (vector signed long long)__b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, + 0x18, 0X19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F)); +} +static vector signed long long __ATTRS_o_ai +vec_mergel(vector bool long long __a, vector signed long long __b) { + return vec_perm((vector signed long long)__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, + 0x18, 0X19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F)); +} +static vector unsigned long long __ATTRS_o_ai +vec_mergel(vector unsigned long long __a, vector unsigned long long __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, + 0x18, 0X19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F)); +} +static vector unsigned long long __ATTRS_o_ai +vec_mergel(vector unsigned long long __a, vector bool long long __b) { + return vec_perm(__a, (vector unsigned long long)__b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, + 0x18, 0X19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F)); +} +static vector unsigned long long __ATTRS_o_ai +vec_mergel(vector bool long long __a, vector unsigned long long __b) { + return vec_perm((vector unsigned long long)__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, + 0x18, 0X19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F)); +} +static vector bool long long __ATTRS_o_ai +vec_mergel(vector bool long long __a, vector bool long long __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, + 0x18, 0X19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F)); +} +static vector double __ATTRS_o_ai +vec_mergel(vector double __a, vector double __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, + 0x18, 0X19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F)); +} +static vector double __ATTRS_o_ai +vec_mergel(vector double __a, vector bool long long __b) { + return vec_perm(__a, (vector double)__b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, + 0x18, 0X19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F)); +} +static vector double __ATTRS_o_ai +vec_mergel(vector bool long long __a, vector double __b) { + return vec_perm((vector double)__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, + 0x18, 0X19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F)); +} +#endif + +/* vec_vmrglb */ + +#define __builtin_altivec_vmrglb vec_vmrglb + +static vector signed char __ATTRS_o_ai vec_vmrglb(vector signed char __a, + vector signed char __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, + 0x0B, 0x1B, 0x0C, 0x1C, 0x0D, 0x1D, + 0x0E, 0x1E, 0x0F, 0x1F)); +} + +static vector unsigned char __ATTRS_o_ai vec_vmrglb(vector unsigned char __a, + vector unsigned char __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, + 0x0B, 0x1B, 0x0C, 0x1C, 0x0D, 0x1D, + 0x0E, 0x1E, 0x0F, 0x1F)); +} + +static vector bool char __ATTRS_o_ai vec_vmrglb(vector bool char __a, + vector bool char __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, + 0x0B, 0x1B, 0x0C, 0x1C, 0x0D, 0x1D, + 0x0E, 0x1E, 0x0F, 0x1F)); +} + +/* vec_vmrglh */ + +#define __builtin_altivec_vmrglh vec_vmrglh + +static vector short __ATTRS_o_ai vec_vmrglh(vector short __a, + vector short __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, + 0x1A, 0x1B, 0x0C, 0x0D, 0x1C, 0x1D, + 0x0E, 0x0F, 0x1E, 0x1F)); +} + +static vector unsigned short __ATTRS_o_ai +vec_vmrglh(vector unsigned short __a, vector unsigned short __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, + 0x1A, 0x1B, 0x0C, 0x0D, 0x1C, 0x1D, + 0x0E, 0x0F, 0x1E, 0x1F)); +} + +static vector bool short __ATTRS_o_ai vec_vmrglh(vector bool short __a, + vector bool short __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, + 0x1A, 0x1B, 0x0C, 0x0D, 0x1C, 0x1D, + 0x0E, 0x0F, 0x1E, 0x1F)); +} + +static vector pixel __ATTRS_o_ai vec_vmrglh(vector pixel __a, + vector pixel __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, + 0x1A, 0x1B, 0x0C, 0x0D, 0x1C, 0x1D, + 0x0E, 0x0F, 0x1E, 0x1F)); +} + +/* vec_vmrglw */ + +#define __builtin_altivec_vmrglw vec_vmrglw + +static vector int __ATTRS_o_ai vec_vmrglw(vector int __a, vector int __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, + 0x1A, 0x1B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x1C, 0x1D, 0x1E, 0x1F)); +} + +static vector unsigned int __ATTRS_o_ai vec_vmrglw(vector unsigned int __a, + vector unsigned int __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, + 0x1A, 0x1B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x1C, 0x1D, 0x1E, 0x1F)); +} + +static vector bool int __ATTRS_o_ai vec_vmrglw(vector bool int __a, + vector bool int __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, + 0x1A, 0x1B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x1C, 0x1D, 0x1E, 0x1F)); +} + +static vector float __ATTRS_o_ai vec_vmrglw(vector float __a, + vector float __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, + 0x1A, 0x1B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x1C, 0x1D, 0x1E, 0x1F)); +} + + +#ifdef __POWER8_VECTOR__ +/* vec_mergee */ + +static vector bool int __ATTRS_o_ai +vec_mergee(vector bool int __a, vector bool int __b) { + return vec_perm(__a, __b, (vector unsigned char) + (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, + 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B)); +} + +static vector signed int __ATTRS_o_ai +vec_mergee(vector signed int __a, vector signed int __b) { + return vec_perm(__a, __b, (vector unsigned char) + (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, + 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B)); +} + +static vector unsigned int __ATTRS_o_ai +vec_mergee(vector unsigned int __a, vector unsigned int __b) { + return vec_perm(__a, __b, (vector unsigned char) + (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, + 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B)); +} + +/* vec_mergeo */ + +static vector bool int __ATTRS_o_ai +vec_mergeo(vector bool int __a, vector bool int __b) { + return vec_perm(__a, __b, (vector unsigned char) + (0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17, + 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F)); +} + +static vector signed int __ATTRS_o_ai +vec_mergeo(vector signed int __a, vector signed int __b) { + return vec_perm(__a, __b, (vector unsigned char) + (0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17, + 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F)); +} + +static vector unsigned int __ATTRS_o_ai +vec_mergeo(vector unsigned int __a, vector unsigned int __b) { + return vec_perm(__a, __b, (vector unsigned char) + (0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17, + 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F)); +} + +#endif + +/* vec_mfvscr */ + +static vector unsigned short __attribute__((__always_inline__)) +vec_mfvscr(void) { + return __builtin_altivec_mfvscr(); +} + +/* vec_min */ + +static vector signed char __ATTRS_o_ai vec_min(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vminsb(__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_min(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vminsb((vector signed char)__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_min(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vminsb(__a, (vector signed char)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_min(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vminub(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_min(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vminub((vector unsigned char)__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_min(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vminub(__a, (vector unsigned char)__b); +} + +static vector short __ATTRS_o_ai vec_min(vector short __a, vector short __b) { + return __builtin_altivec_vminsh(__a, __b); +} + +static vector short __ATTRS_o_ai vec_min(vector bool short __a, + vector short __b) { + return __builtin_altivec_vminsh((vector short)__a, __b); +} + +static vector short __ATTRS_o_ai vec_min(vector short __a, + vector bool short __b) { + return __builtin_altivec_vminsh(__a, (vector short)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_min(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vminuh(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_min(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vminuh((vector unsigned short)__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_min(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vminuh(__a, (vector unsigned short)__b); +} + +static vector int __ATTRS_o_ai vec_min(vector int __a, vector int __b) { + return __builtin_altivec_vminsw(__a, __b); +} + +static vector int __ATTRS_o_ai vec_min(vector bool int __a, vector int __b) { + return __builtin_altivec_vminsw((vector int)__a, __b); +} + +static vector int __ATTRS_o_ai vec_min(vector int __a, vector bool int __b) { + return __builtin_altivec_vminsw(__a, (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_min(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vminuw(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_min(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vminuw((vector unsigned int)__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_min(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vminuw(__a, (vector unsigned int)__b); +} + +#ifdef __POWER8_VECTOR__ +static vector signed long long __ATTRS_o_ai +vec_min(vector signed long long __a, vector signed long long __b) { + return __builtin_altivec_vminsd(__a, __b); +} + +static vector signed long long __ATTRS_o_ai +vec_min(vector bool long long __a, vector signed long long __b) { + return __builtin_altivec_vminsd((vector signed long long)__a, __b); +} + +static vector signed long long __ATTRS_o_ai vec_min(vector signed long long __a, + vector bool long long __b) { + return __builtin_altivec_vminsd(__a, (vector signed long long)__b); +} + +static vector unsigned long long __ATTRS_o_ai +vec_min(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_altivec_vminud(__a, __b); +} + +static vector unsigned long long __ATTRS_o_ai +vec_min(vector bool long long __a, vector unsigned long long __b) { + return __builtin_altivec_vminud((vector unsigned long long)__a, __b); +} + +static vector unsigned long long __ATTRS_o_ai +vec_min(vector unsigned long long __a, vector bool long long __b) { + return __builtin_altivec_vminud(__a, (vector unsigned long long)__b); +} +#endif + +static vector float __ATTRS_o_ai vec_min(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvminsp(__a, __b); +#else + return __builtin_altivec_vminfp(__a, __b); +#endif +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai vec_min(vector double __a, + vector double __b) { + return __builtin_vsx_xvmindp(__a, __b); +} +#endif + +/* vec_vminsb */ + +static vector signed char __ATTRS_o_ai vec_vminsb(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vminsb(__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_vminsb(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vminsb((vector signed char)__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_vminsb(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vminsb(__a, (vector signed char)__b); +} + +/* vec_vminub */ + +static vector unsigned char __ATTRS_o_ai vec_vminub(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vminub(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_vminub(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vminub((vector unsigned char)__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_vminub(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vminub(__a, (vector unsigned char)__b); +} + +/* vec_vminsh */ + +static vector short __ATTRS_o_ai vec_vminsh(vector short __a, + vector short __b) { + return __builtin_altivec_vminsh(__a, __b); +} + +static vector short __ATTRS_o_ai vec_vminsh(vector bool short __a, + vector short __b) { + return __builtin_altivec_vminsh((vector short)__a, __b); +} + +static vector short __ATTRS_o_ai vec_vminsh(vector short __a, + vector bool short __b) { + return __builtin_altivec_vminsh(__a, (vector short)__b); +} + +/* vec_vminuh */ + +static vector unsigned short __ATTRS_o_ai +vec_vminuh(vector unsigned short __a, vector unsigned short __b) { + return __builtin_altivec_vminuh(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai +vec_vminuh(vector bool short __a, vector unsigned short __b) { + return __builtin_altivec_vminuh((vector unsigned short)__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_vminuh(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vminuh(__a, (vector unsigned short)__b); +} + +/* vec_vminsw */ + +static vector int __ATTRS_o_ai vec_vminsw(vector int __a, vector int __b) { + return __builtin_altivec_vminsw(__a, __b); +} + +static vector int __ATTRS_o_ai vec_vminsw(vector bool int __a, vector int __b) { + return __builtin_altivec_vminsw((vector int)__a, __b); +} + +static vector int __ATTRS_o_ai vec_vminsw(vector int __a, vector bool int __b) { + return __builtin_altivec_vminsw(__a, (vector int)__b); +} + +/* vec_vminuw */ + +static vector unsigned int __ATTRS_o_ai vec_vminuw(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vminuw(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_vminuw(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vminuw((vector unsigned int)__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_vminuw(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vminuw(__a, (vector unsigned int)__b); +} + +/* vec_vminfp */ + +static vector float __attribute__((__always_inline__)) +vec_vminfp(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvminsp(__a, __b); +#else + return __builtin_altivec_vminfp(__a, __b); +#endif +} + +/* vec_mladd */ + +#define __builtin_altivec_vmladduhm vec_mladd + +static vector short __ATTRS_o_ai vec_mladd(vector short __a, vector short __b, + vector short __c) { + return __a * __b + __c; +} + +static vector short __ATTRS_o_ai vec_mladd(vector short __a, + vector unsigned short __b, + vector unsigned short __c) { + return __a * (vector short)__b + (vector short)__c; +} + +static vector short __ATTRS_o_ai vec_mladd(vector unsigned short __a, + vector short __b, vector short __c) { + return (vector short)__a * __b + __c; +} + +static vector unsigned short __ATTRS_o_ai vec_mladd(vector unsigned short __a, + vector unsigned short __b, + vector unsigned short __c) { + return __a * __b + __c; +} + +/* vec_vmladduhm */ + +static vector short __ATTRS_o_ai vec_vmladduhm(vector short __a, + vector short __b, + vector short __c) { + return __a * __b + __c; +} + +static vector short __ATTRS_o_ai vec_vmladduhm(vector short __a, + vector unsigned short __b, + vector unsigned short __c) { + return __a * (vector short)__b + (vector short)__c; +} + +static vector short __ATTRS_o_ai vec_vmladduhm(vector unsigned short __a, + vector short __b, + vector short __c) { + return (vector short)__a * __b + __c; +} + +static vector unsigned short __ATTRS_o_ai +vec_vmladduhm(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c) { + return __a * __b + __c; +} + +/* vec_mradds */ + +static vector short __attribute__((__always_inline__)) +vec_mradds(vector short __a, vector short __b, vector short __c) { + return __builtin_altivec_vmhraddshs(__a, __b, __c); +} + +/* vec_vmhraddshs */ + +static vector short __attribute__((__always_inline__)) +vec_vmhraddshs(vector short __a, vector short __b, vector short __c) { + return __builtin_altivec_vmhraddshs(__a, __b, __c); +} + +/* vec_msum */ + +static vector int __ATTRS_o_ai vec_msum(vector signed char __a, + vector unsigned char __b, + vector int __c) { + return __builtin_altivec_vmsummbm(__a, __b, __c); +} + +static vector unsigned int __ATTRS_o_ai vec_msum(vector unsigned char __a, + vector unsigned char __b, + vector unsigned int __c) { + return __builtin_altivec_vmsumubm(__a, __b, __c); +} + +static vector int __ATTRS_o_ai vec_msum(vector short __a, vector short __b, + vector int __c) { + return __builtin_altivec_vmsumshm(__a, __b, __c); +} + +static vector unsigned int __ATTRS_o_ai vec_msum(vector unsigned short __a, + vector unsigned short __b, + vector unsigned int __c) { + return __builtin_altivec_vmsumuhm(__a, __b, __c); +} + +/* vec_vmsummbm */ + +static vector int __attribute__((__always_inline__)) +vec_vmsummbm(vector signed char __a, vector unsigned char __b, vector int __c) { + return __builtin_altivec_vmsummbm(__a, __b, __c); +} + +/* vec_vmsumubm */ + +static vector unsigned int __attribute__((__always_inline__)) +vec_vmsumubm(vector unsigned char __a, vector unsigned char __b, + vector unsigned int __c) { + return __builtin_altivec_vmsumubm(__a, __b, __c); +} + +/* vec_vmsumshm */ + +static vector int __attribute__((__always_inline__)) +vec_vmsumshm(vector short __a, vector short __b, vector int __c) { + return __builtin_altivec_vmsumshm(__a, __b, __c); +} + +/* vec_vmsumuhm */ + +static vector unsigned int __attribute__((__always_inline__)) +vec_vmsumuhm(vector unsigned short __a, vector unsigned short __b, + vector unsigned int __c) { + return __builtin_altivec_vmsumuhm(__a, __b, __c); +} + +/* vec_msums */ + +static vector int __ATTRS_o_ai vec_msums(vector short __a, vector short __b, + vector int __c) { + return __builtin_altivec_vmsumshs(__a, __b, __c); +} + +static vector unsigned int __ATTRS_o_ai vec_msums(vector unsigned short __a, + vector unsigned short __b, + vector unsigned int __c) { + return __builtin_altivec_vmsumuhs(__a, __b, __c); +} + +/* vec_vmsumshs */ + +static vector int __attribute__((__always_inline__)) +vec_vmsumshs(vector short __a, vector short __b, vector int __c) { + return __builtin_altivec_vmsumshs(__a, __b, __c); +} + +/* vec_vmsumuhs */ + +static vector unsigned int __attribute__((__always_inline__)) +vec_vmsumuhs(vector unsigned short __a, vector unsigned short __b, + vector unsigned int __c) { + return __builtin_altivec_vmsumuhs(__a, __b, __c); +} + +/* vec_mtvscr */ + +static void __ATTRS_o_ai vec_mtvscr(vector signed char __a) { + __builtin_altivec_mtvscr((vector int)__a); +} + +static void __ATTRS_o_ai vec_mtvscr(vector unsigned char __a) { + __builtin_altivec_mtvscr((vector int)__a); +} + +static void __ATTRS_o_ai vec_mtvscr(vector bool char __a) { + __builtin_altivec_mtvscr((vector int)__a); +} + +static void __ATTRS_o_ai vec_mtvscr(vector short __a) { + __builtin_altivec_mtvscr((vector int)__a); +} + +static void __ATTRS_o_ai vec_mtvscr(vector unsigned short __a) { + __builtin_altivec_mtvscr((vector int)__a); +} + +static void __ATTRS_o_ai vec_mtvscr(vector bool short __a) { + __builtin_altivec_mtvscr((vector int)__a); +} + +static void __ATTRS_o_ai vec_mtvscr(vector pixel __a) { + __builtin_altivec_mtvscr((vector int)__a); +} + +static void __ATTRS_o_ai vec_mtvscr(vector int __a) { + __builtin_altivec_mtvscr((vector int)__a); +} + +static void __ATTRS_o_ai vec_mtvscr(vector unsigned int __a) { + __builtin_altivec_mtvscr((vector int)__a); +} + +static void __ATTRS_o_ai vec_mtvscr(vector bool int __a) { + __builtin_altivec_mtvscr((vector int)__a); +} + +static void __ATTRS_o_ai vec_mtvscr(vector float __a) { + __builtin_altivec_mtvscr((vector int)__a); +} + +/* vec_mul */ + +/* Integer vector multiplication will involve multiplication of the odd/even + elements separately, then truncating the results and moving to the + result vector. +*/ +static vector signed char __ATTRS_o_ai vec_mul(vector signed char __a, + vector signed char __b) { + return __a * __b; +} + +static vector unsigned char __ATTRS_o_ai vec_mul(vector unsigned char __a, + vector unsigned char __b) { + return __a * __b; +} + +static vector signed short __ATTRS_o_ai vec_mul(vector signed short __a, + vector signed short __b) { + return __a * __b; +} + +static vector unsigned short __ATTRS_o_ai vec_mul(vector unsigned short __a, + vector unsigned short __b) { + return __a * __b; +} + +static vector signed int __ATTRS_o_ai vec_mul(vector signed int __a, + vector signed int __b) { + return __a * __b; +} + +static vector unsigned int __ATTRS_o_ai vec_mul(vector unsigned int __a, + vector unsigned int __b) { + return __a * __b; +} + +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai +vec_mul(vector signed long long __a, vector signed long long __b) { + return __a * __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_mul(vector unsigned long long __a, vector unsigned long long __b) { + return __a * __b; +} +#endif + +static vector float __ATTRS_o_ai vec_mul(vector float __a, vector float __b) { + return __a * __b; +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai +vec_mul(vector double __a, vector double __b) { + return __a * __b; +} +#endif + +/* The vmulos* and vmules* instructions have a big endian bias, so + we must reverse the meaning of "even" and "odd" for little endian. */ + +/* vec_mule */ + +static vector short __ATTRS_o_ai vec_mule(vector signed char __a, + vector signed char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulosb(__a, __b); +#else + return __builtin_altivec_vmulesb(__a, __b); +#endif +} + +static vector unsigned short __ATTRS_o_ai vec_mule(vector unsigned char __a, + vector unsigned char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuloub(__a, __b); +#else + return __builtin_altivec_vmuleub(__a, __b); +#endif +} + +static vector int __ATTRS_o_ai vec_mule(vector short __a, vector short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulosh(__a, __b); +#else + return __builtin_altivec_vmulesh(__a, __b); +#endif +} + +static vector unsigned int __ATTRS_o_ai vec_mule(vector unsigned short __a, + vector unsigned short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulouh(__a, __b); +#else + return __builtin_altivec_vmuleuh(__a, __b); +#endif +} + +#ifdef __POWER8_VECTOR__ +static vector signed long long __ATTRS_o_ai vec_mule(vector signed int __a, + vector signed int __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulosw(__a, __b); +#else + return __builtin_altivec_vmulesw(__a, __b); +#endif +} + +static vector unsigned long long __ATTRS_o_ai +vec_mule(vector unsigned int __a, vector unsigned int __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulouw(__a, __b); +#else + return __builtin_altivec_vmuleuw(__a, __b); +#endif +} +#endif + +/* vec_vmulesb */ + +static vector short __attribute__((__always_inline__)) +vec_vmulesb(vector signed char __a, vector signed char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulosb(__a, __b); +#else + return __builtin_altivec_vmulesb(__a, __b); +#endif +} + +/* vec_vmuleub */ + +static vector unsigned short __attribute__((__always_inline__)) +vec_vmuleub(vector unsigned char __a, vector unsigned char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuloub(__a, __b); +#else + return __builtin_altivec_vmuleub(__a, __b); +#endif +} + +/* vec_vmulesh */ + +static vector int __attribute__((__always_inline__)) +vec_vmulesh(vector short __a, vector short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulosh(__a, __b); +#else + return __builtin_altivec_vmulesh(__a, __b); +#endif +} + +/* vec_vmuleuh */ + +static vector unsigned int __attribute__((__always_inline__)) +vec_vmuleuh(vector unsigned short __a, vector unsigned short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulouh(__a, __b); +#else + return __builtin_altivec_vmuleuh(__a, __b); +#endif +} + +/* vec_mulo */ + +static vector short __ATTRS_o_ai vec_mulo(vector signed char __a, + vector signed char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulesb(__a, __b); +#else + return __builtin_altivec_vmulosb(__a, __b); +#endif +} + +static vector unsigned short __ATTRS_o_ai vec_mulo(vector unsigned char __a, + vector unsigned char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuleub(__a, __b); +#else + return __builtin_altivec_vmuloub(__a, __b); +#endif +} + +static vector int __ATTRS_o_ai vec_mulo(vector short __a, vector short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulesh(__a, __b); +#else + return __builtin_altivec_vmulosh(__a, __b); +#endif +} + +static vector unsigned int __ATTRS_o_ai vec_mulo(vector unsigned short __a, + vector unsigned short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuleuh(__a, __b); +#else + return __builtin_altivec_vmulouh(__a, __b); +#endif +} + +#ifdef __POWER8_VECTOR__ +static vector signed long long __ATTRS_o_ai vec_mulo(vector signed int __a, + vector signed int __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulesw(__a, __b); +#else + return __builtin_altivec_vmulosw(__a, __b); +#endif +} + +static vector unsigned long long __ATTRS_o_ai +vec_mulo(vector unsigned int __a, vector unsigned int __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuleuw(__a, __b); +#else + return __builtin_altivec_vmulouw(__a, __b); +#endif +} +#endif + +/* vec_vmulosb */ + +static vector short __attribute__((__always_inline__)) +vec_vmulosb(vector signed char __a, vector signed char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulesb(__a, __b); +#else + return __builtin_altivec_vmulosb(__a, __b); +#endif +} + +/* vec_vmuloub */ + +static vector unsigned short __attribute__((__always_inline__)) +vec_vmuloub(vector unsigned char __a, vector unsigned char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuleub(__a, __b); +#else + return __builtin_altivec_vmuloub(__a, __b); +#endif +} + +/* vec_vmulosh */ + +static vector int __attribute__((__always_inline__)) +vec_vmulosh(vector short __a, vector short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulesh(__a, __b); +#else + return __builtin_altivec_vmulosh(__a, __b); +#endif +} + +/* vec_vmulouh */ + +static vector unsigned int __attribute__((__always_inline__)) +vec_vmulouh(vector unsigned short __a, vector unsigned short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuleuh(__a, __b); +#else + return __builtin_altivec_vmulouh(__a, __b); +#endif +} + +/* vec_nand */ + +#ifdef __POWER8_VECTOR__ +static vector signed char __ATTRS_o_ai vec_nand(vector signed char __a, + vector signed char __b) { + return ~(__a & __b); +} + +static vector signed char __ATTRS_o_ai vec_nand(vector signed char __a, + vector bool char __b) { + return ~(__a & __b); +} + +static vector signed char __ATTRS_o_ai vec_nand(vector bool char __a, + vector signed char __b) { + return ~(__a & __b); +} + +static vector unsigned char __ATTRS_o_ai vec_nand(vector unsigned char __a, + vector unsigned char __b) { + return ~(__a & __b); +} + +static vector unsigned char __ATTRS_o_ai vec_nand(vector unsigned char __a, + vector bool char __b) { + return ~(__a & __b); + +} + +static vector unsigned char __ATTRS_o_ai vec_nand(vector bool char __a, + vector unsigned char __b) { + return ~(__a & __b); +} + +static vector bool char __ATTRS_o_ai vec_nand(vector bool char __a, + vector bool char __b) { + return ~(__a & __b); +} + +static vector signed short __ATTRS_o_ai vec_nand(vector signed short __a, + vector signed short __b) { + return ~(__a & __b); +} + +static vector signed short __ATTRS_o_ai vec_nand(vector signed short __a, + vector bool short __b) { + return ~(__a & __b); +} + +static vector signed short __ATTRS_o_ai vec_nand(vector bool short __a, + vector signed short __b) { + return ~(__a & __b); +} + +static vector unsigned short __ATTRS_o_ai vec_nand(vector unsigned short __a, + vector unsigned short __b) { + return ~(__a & __b); +} + +static vector unsigned short __ATTRS_o_ai vec_nand(vector unsigned short __a, + vector bool short __b) { + return ~(__a & __b); + +} + +static vector bool short __ATTRS_o_ai vec_nand(vector bool short __a, + vector bool short __b) { + return ~(__a & __b); + +} + +static vector signed int __ATTRS_o_ai vec_nand(vector signed int __a, + vector signed int __b) { + return ~(__a & __b); +} + +static vector signed int __ATTRS_o_ai vec_nand(vector signed int __a, + vector bool int __b) { + return ~(__a & __b); +} + +static vector signed int __ATTRS_o_ai vec_nand(vector bool int __a, + vector signed int __b) { + return ~(__a & __b); +} + +static vector unsigned int __ATTRS_o_ai vec_nand(vector unsigned int __a, + vector unsigned int __b) { + return ~(__a & __b); +} + +static vector unsigned int __ATTRS_o_ai vec_nand(vector unsigned int __a, + vector bool int __b) { + return ~(__a & __b); +} + +static vector unsigned int __ATTRS_o_ai vec_nand(vector bool int __a, + vector unsigned int __b) { + return ~(__a & __b); +} + +static vector bool int __ATTRS_o_ai vec_nand(vector bool int __a, + vector bool int __b) { + return ~(__a & __b); +} + +static vector signed long long __ATTRS_o_ai +vec_nand(vector signed long long __a, vector signed long long __b) { + return ~(__a & __b); +} + +static vector signed long long __ATTRS_o_ai +vec_nand(vector signed long long __a, vector bool long long __b) { + return ~(__a & __b); +} + +static vector signed long long __ATTRS_o_ai +vec_nand(vector bool long long __a, vector signed long long __b) { + return ~(__a & __b); +} + +static vector unsigned long long __ATTRS_o_ai +vec_nand(vector unsigned long long __a, vector unsigned long long __b) { + return ~(__a & __b); +} + +static vector unsigned long long __ATTRS_o_ai +vec_nand(vector unsigned long long __a, vector bool long long __b) { + return ~(__a & __b); +} + +static vector unsigned long long __ATTRS_o_ai +vec_nand(vector bool long long __a, vector unsigned long long __b) { + return ~(__a & __b); +} + +static vector bool long long __ATTRS_o_ai +vec_nand(vector bool long long __a, vector bool long long __b) { + return ~(__a & __b); +} + +#endif + +/* vec_nmadd */ + +#ifdef __VSX__ +static vector float __ATTRS_o_ai +vec_nmadd(vector float __a, vector float __b, vector float __c) { + return __builtin_vsx_xvnmaddasp(__a, __b, __c); +} + +static vector double __ATTRS_o_ai +vec_nmadd(vector double __a, vector double __b, vector double __c) { + return __builtin_vsx_xvnmaddadp(__a, __b, __c); +} +#endif + +/* vec_nmsub */ + +static vector float __ATTRS_o_ai +vec_nmsub(vector float __a, vector float __b, vector float __c) { +#ifdef __VSX__ + return __builtin_vsx_xvnmsubasp(__a, __b, __c); +#else + return __builtin_altivec_vnmsubfp(__a, __b, __c); +#endif +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai +vec_nmsub(vector double __a, vector double __b, vector double __c) { + return __builtin_vsx_xvnmsubadp(__a, __b, __c); +} +#endif + +/* vec_vnmsubfp */ + +static vector float __attribute__((__always_inline__)) +vec_vnmsubfp(vector float __a, vector float __b, vector float __c) { + return __builtin_altivec_vnmsubfp(__a, __b, __c); +} + +/* vec_nor */ + +#define __builtin_altivec_vnor vec_nor + +static vector signed char __ATTRS_o_ai vec_nor(vector signed char __a, + vector signed char __b) { + return ~(__a | __b); +} + +static vector unsigned char __ATTRS_o_ai vec_nor(vector unsigned char __a, + vector unsigned char __b) { + return ~(__a | __b); +} + +static vector bool char __ATTRS_o_ai vec_nor(vector bool char __a, + vector bool char __b) { + return ~(__a | __b); +} + +static vector short __ATTRS_o_ai vec_nor(vector short __a, vector short __b) { + return ~(__a | __b); +} + +static vector unsigned short __ATTRS_o_ai vec_nor(vector unsigned short __a, + vector unsigned short __b) { + return ~(__a | __b); +} + +static vector bool short __ATTRS_o_ai vec_nor(vector bool short __a, + vector bool short __b) { + return ~(__a | __b); +} + +static vector int __ATTRS_o_ai vec_nor(vector int __a, vector int __b) { + return ~(__a | __b); +} + +static vector unsigned int __ATTRS_o_ai vec_nor(vector unsigned int __a, + vector unsigned int __b) { + return ~(__a | __b); +} + +static vector bool int __ATTRS_o_ai vec_nor(vector bool int __a, + vector bool int __b) { + return ~(__a | __b); +} + +static vector float __ATTRS_o_ai vec_nor(vector float __a, vector float __b) { + vector unsigned int __res = + ~((vector unsigned int)__a | (vector unsigned int)__b); + return (vector float)__res; +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai +vec_nor(vector double __a, vector double __b) { + vector unsigned long long __res = + ~((vector unsigned long long)__a | (vector unsigned long long)__b); + return (vector double)__res; +} +#endif + +/* vec_vnor */ + +static vector signed char __ATTRS_o_ai vec_vnor(vector signed char __a, + vector signed char __b) { + return ~(__a | __b); +} + +static vector unsigned char __ATTRS_o_ai vec_vnor(vector unsigned char __a, + vector unsigned char __b) { + return ~(__a | __b); +} + +static vector bool char __ATTRS_o_ai vec_vnor(vector bool char __a, + vector bool char __b) { + return ~(__a | __b); +} + +static vector short __ATTRS_o_ai vec_vnor(vector short __a, vector short __b) { + return ~(__a | __b); +} + +static vector unsigned short __ATTRS_o_ai vec_vnor(vector unsigned short __a, + vector unsigned short __b) { + return ~(__a | __b); +} + +static vector bool short __ATTRS_o_ai vec_vnor(vector bool short __a, + vector bool short __b) { + return ~(__a | __b); +} + +static vector int __ATTRS_o_ai vec_vnor(vector int __a, vector int __b) { + return ~(__a | __b); +} + +static vector unsigned int __ATTRS_o_ai vec_vnor(vector unsigned int __a, + vector unsigned int __b) { + return ~(__a | __b); +} + +static vector bool int __ATTRS_o_ai vec_vnor(vector bool int __a, + vector bool int __b) { + return ~(__a | __b); +} + +static vector float __ATTRS_o_ai vec_vnor(vector float __a, vector float __b) { + vector unsigned int __res = + ~((vector unsigned int)__a | (vector unsigned int)__b); + return (vector float)__res; +} + +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai +vec_nor(vector signed long long __a, vector signed long long __b) { + return ~(__a | __b); +} + +static vector unsigned long long __ATTRS_o_ai +vec_nor(vector unsigned long long __a, vector unsigned long long __b) { + return ~(__a | __b); +} + +static vector bool long long __ATTRS_o_ai vec_nor(vector bool long long __a, + vector bool long long __b) { + return ~(__a | __b); +} +#endif + +/* vec_or */ + +#define __builtin_altivec_vor vec_or + +static vector signed char __ATTRS_o_ai vec_or(vector signed char __a, + vector signed char __b) { + return __a | __b; +} + +static vector signed char __ATTRS_o_ai vec_or(vector bool char __a, + vector signed char __b) { + return (vector signed char)__a | __b; +} + +static vector signed char __ATTRS_o_ai vec_or(vector signed char __a, + vector bool char __b) { + return __a | (vector signed char)__b; +} + +static vector unsigned char __ATTRS_o_ai vec_or(vector unsigned char __a, + vector unsigned char __b) { + return __a | __b; +} + +static vector unsigned char __ATTRS_o_ai vec_or(vector bool char __a, + vector unsigned char __b) { + return (vector unsigned char)__a | __b; +} + +static vector unsigned char __ATTRS_o_ai vec_or(vector unsigned char __a, + vector bool char __b) { + return __a | (vector unsigned char)__b; +} + +static vector bool char __ATTRS_o_ai vec_or(vector bool char __a, + vector bool char __b) { + return __a | __b; +} + +static vector short __ATTRS_o_ai vec_or(vector short __a, vector short __b) { + return __a | __b; +} + +static vector short __ATTRS_o_ai vec_or(vector bool short __a, + vector short __b) { + return (vector short)__a | __b; +} + +static vector short __ATTRS_o_ai vec_or(vector short __a, + vector bool short __b) { + return __a | (vector short)__b; +} + +static vector unsigned short __ATTRS_o_ai vec_or(vector unsigned short __a, + vector unsigned short __b) { + return __a | __b; +} + +static vector unsigned short __ATTRS_o_ai vec_or(vector bool short __a, + vector unsigned short __b) { + return (vector unsigned short)__a | __b; +} + +static vector unsigned short __ATTRS_o_ai vec_or(vector unsigned short __a, + vector bool short __b) { + return __a | (vector unsigned short)__b; +} + +static vector bool short __ATTRS_o_ai vec_or(vector bool short __a, + vector bool short __b) { + return __a | __b; +} + +static vector int __ATTRS_o_ai vec_or(vector int __a, vector int __b) { + return __a | __b; +} + +static vector int __ATTRS_o_ai vec_or(vector bool int __a, vector int __b) { + return (vector int)__a | __b; +} + +static vector int __ATTRS_o_ai vec_or(vector int __a, vector bool int __b) { + return __a | (vector int)__b; +} + +static vector unsigned int __ATTRS_o_ai vec_or(vector unsigned int __a, + vector unsigned int __b) { + return __a | __b; +} + +static vector unsigned int __ATTRS_o_ai vec_or(vector bool int __a, + vector unsigned int __b) { + return (vector unsigned int)__a | __b; +} + +static vector unsigned int __ATTRS_o_ai vec_or(vector unsigned int __a, + vector bool int __b) { + return __a | (vector unsigned int)__b; +} + +static vector bool int __ATTRS_o_ai vec_or(vector bool int __a, + vector bool int __b) { + return __a | __b; +} + +static vector float __ATTRS_o_ai vec_or(vector float __a, vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a | (vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_or(vector bool int __a, vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a | (vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_or(vector float __a, vector bool int __b) { + vector unsigned int __res = + (vector unsigned int)__a | (vector unsigned int)__b; + return (vector float)__res; +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai vec_or(vector bool long long __a, + vector double __b) { + return (vector unsigned long long)__a | (vector unsigned long long)__b; +} + +static vector double __ATTRS_o_ai vec_or(vector double __a, + vector bool long long __b) { + return (vector unsigned long long)__a | (vector unsigned long long)__b; +} + +static vector double __ATTRS_o_ai vec_or(vector double __a, vector double __b) { + vector unsigned long long __res = + (vector unsigned long long)__a | (vector unsigned long long)__b; + return (vector double)__res; +} + +static vector signed long long __ATTRS_o_ai +vec_or(vector signed long long __a, vector signed long long __b) { + return __a | __b; +} + +static vector signed long long __ATTRS_o_ai +vec_or(vector bool long long __a, vector signed long long __b) { + return (vector signed long long)__a | __b; +} + +static vector signed long long __ATTRS_o_ai vec_or(vector signed long long __a, + vector bool long long __b) { + return __a | (vector signed long long)__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_or(vector unsigned long long __a, vector unsigned long long __b) { + return __a | __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_or(vector bool long long __a, vector unsigned long long __b) { + return (vector unsigned long long)__a | __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_or(vector unsigned long long __a, vector bool long long __b) { + return __a | (vector unsigned long long)__b; +} + +static vector bool long long __ATTRS_o_ai vec_or(vector bool long long __a, + vector bool long long __b) { + return __a | __b; +} +#endif + +#ifdef __POWER8_VECTOR__ +static vector signed char __ATTRS_o_ai vec_orc(vector signed char __a, + vector signed char __b) { + return __a | ~__b; +} + +static vector signed char __ATTRS_o_ai vec_orc(vector signed char __a, + vector bool char __b) { + return __a | ~__b; +} + +static vector signed char __ATTRS_o_ai vec_orc(vector bool char __a, + vector signed char __b) { + return __a | ~__b; +} + +static vector unsigned char __ATTRS_o_ai vec_orc(vector unsigned char __a, + vector unsigned char __b) { + return __a | ~__b; +} + +static vector unsigned char __ATTRS_o_ai vec_orc(vector unsigned char __a, + vector bool char __b) { + return __a | ~__b; +} + +static vector unsigned char __ATTRS_o_ai vec_orc(vector bool char __a, + vector unsigned char __b) { + return __a | ~__b; +} + +static vector bool char __ATTRS_o_ai vec_orc(vector bool char __a, + vector bool char __b) { + return __a | ~__b; +} + +static vector signed short __ATTRS_o_ai vec_orc(vector signed short __a, + vector signed short __b) { + return __a | ~__b; +} + +static vector signed short __ATTRS_o_ai vec_orc(vector signed short __a, + vector bool short __b) { + return __a | ~__b; +} + +static vector signed short __ATTRS_o_ai vec_orc(vector bool short __a, + vector signed short __b) { + return __a | ~__b; +} + +static vector unsigned short __ATTRS_o_ai vec_orc(vector unsigned short __a, + vector unsigned short __b) { + return __a | ~__b; +} + +static vector unsigned short __ATTRS_o_ai vec_orc(vector unsigned short __a, + vector bool short __b) { + return __a | ~__b; +} + +static vector unsigned short __ATTRS_o_ai +vec_orc(vector bool short __a, vector unsigned short __b) { + return __a | ~__b; +} + +static vector bool short __ATTRS_o_ai vec_orc(vector bool short __a, + vector bool short __b) { + return __a | ~__b; +} + +static vector signed int __ATTRS_o_ai vec_orc(vector signed int __a, + vector signed int __b) { + return __a | ~__b; +} + +static vector signed int __ATTRS_o_ai vec_orc(vector signed int __a, + vector bool int __b) { + return __a | ~__b; +} + +static vector signed int __ATTRS_o_ai vec_orc(vector bool int __a, + vector signed int __b) { + return __a | ~__b; +} + +static vector unsigned int __ATTRS_o_ai vec_orc(vector unsigned int __a, + vector unsigned int __b) { + return __a | ~__b; +} + +static vector unsigned int __ATTRS_o_ai vec_orc(vector unsigned int __a, + vector bool int __b) { + return __a | ~__b; +} + +static vector unsigned int __ATTRS_o_ai vec_orc(vector bool int __a, + vector unsigned int __b) { + return __a | ~__b; +} + +static vector bool int __ATTRS_o_ai vec_orc(vector bool int __a, + vector bool int __b) { + return __a | ~__b; +} + +static vector signed long long __ATTRS_o_ai +vec_orc(vector signed long long __a, vector signed long long __b) { + return __a | ~__b; +} + +static vector signed long long __ATTRS_o_ai vec_orc(vector signed long long __a, + vector bool long long __b) { + return __a | ~__b; +} + +static vector signed long long __ATTRS_o_ai +vec_orc(vector bool long long __a, vector signed long long __b) { + return __a | ~__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_orc(vector unsigned long long __a, vector unsigned long long __b) { + return __a | ~__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_orc(vector unsigned long long __a, vector bool long long __b) { + return __a | ~__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_orc(vector bool long long __a, vector unsigned long long __b) { + return __a | ~__b; +} + +static vector bool long long __ATTRS_o_ai +vec_orc(vector bool long long __a, vector bool long long __b) { + return __a | ~__b; +} +#endif + +/* vec_vor */ + +static vector signed char __ATTRS_o_ai vec_vor(vector signed char __a, + vector signed char __b) { + return __a | __b; +} + +static vector signed char __ATTRS_o_ai vec_vor(vector bool char __a, + vector signed char __b) { + return (vector signed char)__a | __b; +} + +static vector signed char __ATTRS_o_ai vec_vor(vector signed char __a, + vector bool char __b) { + return __a | (vector signed char)__b; +} + +static vector unsigned char __ATTRS_o_ai vec_vor(vector unsigned char __a, + vector unsigned char __b) { + return __a | __b; +} + +static vector unsigned char __ATTRS_o_ai vec_vor(vector bool char __a, + vector unsigned char __b) { + return (vector unsigned char)__a | __b; +} + +static vector unsigned char __ATTRS_o_ai vec_vor(vector unsigned char __a, + vector bool char __b) { + return __a | (vector unsigned char)__b; +} + +static vector bool char __ATTRS_o_ai vec_vor(vector bool char __a, + vector bool char __b) { + return __a | __b; +} + +static vector short __ATTRS_o_ai vec_vor(vector short __a, vector short __b) { + return __a | __b; +} + +static vector short __ATTRS_o_ai vec_vor(vector bool short __a, + vector short __b) { + return (vector short)__a | __b; +} + +static vector short __ATTRS_o_ai vec_vor(vector short __a, + vector bool short __b) { + return __a | (vector short)__b; +} + +static vector unsigned short __ATTRS_o_ai vec_vor(vector unsigned short __a, + vector unsigned short __b) { + return __a | __b; +} + +static vector unsigned short __ATTRS_o_ai vec_vor(vector bool short __a, + vector unsigned short __b) { + return (vector unsigned short)__a | __b; +} + +static vector unsigned short __ATTRS_o_ai vec_vor(vector unsigned short __a, + vector bool short __b) { + return __a | (vector unsigned short)__b; +} + +static vector bool short __ATTRS_o_ai vec_vor(vector bool short __a, + vector bool short __b) { + return __a | __b; +} + +static vector int __ATTRS_o_ai vec_vor(vector int __a, vector int __b) { + return __a | __b; +} + +static vector int __ATTRS_o_ai vec_vor(vector bool int __a, vector int __b) { + return (vector int)__a | __b; +} + +static vector int __ATTRS_o_ai vec_vor(vector int __a, vector bool int __b) { + return __a | (vector int)__b; +} + +static vector unsigned int __ATTRS_o_ai vec_vor(vector unsigned int __a, + vector unsigned int __b) { + return __a | __b; +} + +static vector unsigned int __ATTRS_o_ai vec_vor(vector bool int __a, + vector unsigned int __b) { + return (vector unsigned int)__a | __b; +} + +static vector unsigned int __ATTRS_o_ai vec_vor(vector unsigned int __a, + vector bool int __b) { + return __a | (vector unsigned int)__b; +} + +static vector bool int __ATTRS_o_ai vec_vor(vector bool int __a, + vector bool int __b) { + return __a | __b; +} + +static vector float __ATTRS_o_ai vec_vor(vector float __a, vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a | (vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_vor(vector bool int __a, + vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a | (vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_vor(vector float __a, + vector bool int __b) { + vector unsigned int __res = + (vector unsigned int)__a | (vector unsigned int)__b; + return (vector float)__res; +} + +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai +vec_vor(vector signed long long __a, vector signed long long __b) { + return __a | __b; +} + +static vector signed long long __ATTRS_o_ai +vec_vor(vector bool long long __a, vector signed long long __b) { + return (vector signed long long)__a | __b; +} + +static vector signed long long __ATTRS_o_ai vec_vor(vector signed long long __a, + vector bool long long __b) { + return __a | (vector signed long long)__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_vor(vector unsigned long long __a, vector unsigned long long __b) { + return __a | __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_vor(vector bool long long __a, vector unsigned long long __b) { + return (vector unsigned long long)__a | __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_vor(vector unsigned long long __a, vector bool long long __b) { + return __a | (vector unsigned long long)__b; +} + +static vector bool long long __ATTRS_o_ai vec_vor(vector bool long long __a, + vector bool long long __b) { + return __a | __b; +} +#endif + +/* vec_pack */ + +/* The various vector pack instructions have a big-endian bias, so for + little endian we must handle reversed element numbering. */ + +static vector signed char __ATTRS_o_ai vec_pack(vector signed short __a, + vector signed short __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector signed char)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, + 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E)); +#else + return (vector signed char)vec_perm( + __a, __b, + (vector unsigned char)(0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, + 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F)); +#endif +} + +static vector unsigned char __ATTRS_o_ai vec_pack(vector unsigned short __a, + vector unsigned short __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector unsigned char)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, + 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E)); +#else + return (vector unsigned char)vec_perm( + __a, __b, + (vector unsigned char)(0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, + 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F)); +#endif +} + +static vector bool char __ATTRS_o_ai vec_pack(vector bool short __a, + vector bool short __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool char)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, + 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E)); +#else + return (vector bool char)vec_perm( + __a, __b, + (vector unsigned char)(0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, + 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F)); +#endif +} + +static vector short __ATTRS_o_ai vec_pack(vector int __a, vector int __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector short)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D, + 0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D)); +#else + return (vector short)vec_perm( + __a, __b, + (vector unsigned char)(0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F, + 0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F)); +#endif +} + +static vector unsigned short __ATTRS_o_ai vec_pack(vector unsigned int __a, + vector unsigned int __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector unsigned short)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D, + 0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D)); +#else + return (vector unsigned short)vec_perm( + __a, __b, + (vector unsigned char)(0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F, + 0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F)); +#endif +} + +static vector bool short __ATTRS_o_ai vec_pack(vector bool int __a, + vector bool int __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool short)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D, + 0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D)); +#else + return (vector bool short)vec_perm( + __a, __b, + (vector unsigned char)(0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F, + 0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F)); +#endif +} + +#ifdef __VSX__ +static vector signed int __ATTRS_o_ai vec_pack(vector signed long long __a, + vector signed long long __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector signed int)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, + 0x10, 0x11, 0x12, 0x13, 0x18, 0x19, 0x1A, 0x1B)); +#else + return (vector signed int)vec_perm( + __a, __b, + (vector unsigned char)(0x04, 0x05, 0x06, 0x07, 0x0C, 0x0D, 0x0E, 0x0F, + 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F)); +#endif +} +static vector unsigned int __ATTRS_o_ai +vec_pack(vector unsigned long long __a, vector unsigned long long __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector unsigned int)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, + 0x10, 0x11, 0x12, 0x13, 0x18, 0x19, 0x1A, 0x1B)); +#else + return (vector unsigned int)vec_perm( + __a, __b, + (vector unsigned char)(0x04, 0x05, 0x06, 0x07, 0x0C, 0x0D, 0x0E, 0x0F, + 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F)); +#endif +} + +static vector bool int __ATTRS_o_ai vec_pack(vector bool long long __a, + vector bool long long __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool int)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, + 0x10, 0x11, 0x12, 0x13, 0x18, 0x19, 0x1A, 0x1B)); +#else + return (vector bool int)vec_perm( + __a, __b, + (vector unsigned char)(0x04, 0x05, 0x06, 0x07, 0x0C, 0x0D, 0x0E, 0x0F, + 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F)); +#endif +} + +#endif + +/* vec_vpkuhum */ + +#define __builtin_altivec_vpkuhum vec_vpkuhum + +static vector signed char __ATTRS_o_ai vec_vpkuhum(vector signed short __a, + vector signed short __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector signed char)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, + 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E)); +#else + return (vector signed char)vec_perm( + __a, __b, + (vector unsigned char)(0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, + 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F)); +#endif +} + +static vector unsigned char __ATTRS_o_ai +vec_vpkuhum(vector unsigned short __a, vector unsigned short __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector unsigned char)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, + 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E)); +#else + return (vector unsigned char)vec_perm( + __a, __b, + (vector unsigned char)(0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, + 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F)); +#endif +} + +static vector bool char __ATTRS_o_ai vec_vpkuhum(vector bool short __a, + vector bool short __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool char)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, + 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E)); +#else + return (vector bool char)vec_perm( + __a, __b, + (vector unsigned char)(0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, + 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F)); +#endif +} + +/* vec_vpkuwum */ + +#define __builtin_altivec_vpkuwum vec_vpkuwum + +static vector short __ATTRS_o_ai vec_vpkuwum(vector int __a, vector int __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector short)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D, + 0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D)); +#else + return (vector short)vec_perm( + __a, __b, + (vector unsigned char)(0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F, + 0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F)); +#endif +} + +static vector unsigned short __ATTRS_o_ai vec_vpkuwum(vector unsigned int __a, + vector unsigned int __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector unsigned short)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D, + 0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D)); +#else + return (vector unsigned short)vec_perm( + __a, __b, + (vector unsigned char)(0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F, + 0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F)); +#endif +} + +static vector bool short __ATTRS_o_ai vec_vpkuwum(vector bool int __a, + vector bool int __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool short)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D, + 0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D)); +#else + return (vector bool short)vec_perm( + __a, __b, + (vector unsigned char)(0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F, + 0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F)); +#endif +} + +/* vec_vpkudum */ + +#ifdef __POWER8_VECTOR__ +#define __builtin_altivec_vpkudum vec_vpkudum + +static vector int __ATTRS_o_ai vec_vpkudum(vector long long __a, + vector long long __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector int)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, + 0x10, 0x11, 0x12, 0x13, 0x18, 0x19, 0x1A, 0x1B)); +#else + return (vector int)vec_perm( + __a, __b, + (vector unsigned char)(0x04, 0x05, 0x06, 0x07, 0x0C, 0x0D, 0x0E, 0x0F, + 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F)); +#endif +} + +static vector unsigned int __ATTRS_o_ai +vec_vpkudum(vector unsigned long long __a, vector unsigned long long __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector unsigned int)vec_perm( + __a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, + 0x10, 0x11, 0x12, 0x13, 0x18, 0x19, 0x1A, 0x1B)); +#else + return (vector unsigned int)vec_perm( + __a, __b, + (vector unsigned char)(0x04, 0x05, 0x06, 0x07, 0x0C, 0x0D, 0x0E, 0x0F, + 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F)); +#endif +} + +static vector bool int __ATTRS_o_ai vec_vpkudum(vector bool long long __a, + vector bool long long __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool int)vec_perm( + (vector long long)__a, (vector long long)__b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, + 0x10, 0x11, 0x12, 0x13, 0x18, 0x19, 0x1A, 0x1B)); +#else + return (vector bool int)vec_perm( + (vector long long)__a, (vector long long)__b, + (vector unsigned char)(0x04, 0x05, 0x06, 0x07, 0x0C, 0x0D, 0x0E, 0x0F, + 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F)); +#endif +} +#endif + +/* vec_packpx */ + +static vector pixel __attribute__((__always_inline__)) +vec_packpx(vector unsigned int __a, vector unsigned int __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector pixel)__builtin_altivec_vpkpx(__b, __a); +#else + return (vector pixel)__builtin_altivec_vpkpx(__a, __b); +#endif +} + +/* vec_vpkpx */ + +static vector pixel __attribute__((__always_inline__)) +vec_vpkpx(vector unsigned int __a, vector unsigned int __b) { +#ifdef __LITTLE_ENDIAN__ + return (vector pixel)__builtin_altivec_vpkpx(__b, __a); +#else + return (vector pixel)__builtin_altivec_vpkpx(__a, __b); +#endif +} + +/* vec_packs */ + +static vector signed char __ATTRS_o_ai vec_packs(vector short __a, + vector short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkshss(__b, __a); +#else + return __builtin_altivec_vpkshss(__a, __b); +#endif +} + +static vector unsigned char __ATTRS_o_ai vec_packs(vector unsigned short __a, + vector unsigned short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkuhus(__b, __a); +#else + return __builtin_altivec_vpkuhus(__a, __b); +#endif +} + +static vector signed short __ATTRS_o_ai vec_packs(vector int __a, + vector int __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkswss(__b, __a); +#else + return __builtin_altivec_vpkswss(__a, __b); +#endif +} + +static vector unsigned short __ATTRS_o_ai vec_packs(vector unsigned int __a, + vector unsigned int __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkuwus(__b, __a); +#else + return __builtin_altivec_vpkuwus(__a, __b); +#endif +} + +#ifdef __POWER8_VECTOR__ +static vector int __ATTRS_o_ai vec_packs(vector long long __a, + vector long long __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpksdss(__b, __a); +#else + return __builtin_altivec_vpksdss(__a, __b); +#endif +} + +static vector unsigned int __ATTRS_o_ai +vec_packs(vector unsigned long long __a, vector unsigned long long __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkudus(__b, __a); +#else + return __builtin_altivec_vpkudus(__a, __b); +#endif +} +#endif + +/* vec_vpkshss */ + +static vector signed char __attribute__((__always_inline__)) +vec_vpkshss(vector short __a, vector short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkshss(__b, __a); +#else + return __builtin_altivec_vpkshss(__a, __b); +#endif +} + +/* vec_vpksdss */ + +#ifdef __POWER8_VECTOR__ +static vector int __ATTRS_o_ai vec_vpksdss(vector long long __a, + vector long long __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpksdss(__b, __a); +#else + return __builtin_altivec_vpksdss(__a, __b); +#endif +} +#endif + +/* vec_vpkuhus */ + +static vector unsigned char __attribute__((__always_inline__)) +vec_vpkuhus(vector unsigned short __a, vector unsigned short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkuhus(__b, __a); +#else + return __builtin_altivec_vpkuhus(__a, __b); +#endif +} + +/* vec_vpkudus */ + +#ifdef __POWER8_VECTOR__ +static vector unsigned int __attribute__((__always_inline__)) +vec_vpkudus(vector unsigned long long __a, vector unsigned long long __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkudus(__b, __a); +#else + return __builtin_altivec_vpkudus(__a, __b); +#endif +} +#endif + +/* vec_vpkswss */ + +static vector signed short __attribute__((__always_inline__)) +vec_vpkswss(vector int __a, vector int __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkswss(__b, __a); +#else + return __builtin_altivec_vpkswss(__a, __b); +#endif +} + +/* vec_vpkuwus */ + +static vector unsigned short __attribute__((__always_inline__)) +vec_vpkuwus(vector unsigned int __a, vector unsigned int __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkuwus(__b, __a); +#else + return __builtin_altivec_vpkuwus(__a, __b); +#endif +} + +/* vec_packsu */ + +static vector unsigned char __ATTRS_o_ai vec_packsu(vector short __a, + vector short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkshus(__b, __a); +#else + return __builtin_altivec_vpkshus(__a, __b); +#endif +} + +static vector unsigned char __ATTRS_o_ai vec_packsu(vector unsigned short __a, + vector unsigned short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkuhus(__b, __a); +#else + return __builtin_altivec_vpkuhus(__a, __b); +#endif +} + +static vector unsigned short __ATTRS_o_ai vec_packsu(vector int __a, + vector int __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkswus(__b, __a); +#else + return __builtin_altivec_vpkswus(__a, __b); +#endif +} + +static vector unsigned short __ATTRS_o_ai vec_packsu(vector unsigned int __a, + vector unsigned int __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkuwus(__b, __a); +#else + return __builtin_altivec_vpkuwus(__a, __b); +#endif +} + +#ifdef __POWER8_VECTOR__ +static vector unsigned int __ATTRS_o_ai vec_packsu(vector long long __a, + vector long long __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpksdus(__b, __a); +#else + return __builtin_altivec_vpksdus(__a, __b); +#endif +} + +static vector unsigned int __ATTRS_o_ai +vec_packsu(vector unsigned long long __a, vector unsigned long long __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkudus(__b, __a); +#else + return __builtin_altivec_vpkudus(__a, __b); +#endif +} +#endif + +/* vec_vpkshus */ + +static vector unsigned char __ATTRS_o_ai vec_vpkshus(vector short __a, + vector short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkshus(__b, __a); +#else + return __builtin_altivec_vpkshus(__a, __b); +#endif +} + +static vector unsigned char __ATTRS_o_ai +vec_vpkshus(vector unsigned short __a, vector unsigned short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkuhus(__b, __a); +#else + return __builtin_altivec_vpkuhus(__a, __b); +#endif +} + +/* vec_vpkswus */ + +static vector unsigned short __ATTRS_o_ai vec_vpkswus(vector int __a, + vector int __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkswus(__b, __a); +#else + return __builtin_altivec_vpkswus(__a, __b); +#endif +} + +static vector unsigned short __ATTRS_o_ai vec_vpkswus(vector unsigned int __a, + vector unsigned int __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpkuwus(__b, __a); +#else + return __builtin_altivec_vpkuwus(__a, __b); +#endif +} + +/* vec_vpksdus */ + +#ifdef __POWER8_VECTOR__ +static vector unsigned int __ATTRS_o_ai vec_vpksdus(vector long long __a, + vector long long __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vpksdus(__b, __a); +#else + return __builtin_altivec_vpksdus(__a, __b); +#endif +} +#endif + +/* vec_perm */ + +// The vperm instruction is defined architecturally with a big-endian bias. +// For little endian, we swap the input operands and invert the permute +// control vector. Only the rightmost 5 bits matter, so we could use +// a vector of all 31s instead of all 255s to perform the inversion. +// However, when the PCV is not a constant, using 255 has an advantage +// in that the vec_xor can be recognized as a vec_nor (and for P8 and +// later, possibly a vec_nand). + +static vector signed char __ATTRS_o_ai vec_perm(vector signed char __a, + vector signed char __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector signed char)__builtin_altivec_vperm_4si((vector int)__b, + (vector int)__a, __d); +#else + return (vector signed char)__builtin_altivec_vperm_4si((vector int)__a, + (vector int)__b, __c); +#endif +} + +static vector unsigned char __ATTRS_o_ai vec_perm(vector unsigned char __a, + vector unsigned char __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector unsigned char)__builtin_altivec_vperm_4si( + (vector int)__b, (vector int)__a, __d); +#else + return (vector unsigned char)__builtin_altivec_vperm_4si( + (vector int)__a, (vector int)__b, __c); +#endif +} + +static vector bool char __ATTRS_o_ai vec_perm(vector bool char __a, + vector bool char __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector bool char)__builtin_altivec_vperm_4si((vector int)__b, + (vector int)__a, __d); +#else + return (vector bool char)__builtin_altivec_vperm_4si((vector int)__a, + (vector int)__b, __c); +#endif +} + +static vector short __ATTRS_o_ai vec_perm(vector signed short __a, + vector signed short __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector signed short)__builtin_altivec_vperm_4si((vector int)__b, + (vector int)__a, __d); +#else + return (vector signed short)__builtin_altivec_vperm_4si((vector int)__a, + (vector int)__b, __c); +#endif +} + +static vector unsigned short __ATTRS_o_ai vec_perm(vector unsigned short __a, + vector unsigned short __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector unsigned short)__builtin_altivec_vperm_4si( + (vector int)__b, (vector int)__a, __d); +#else + return (vector unsigned short)__builtin_altivec_vperm_4si( + (vector int)__a, (vector int)__b, __c); +#endif +} + +static vector bool short __ATTRS_o_ai vec_perm(vector bool short __a, + vector bool short __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector bool short)__builtin_altivec_vperm_4si((vector int)__b, + (vector int)__a, __d); +#else + return (vector bool short)__builtin_altivec_vperm_4si((vector int)__a, + (vector int)__b, __c); +#endif +} + +static vector pixel __ATTRS_o_ai vec_perm(vector pixel __a, vector pixel __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector pixel)__builtin_altivec_vperm_4si((vector int)__b, + (vector int)__a, __d); +#else + return (vector pixel)__builtin_altivec_vperm_4si((vector int)__a, + (vector int)__b, __c); +#endif +} + +static vector int __ATTRS_o_ai vec_perm(vector signed int __a, + vector signed int __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector signed int)__builtin_altivec_vperm_4si(__b, __a, __d); +#else + return (vector signed int)__builtin_altivec_vperm_4si(__a, __b, __c); +#endif +} + +static vector unsigned int __ATTRS_o_ai vec_perm(vector unsigned int __a, + vector unsigned int __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector unsigned int)__builtin_altivec_vperm_4si((vector int)__b, + (vector int)__a, __d); +#else + return (vector unsigned int)__builtin_altivec_vperm_4si((vector int)__a, + (vector int)__b, __c); +#endif +} + +static vector bool int __ATTRS_o_ai vec_perm(vector bool int __a, + vector bool int __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector bool int)__builtin_altivec_vperm_4si((vector int)__b, + (vector int)__a, __d); +#else + return (vector bool int)__builtin_altivec_vperm_4si((vector int)__a, + (vector int)__b, __c); +#endif +} + +static vector float __ATTRS_o_ai vec_perm(vector float __a, vector float __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector float)__builtin_altivec_vperm_4si((vector int)__b, + (vector int)__a, __d); +#else + return (vector float)__builtin_altivec_vperm_4si((vector int)__a, + (vector int)__b, __c); +#endif +} + +#ifdef __VSX__ +static vector long long __ATTRS_o_ai vec_perm(vector signed long long __a, + vector signed long long __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector signed long long)__builtin_altivec_vperm_4si( + (vector int)__b, (vector int)__a, __d); +#else + return (vector signed long long)__builtin_altivec_vperm_4si( + (vector int)__a, (vector int)__b, __c); +#endif +} + +static vector unsigned long long __ATTRS_o_ai +vec_perm(vector unsigned long long __a, vector unsigned long long __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector unsigned long long)__builtin_altivec_vperm_4si( + (vector int)__b, (vector int)__a, __d); +#else + return (vector unsigned long long)__builtin_altivec_vperm_4si( + (vector int)__a, (vector int)__b, __c); +#endif +} + +static vector bool long long __ATTRS_o_ai +vec_perm(vector bool long long __a, vector bool long long __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector bool long long)__builtin_altivec_vperm_4si( + (vector int)__b, (vector int)__a, __d); +#else + return (vector bool long long)__builtin_altivec_vperm_4si( + (vector int)__a, (vector int)__b, __c); +#endif +} + +static vector double __ATTRS_o_ai vec_perm(vector double __a, vector double __b, + vector unsigned char __c) { +#ifdef __LITTLE_ENDIAN__ + vector unsigned char __d = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255}; + __d = vec_xor(__c, __d); + return (vector double)__builtin_altivec_vperm_4si((vector int)__b, + (vector int)__a, __d); +#else + return (vector double)__builtin_altivec_vperm_4si((vector int)__a, + (vector int)__b, __c); +#endif +} +#endif + +/* vec_vperm */ + +static vector signed char __ATTRS_o_ai vec_vperm(vector signed char __a, + vector signed char __b, + vector unsigned char __c) { + return vec_perm(__a, __b, __c); +} + +static vector unsigned char __ATTRS_o_ai vec_vperm(vector unsigned char __a, + vector unsigned char __b, + vector unsigned char __c) { + return vec_perm(__a, __b, __c); +} + +static vector bool char __ATTRS_o_ai vec_vperm(vector bool char __a, + vector bool char __b, + vector unsigned char __c) { + return vec_perm(__a, __b, __c); +} + +static vector short __ATTRS_o_ai vec_vperm(vector short __a, vector short __b, + vector unsigned char __c) { + return vec_perm(__a, __b, __c); +} + +static vector unsigned short __ATTRS_o_ai vec_vperm(vector unsigned short __a, + vector unsigned short __b, + vector unsigned char __c) { + return vec_perm(__a, __b, __c); +} + +static vector bool short __ATTRS_o_ai vec_vperm(vector bool short __a, + vector bool short __b, + vector unsigned char __c) { + return vec_perm(__a, __b, __c); +} + +static vector pixel __ATTRS_o_ai vec_vperm(vector pixel __a, vector pixel __b, + vector unsigned char __c) { + return vec_perm(__a, __b, __c); +} + +static vector int __ATTRS_o_ai vec_vperm(vector int __a, vector int __b, + vector unsigned char __c) { + return vec_perm(__a, __b, __c); +} + +static vector unsigned int __ATTRS_o_ai vec_vperm(vector unsigned int __a, + vector unsigned int __b, + vector unsigned char __c) { + return vec_perm(__a, __b, __c); +} + +static vector bool int __ATTRS_o_ai vec_vperm(vector bool int __a, + vector bool int __b, + vector unsigned char __c) { + return vec_perm(__a, __b, __c); +} + +static vector float __ATTRS_o_ai vec_vperm(vector float __a, vector float __b, + vector unsigned char __c) { + return vec_perm(__a, __b, __c); +} + +#ifdef __VSX__ +static vector long long __ATTRS_o_ai vec_vperm(vector long long __a, + vector long long __b, + vector unsigned char __c) { + return vec_perm(__a, __b, __c); +} + +static vector unsigned long long __ATTRS_o_ai +vec_vperm(vector unsigned long long __a, vector unsigned long long __b, + vector unsigned char __c) { + return vec_perm(__a, __b, __c); +} + +static vector double __ATTRS_o_ai vec_vperm(vector double __a, + vector double __b, + vector unsigned char __c) { + return vec_perm(__a, __b, __c); +} +#endif + +/* vec_re */ + +static vector float __ATTRS_o_ai +vec_re(vector float __a) { +#ifdef __VSX__ + return __builtin_vsx_xvresp(__a); +#else + return __builtin_altivec_vrefp(__a); +#endif +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai vec_re(vector double __a) { + return __builtin_vsx_xvredp(__a); +} +#endif + +/* vec_vrefp */ + +static vector float __attribute__((__always_inline__)) +vec_vrefp(vector float __a) { + return __builtin_altivec_vrefp(__a); +} + +/* vec_rl */ + +static vector signed char __ATTRS_o_ai vec_rl(vector signed char __a, + vector unsigned char __b) { + return (vector signed char)__builtin_altivec_vrlb((vector char)__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_rl(vector unsigned char __a, + vector unsigned char __b) { + return (vector unsigned char)__builtin_altivec_vrlb((vector char)__a, __b); +} + +static vector short __ATTRS_o_ai vec_rl(vector short __a, + vector unsigned short __b) { + return __builtin_altivec_vrlh(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_rl(vector unsigned short __a, + vector unsigned short __b) { + return (vector unsigned short)__builtin_altivec_vrlh((vector short)__a, __b); +} + +static vector int __ATTRS_o_ai vec_rl(vector int __a, vector unsigned int __b) { + return __builtin_altivec_vrlw(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_rl(vector unsigned int __a, + vector unsigned int __b) { + return (vector unsigned int)__builtin_altivec_vrlw((vector int)__a, __b); +} + +#ifdef __POWER8_VECTOR__ +static vector signed long long __ATTRS_o_ai +vec_rl(vector signed long long __a, vector unsigned long long __b) { + return __builtin_altivec_vrld(__a, __b); +} + +static vector unsigned long long __ATTRS_o_ai +vec_rl(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_altivec_vrld(__a, __b); +} +#endif + +/* vec_vrlb */ + +static vector signed char __ATTRS_o_ai vec_vrlb(vector signed char __a, + vector unsigned char __b) { + return (vector signed char)__builtin_altivec_vrlb((vector char)__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_vrlb(vector unsigned char __a, + vector unsigned char __b) { + return (vector unsigned char)__builtin_altivec_vrlb((vector char)__a, __b); +} + +/* vec_vrlh */ + +static vector short __ATTRS_o_ai vec_vrlh(vector short __a, + vector unsigned short __b) { + return __builtin_altivec_vrlh(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_vrlh(vector unsigned short __a, + vector unsigned short __b) { + return (vector unsigned short)__builtin_altivec_vrlh((vector short)__a, __b); +} + +/* vec_vrlw */ + +static vector int __ATTRS_o_ai vec_vrlw(vector int __a, + vector unsigned int __b) { + return __builtin_altivec_vrlw(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_vrlw(vector unsigned int __a, + vector unsigned int __b) { + return (vector unsigned int)__builtin_altivec_vrlw((vector int)__a, __b); +} + +/* vec_round */ + +static vector float __ATTRS_o_ai vec_round(vector float __a) { +#ifdef __VSX__ + return __builtin_vsx_xvrspi(__a); +#else + return __builtin_altivec_vrfin(__a); +#endif +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai vec_round(vector double __a) { + return __builtin_vsx_xvrdpi(__a); +} + +/* vec_rint */ + +static vector float __ATTRS_o_ai +vec_rint(vector float __a) { + return __builtin_vsx_xvrspic(__a); +} + +static vector double __ATTRS_o_ai +vec_rint(vector double __a) { + return __builtin_vsx_xvrdpic(__a); +} + +/* vec_nearbyint */ + +static vector float __ATTRS_o_ai vec_nearbyint(vector float __a) { + return __builtin_vsx_xvrspi(__a); +} + +static vector double __ATTRS_o_ai vec_nearbyint(vector double __a) { + return __builtin_vsx_xvrdpi(__a); +} +#endif + +/* vec_vrfin */ + +static vector float __attribute__((__always_inline__)) +vec_vrfin(vector float __a) { + return __builtin_altivec_vrfin(__a); +} + +/* vec_sqrt */ + +#ifdef __VSX__ +static vector float __ATTRS_o_ai vec_sqrt(vector float __a) { + return __builtin_vsx_xvsqrtsp(__a); +} + +static vector double __ATTRS_o_ai vec_sqrt(vector double __a) { + return __builtin_vsx_xvsqrtdp(__a); +} +#endif + +/* vec_rsqrte */ + +static vector float __ATTRS_o_ai +vec_rsqrte(vector float __a) { +#ifdef __VSX__ + return __builtin_vsx_xvrsqrtesp(__a); +#else + return __builtin_altivec_vrsqrtefp(__a); +#endif +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai vec_rsqrte(vector double __a) { + return __builtin_vsx_xvrsqrtedp(__a); +} +#endif + +/* vec_vrsqrtefp */ + +static __vector float __attribute__((__always_inline__)) +vec_vrsqrtefp(vector float __a) { + return __builtin_altivec_vrsqrtefp(__a); +} + +/* vec_sel */ + +#define __builtin_altivec_vsel_4si vec_sel + +static vector signed char __ATTRS_o_ai vec_sel(vector signed char __a, + vector signed char __b, + vector unsigned char __c) { + return (__a & ~(vector signed char)__c) | (__b & (vector signed char)__c); +} + +static vector signed char __ATTRS_o_ai vec_sel(vector signed char __a, + vector signed char __b, + vector bool char __c) { + return (__a & ~(vector signed char)__c) | (__b & (vector signed char)__c); +} + +static vector unsigned char __ATTRS_o_ai vec_sel(vector unsigned char __a, + vector unsigned char __b, + vector unsigned char __c) { + return (__a & ~__c) | (__b & __c); +} + +static vector unsigned char __ATTRS_o_ai vec_sel(vector unsigned char __a, + vector unsigned char __b, + vector bool char __c) { + return (__a & ~(vector unsigned char)__c) | (__b & (vector unsigned char)__c); +} + +static vector bool char __ATTRS_o_ai vec_sel(vector bool char __a, + vector bool char __b, + vector unsigned char __c) { + return (__a & ~(vector bool char)__c) | (__b & (vector bool char)__c); +} + +static vector bool char __ATTRS_o_ai vec_sel(vector bool char __a, + vector bool char __b, + vector bool char __c) { + return (__a & ~__c) | (__b & __c); +} + +static vector short __ATTRS_o_ai vec_sel(vector short __a, vector short __b, + vector unsigned short __c) { + return (__a & ~(vector short)__c) | (__b & (vector short)__c); +} + +static vector short __ATTRS_o_ai vec_sel(vector short __a, vector short __b, + vector bool short __c) { + return (__a & ~(vector short)__c) | (__b & (vector short)__c); +} + +static vector unsigned short __ATTRS_o_ai vec_sel(vector unsigned short __a, + vector unsigned short __b, + vector unsigned short __c) { + return (__a & ~__c) | (__b & __c); +} + +static vector unsigned short __ATTRS_o_ai vec_sel(vector unsigned short __a, + vector unsigned short __b, + vector bool short __c) { + return (__a & ~(vector unsigned short)__c) | + (__b & (vector unsigned short)__c); +} + +static vector bool short __ATTRS_o_ai vec_sel(vector bool short __a, + vector bool short __b, + vector unsigned short __c) { + return (__a & ~(vector bool short)__c) | (__b & (vector bool short)__c); +} + +static vector bool short __ATTRS_o_ai vec_sel(vector bool short __a, + vector bool short __b, + vector bool short __c) { + return (__a & ~__c) | (__b & __c); +} + +static vector int __ATTRS_o_ai vec_sel(vector int __a, vector int __b, + vector unsigned int __c) { + return (__a & ~(vector int)__c) | (__b & (vector int)__c); +} + +static vector int __ATTRS_o_ai vec_sel(vector int __a, vector int __b, + vector bool int __c) { + return (__a & ~(vector int)__c) | (__b & (vector int)__c); +} + +static vector unsigned int __ATTRS_o_ai vec_sel(vector unsigned int __a, + vector unsigned int __b, + vector unsigned int __c) { + return (__a & ~__c) | (__b & __c); +} + +static vector unsigned int __ATTRS_o_ai vec_sel(vector unsigned int __a, + vector unsigned int __b, + vector bool int __c) { + return (__a & ~(vector unsigned int)__c) | (__b & (vector unsigned int)__c); +} + +static vector bool int __ATTRS_o_ai vec_sel(vector bool int __a, + vector bool int __b, + vector unsigned int __c) { + return (__a & ~(vector bool int)__c) | (__b & (vector bool int)__c); +} + +static vector bool int __ATTRS_o_ai vec_sel(vector bool int __a, + vector bool int __b, + vector bool int __c) { + return (__a & ~__c) | (__b & __c); +} + +static vector float __ATTRS_o_ai vec_sel(vector float __a, vector float __b, + vector unsigned int __c) { + vector int __res = ((vector int)__a & ~(vector int)__c) | + ((vector int)__b & (vector int)__c); + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_sel(vector float __a, vector float __b, + vector bool int __c) { + vector int __res = ((vector int)__a & ~(vector int)__c) | + ((vector int)__b & (vector int)__c); + return (vector float)__res; +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai vec_sel(vector double __a, vector double __b, + vector bool long long __c) { + vector long long __res = ((vector long long)__a & ~(vector long long)__c) | + ((vector long long)__b & (vector long long)__c); + return (vector double)__res; +} + +static vector double __ATTRS_o_ai vec_sel(vector double __a, vector double __b, + vector unsigned long long __c) { + vector long long __res = ((vector long long)__a & ~(vector long long)__c) | + ((vector long long)__b & (vector long long)__c); + return (vector double)__res; +} +#endif + +/* vec_vsel */ + +static vector signed char __ATTRS_o_ai vec_vsel(vector signed char __a, + vector signed char __b, + vector unsigned char __c) { + return (__a & ~(vector signed char)__c) | (__b & (vector signed char)__c); +} + +static vector signed char __ATTRS_o_ai vec_vsel(vector signed char __a, + vector signed char __b, + vector bool char __c) { + return (__a & ~(vector signed char)__c) | (__b & (vector signed char)__c); +} + +static vector unsigned char __ATTRS_o_ai vec_vsel(vector unsigned char __a, + vector unsigned char __b, + vector unsigned char __c) { + return (__a & ~__c) | (__b & __c); +} + +static vector unsigned char __ATTRS_o_ai vec_vsel(vector unsigned char __a, + vector unsigned char __b, + vector bool char __c) { + return (__a & ~(vector unsigned char)__c) | (__b & (vector unsigned char)__c); +} + +static vector bool char __ATTRS_o_ai vec_vsel(vector bool char __a, + vector bool char __b, + vector unsigned char __c) { + return (__a & ~(vector bool char)__c) | (__b & (vector bool char)__c); +} + +static vector bool char __ATTRS_o_ai vec_vsel(vector bool char __a, + vector bool char __b, + vector bool char __c) { + return (__a & ~__c) | (__b & __c); +} + +static vector short __ATTRS_o_ai vec_vsel(vector short __a, vector short __b, + vector unsigned short __c) { + return (__a & ~(vector short)__c) | (__b & (vector short)__c); +} + +static vector short __ATTRS_o_ai vec_vsel(vector short __a, vector short __b, + vector bool short __c) { + return (__a & ~(vector short)__c) | (__b & (vector short)__c); +} + +static vector unsigned short __ATTRS_o_ai vec_vsel(vector unsigned short __a, + vector unsigned short __b, + vector unsigned short __c) { + return (__a & ~__c) | (__b & __c); +} + +static vector unsigned short __ATTRS_o_ai vec_vsel(vector unsigned short __a, + vector unsigned short __b, + vector bool short __c) { + return (__a & ~(vector unsigned short)__c) | + (__b & (vector unsigned short)__c); +} + +static vector bool short __ATTRS_o_ai vec_vsel(vector bool short __a, + vector bool short __b, + vector unsigned short __c) { + return (__a & ~(vector bool short)__c) | (__b & (vector bool short)__c); +} + +static vector bool short __ATTRS_o_ai vec_vsel(vector bool short __a, + vector bool short __b, + vector bool short __c) { + return (__a & ~__c) | (__b & __c); +} + +static vector int __ATTRS_o_ai vec_vsel(vector int __a, vector int __b, + vector unsigned int __c) { + return (__a & ~(vector int)__c) | (__b & (vector int)__c); +} + +static vector int __ATTRS_o_ai vec_vsel(vector int __a, vector int __b, + vector bool int __c) { + return (__a & ~(vector int)__c) | (__b & (vector int)__c); +} + +static vector unsigned int __ATTRS_o_ai vec_vsel(vector unsigned int __a, + vector unsigned int __b, + vector unsigned int __c) { + return (__a & ~__c) | (__b & __c); +} + +static vector unsigned int __ATTRS_o_ai vec_vsel(vector unsigned int __a, + vector unsigned int __b, + vector bool int __c) { + return (__a & ~(vector unsigned int)__c) | (__b & (vector unsigned int)__c); +} + +static vector bool int __ATTRS_o_ai vec_vsel(vector bool int __a, + vector bool int __b, + vector unsigned int __c) { + return (__a & ~(vector bool int)__c) | (__b & (vector bool int)__c); +} + +static vector bool int __ATTRS_o_ai vec_vsel(vector bool int __a, + vector bool int __b, + vector bool int __c) { + return (__a & ~__c) | (__b & __c); +} + +static vector float __ATTRS_o_ai vec_vsel(vector float __a, vector float __b, + vector unsigned int __c) { + vector int __res = ((vector int)__a & ~(vector int)__c) | + ((vector int)__b & (vector int)__c); + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_vsel(vector float __a, vector float __b, + vector bool int __c) { + vector int __res = ((vector int)__a & ~(vector int)__c) | + ((vector int)__b & (vector int)__c); + return (vector float)__res; +} + +/* vec_sl */ + +static vector signed char __ATTRS_o_ai vec_sl(vector signed char __a, + vector unsigned char __b) { + return __a << (vector signed char)__b; +} + +static vector unsigned char __ATTRS_o_ai vec_sl(vector unsigned char __a, + vector unsigned char __b) { + return __a << __b; +} + +static vector short __ATTRS_o_ai vec_sl(vector short __a, + vector unsigned short __b) { + return __a << (vector short)__b; +} + +static vector unsigned short __ATTRS_o_ai vec_sl(vector unsigned short __a, + vector unsigned short __b) { + return __a << __b; +} + +static vector int __ATTRS_o_ai vec_sl(vector int __a, vector unsigned int __b) { + return __a << (vector int)__b; +} + +static vector unsigned int __ATTRS_o_ai vec_sl(vector unsigned int __a, + vector unsigned int __b) { + return __a << __b; +} + +#ifdef __POWER8_VECTOR__ +static vector signed long long __ATTRS_o_ai +vec_sl(vector signed long long __a, vector unsigned long long __b) { + return __a << (vector long long)__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_sl(vector unsigned long long __a, vector unsigned long long __b) { + return __a << __b; +} +#endif + +/* vec_vslb */ + +#define __builtin_altivec_vslb vec_vslb + +static vector signed char __ATTRS_o_ai vec_vslb(vector signed char __a, + vector unsigned char __b) { + return vec_sl(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_vslb(vector unsigned char __a, + vector unsigned char __b) { + return vec_sl(__a, __b); +} + +/* vec_vslh */ + +#define __builtin_altivec_vslh vec_vslh + +static vector short __ATTRS_o_ai vec_vslh(vector short __a, + vector unsigned short __b) { + return vec_sl(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_vslh(vector unsigned short __a, + vector unsigned short __b) { + return vec_sl(__a, __b); +} + +/* vec_vslw */ + +#define __builtin_altivec_vslw vec_vslw + +static vector int __ATTRS_o_ai vec_vslw(vector int __a, + vector unsigned int __b) { + return vec_sl(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_vslw(vector unsigned int __a, + vector unsigned int __b) { + return vec_sl(__a, __b); +} + +/* vec_sld */ + +#define __builtin_altivec_vsldoi_4si vec_sld + +static vector signed char __ATTRS_o_ai vec_sld(vector signed char __a, + vector signed char __b, + unsigned const int __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector unsigned char __ATTRS_o_ai vec_sld(vector unsigned char __a, + vector unsigned char __b, + unsigned const int __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector bool char __ATTRS_o_ai vec_sld(vector bool char __a, + vector bool char __b, + unsigned const int __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector signed short __ATTRS_o_ai vec_sld(vector signed short __a, + vector signed short __b, + unsigned const int __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector unsigned short __ATTRS_o_ai vec_sld(vector unsigned short __a, + vector unsigned short __b, + unsigned const int __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector bool short __ATTRS_o_ai vec_sld(vector bool short __a, + vector bool short __b, + unsigned const int __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector pixel __ATTRS_o_ai vec_sld(vector pixel __a, vector pixel __b, + unsigned const int __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector signed int __ATTRS_o_ai vec_sld(vector signed int __a, + vector signed int __b, + unsigned const int __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector unsigned int __ATTRS_o_ai vec_sld(vector unsigned int __a, + vector unsigned int __b, + unsigned const int __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector bool int __ATTRS_o_ai vec_sld(vector bool int __a, + vector bool int __b, + unsigned const int __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector float __ATTRS_o_ai vec_sld(vector float __a, vector float __b, + unsigned const int __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +/* vec_vsldoi */ + +static vector signed char __ATTRS_o_ai vec_vsldoi(vector signed char __a, + vector signed char __b, + unsigned char __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector unsigned char __ATTRS_o_ai vec_vsldoi(vector unsigned char __a, + vector unsigned char __b, + unsigned char __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector short __ATTRS_o_ai vec_vsldoi(vector short __a, vector short __b, + unsigned char __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector unsigned short __ATTRS_o_ai vec_vsldoi(vector unsigned short __a, + vector unsigned short __b, + unsigned char __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector pixel __ATTRS_o_ai vec_vsldoi(vector pixel __a, vector pixel __b, + unsigned char __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector int __ATTRS_o_ai vec_vsldoi(vector int __a, vector int __b, + unsigned char __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector unsigned int __ATTRS_o_ai vec_vsldoi(vector unsigned int __a, + vector unsigned int __b, + unsigned char __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +static vector float __ATTRS_o_ai vec_vsldoi(vector float __a, vector float __b, + unsigned char __c) { + unsigned char __d = __c & 0x0F; +#ifdef __LITTLE_ENDIAN__ + return vec_perm( + __b, __a, + (vector unsigned char)(16 - __d, 17 - __d, 18 - __d, 19 - __d, 20 - __d, + 21 - __d, 22 - __d, 23 - __d, 24 - __d, 25 - __d, + 26 - __d, 27 - __d, 28 - __d, 29 - __d, 30 - __d, + 31 - __d)); +#else + return vec_perm( + __a, __b, + (vector unsigned char)(__d, __d + 1, __d + 2, __d + 3, __d + 4, __d + 5, + __d + 6, __d + 7, __d + 8, __d + 9, __d + 10, + __d + 11, __d + 12, __d + 13, __d + 14, __d + 15)); +#endif +} + +/* vec_sll */ + +static vector signed char __ATTRS_o_ai vec_sll(vector signed char __a, + vector unsigned char __b) { + return (vector signed char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector signed char __ATTRS_o_ai vec_sll(vector signed char __a, + vector unsigned short __b) { + return (vector signed char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector signed char __ATTRS_o_ai vec_sll(vector signed char __a, + vector unsigned int __b) { + return (vector signed char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_sll(vector unsigned char __a, + vector unsigned char __b) { + return (vector unsigned char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_sll(vector unsigned char __a, + vector unsigned short __b) { + return (vector unsigned char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_sll(vector unsigned char __a, + vector unsigned int __b) { + return (vector unsigned char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool char __ATTRS_o_ai vec_sll(vector bool char __a, + vector unsigned char __b) { + return (vector bool char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool char __ATTRS_o_ai vec_sll(vector bool char __a, + vector unsigned short __b) { + return (vector bool char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool char __ATTRS_o_ai vec_sll(vector bool char __a, + vector unsigned int __b) { + return (vector bool char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_sll(vector short __a, + vector unsigned char __b) { + return (vector short)__builtin_altivec_vsl((vector int)__a, (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_sll(vector short __a, + vector unsigned short __b) { + return (vector short)__builtin_altivec_vsl((vector int)__a, (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_sll(vector short __a, + vector unsigned int __b) { + return (vector short)__builtin_altivec_vsl((vector int)__a, (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_sll(vector unsigned short __a, + vector unsigned char __b) { + return (vector unsigned short)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_sll(vector unsigned short __a, + vector unsigned short __b) { + return (vector unsigned short)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_sll(vector unsigned short __a, + vector unsigned int __b) { + return (vector unsigned short)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool short __ATTRS_o_ai vec_sll(vector bool short __a, + vector unsigned char __b) { + return (vector bool short)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool short __ATTRS_o_ai vec_sll(vector bool short __a, + vector unsigned short __b) { + return (vector bool short)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool short __ATTRS_o_ai vec_sll(vector bool short __a, + vector unsigned int __b) { + return (vector bool short)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_sll(vector pixel __a, + vector unsigned char __b) { + return (vector pixel)__builtin_altivec_vsl((vector int)__a, (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_sll(vector pixel __a, + vector unsigned short __b) { + return (vector pixel)__builtin_altivec_vsl((vector int)__a, (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_sll(vector pixel __a, + vector unsigned int __b) { + return (vector pixel)__builtin_altivec_vsl((vector int)__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_sll(vector int __a, + vector unsigned char __b) { + return (vector int)__builtin_altivec_vsl(__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_sll(vector int __a, + vector unsigned short __b) { + return (vector int)__builtin_altivec_vsl(__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_sll(vector int __a, + vector unsigned int __b) { + return (vector int)__builtin_altivec_vsl(__a, (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_sll(vector unsigned int __a, + vector unsigned char __b) { + return (vector unsigned int)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_sll(vector unsigned int __a, + vector unsigned short __b) { + return (vector unsigned int)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_sll(vector unsigned int __a, + vector unsigned int __b) { + return (vector unsigned int)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool int __ATTRS_o_ai vec_sll(vector bool int __a, + vector unsigned char __b) { + return (vector bool int)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool int __ATTRS_o_ai vec_sll(vector bool int __a, + vector unsigned short __b) { + return (vector bool int)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool int __ATTRS_o_ai vec_sll(vector bool int __a, + vector unsigned int __b) { + return (vector bool int)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +/* vec_vsl */ + +static vector signed char __ATTRS_o_ai vec_vsl(vector signed char __a, + vector unsigned char __b) { + return (vector signed char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector signed char __ATTRS_o_ai vec_vsl(vector signed char __a, + vector unsigned short __b) { + return (vector signed char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector signed char __ATTRS_o_ai vec_vsl(vector signed char __a, + vector unsigned int __b) { + return (vector signed char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_vsl(vector unsigned char __a, + vector unsigned char __b) { + return (vector unsigned char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_vsl(vector unsigned char __a, + vector unsigned short __b) { + return (vector unsigned char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_vsl(vector unsigned char __a, + vector unsigned int __b) { + return (vector unsigned char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool char __ATTRS_o_ai vec_vsl(vector bool char __a, + vector unsigned char __b) { + return (vector bool char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool char __ATTRS_o_ai vec_vsl(vector bool char __a, + vector unsigned short __b) { + return (vector bool char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool char __ATTRS_o_ai vec_vsl(vector bool char __a, + vector unsigned int __b) { + return (vector bool char)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_vsl(vector short __a, + vector unsigned char __b) { + return (vector short)__builtin_altivec_vsl((vector int)__a, (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_vsl(vector short __a, + vector unsigned short __b) { + return (vector short)__builtin_altivec_vsl((vector int)__a, (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_vsl(vector short __a, + vector unsigned int __b) { + return (vector short)__builtin_altivec_vsl((vector int)__a, (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_vsl(vector unsigned short __a, + vector unsigned char __b) { + return (vector unsigned short)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_vsl(vector unsigned short __a, + vector unsigned short __b) { + return (vector unsigned short)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_vsl(vector unsigned short __a, + vector unsigned int __b) { + return (vector unsigned short)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool short __ATTRS_o_ai vec_vsl(vector bool short __a, + vector unsigned char __b) { + return (vector bool short)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool short __ATTRS_o_ai vec_vsl(vector bool short __a, + vector unsigned short __b) { + return (vector bool short)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool short __ATTRS_o_ai vec_vsl(vector bool short __a, + vector unsigned int __b) { + return (vector bool short)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_vsl(vector pixel __a, + vector unsigned char __b) { + return (vector pixel)__builtin_altivec_vsl((vector int)__a, (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_vsl(vector pixel __a, + vector unsigned short __b) { + return (vector pixel)__builtin_altivec_vsl((vector int)__a, (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_vsl(vector pixel __a, + vector unsigned int __b) { + return (vector pixel)__builtin_altivec_vsl((vector int)__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_vsl(vector int __a, + vector unsigned char __b) { + return (vector int)__builtin_altivec_vsl(__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_vsl(vector int __a, + vector unsigned short __b) { + return (vector int)__builtin_altivec_vsl(__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_vsl(vector int __a, + vector unsigned int __b) { + return (vector int)__builtin_altivec_vsl(__a, (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_vsl(vector unsigned int __a, + vector unsigned char __b) { + return (vector unsigned int)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_vsl(vector unsigned int __a, + vector unsigned short __b) { + return (vector unsigned int)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_vsl(vector unsigned int __a, + vector unsigned int __b) { + return (vector unsigned int)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool int __ATTRS_o_ai vec_vsl(vector bool int __a, + vector unsigned char __b) { + return (vector bool int)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool int __ATTRS_o_ai vec_vsl(vector bool int __a, + vector unsigned short __b) { + return (vector bool int)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +static vector bool int __ATTRS_o_ai vec_vsl(vector bool int __a, + vector unsigned int __b) { + return (vector bool int)__builtin_altivec_vsl((vector int)__a, + (vector int)__b); +} + +/* vec_slo */ + +static vector signed char __ATTRS_o_ai vec_slo(vector signed char __a, + vector signed char __b) { + return (vector signed char)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector signed char __ATTRS_o_ai vec_slo(vector signed char __a, + vector unsigned char __b) { + return (vector signed char)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_slo(vector unsigned char __a, + vector signed char __b) { + return (vector unsigned char)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_slo(vector unsigned char __a, + vector unsigned char __b) { + return (vector unsigned char)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_slo(vector short __a, + vector signed char __b) { + return (vector short)__builtin_altivec_vslo((vector int)__a, (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_slo(vector short __a, + vector unsigned char __b) { + return (vector short)__builtin_altivec_vslo((vector int)__a, (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_slo(vector unsigned short __a, + vector signed char __b) { + return (vector unsigned short)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_slo(vector unsigned short __a, + vector unsigned char __b) { + return (vector unsigned short)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_slo(vector pixel __a, + vector signed char __b) { + return (vector pixel)__builtin_altivec_vslo((vector int)__a, (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_slo(vector pixel __a, + vector unsigned char __b) { + return (vector pixel)__builtin_altivec_vslo((vector int)__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_slo(vector int __a, vector signed char __b) { + return (vector int)__builtin_altivec_vslo(__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_slo(vector int __a, + vector unsigned char __b) { + return (vector int)__builtin_altivec_vslo(__a, (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_slo(vector unsigned int __a, + vector signed char __b) { + return (vector unsigned int)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_slo(vector unsigned int __a, + vector unsigned char __b) { + return (vector unsigned int)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector float __ATTRS_o_ai vec_slo(vector float __a, + vector signed char __b) { + return (vector float)__builtin_altivec_vslo((vector int)__a, (vector int)__b); +} + +static vector float __ATTRS_o_ai vec_slo(vector float __a, + vector unsigned char __b) { + return (vector float)__builtin_altivec_vslo((vector int)__a, (vector int)__b); +} + +/* vec_vslo */ + +static vector signed char __ATTRS_o_ai vec_vslo(vector signed char __a, + vector signed char __b) { + return (vector signed char)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector signed char __ATTRS_o_ai vec_vslo(vector signed char __a, + vector unsigned char __b) { + return (vector signed char)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_vslo(vector unsigned char __a, + vector signed char __b) { + return (vector unsigned char)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_vslo(vector unsigned char __a, + vector unsigned char __b) { + return (vector unsigned char)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_vslo(vector short __a, + vector signed char __b) { + return (vector short)__builtin_altivec_vslo((vector int)__a, (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_vslo(vector short __a, + vector unsigned char __b) { + return (vector short)__builtin_altivec_vslo((vector int)__a, (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_vslo(vector unsigned short __a, + vector signed char __b) { + return (vector unsigned short)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_vslo(vector unsigned short __a, + vector unsigned char __b) { + return (vector unsigned short)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_vslo(vector pixel __a, + vector signed char __b) { + return (vector pixel)__builtin_altivec_vslo((vector int)__a, (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_vslo(vector pixel __a, + vector unsigned char __b) { + return (vector pixel)__builtin_altivec_vslo((vector int)__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_vslo(vector int __a, + vector signed char __b) { + return (vector int)__builtin_altivec_vslo(__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_vslo(vector int __a, + vector unsigned char __b) { + return (vector int)__builtin_altivec_vslo(__a, (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_vslo(vector unsigned int __a, + vector signed char __b) { + return (vector unsigned int)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_vslo(vector unsigned int __a, + vector unsigned char __b) { + return (vector unsigned int)__builtin_altivec_vslo((vector int)__a, + (vector int)__b); +} + +static vector float __ATTRS_o_ai vec_vslo(vector float __a, + vector signed char __b) { + return (vector float)__builtin_altivec_vslo((vector int)__a, (vector int)__b); +} + +static vector float __ATTRS_o_ai vec_vslo(vector float __a, + vector unsigned char __b) { + return (vector float)__builtin_altivec_vslo((vector int)__a, (vector int)__b); +} + +/* vec_splat */ + +static vector signed char __ATTRS_o_ai vec_splat(vector signed char __a, + unsigned const int __b) { + return vec_perm(__a, __a, (vector unsigned char)(__b & 0x0F)); +} + +static vector unsigned char __ATTRS_o_ai vec_splat(vector unsigned char __a, + unsigned const int __b) { + return vec_perm(__a, __a, (vector unsigned char)(__b & 0x0F)); +} + +static vector bool char __ATTRS_o_ai vec_splat(vector bool char __a, + unsigned const int __b) { + return vec_perm(__a, __a, (vector unsigned char)(__b & 0x0F)); +} + +static vector signed short __ATTRS_o_ai vec_splat(vector signed short __a, + unsigned const int __b) { + unsigned char b0 = (__b & 0x07) * 2; + unsigned char b1 = b0 + 1; + return vec_perm(__a, __a, + (vector unsigned char)(b0, b1, b0, b1, b0, b1, b0, b1, + b0, b1, b0, b1, b0, b1, b0, b1)); +} + +static vector unsigned short __ATTRS_o_ai vec_splat(vector unsigned short __a, + unsigned const int __b) { + unsigned char b0 = (__b & 0x07) * 2; + unsigned char b1 = b0 + 1; + return vec_perm(__a, __a, + (vector unsigned char)(b0, b1, b0, b1, b0, b1, b0, b1, + b0, b1, b0, b1, b0, b1, b0, b1)); +} + +static vector bool short __ATTRS_o_ai vec_splat(vector bool short __a, + unsigned const int __b) { + unsigned char b0 = (__b & 0x07) * 2; + unsigned char b1 = b0 + 1; + return vec_perm(__a, __a, + (vector unsigned char)(b0, b1, b0, b1, b0, b1, b0, b1, + b0, b1, b0, b1, b0, b1, b0, b1)); +} + +static vector pixel __ATTRS_o_ai vec_splat(vector pixel __a, + unsigned const int __b) { + unsigned char b0 = (__b & 0x07) * 2; + unsigned char b1 = b0 + 1; + return vec_perm(__a, __a, + (vector unsigned char)(b0, b1, b0, b1, b0, b1, b0, b1, + b0, b1, b0, b1, b0, b1, b0, b1)); +} + +static vector signed int __ATTRS_o_ai vec_splat(vector signed int __a, + unsigned const int __b) { + unsigned char b0 = (__b & 0x03) * 4; + unsigned char b1 = b0 + 1, b2 = b0 + 2, b3 = b0 + 3; + return vec_perm(__a, __a, + (vector unsigned char)(b0, b1, b2, b3, b0, b1, b2, b3, b0, + b1, b2, b3, b0, b1, b2, b3)); +} + +static vector unsigned int __ATTRS_o_ai vec_splat(vector unsigned int __a, + unsigned const int __b) { + unsigned char b0 = (__b & 0x03) * 4; + unsigned char b1 = b0 + 1, b2 = b0 + 2, b3 = b0 + 3; + return vec_perm(__a, __a, + (vector unsigned char)(b0, b1, b2, b3, b0, b1, b2, b3, b0, + b1, b2, b3, b0, b1, b2, b3)); +} + +static vector bool int __ATTRS_o_ai vec_splat(vector bool int __a, + unsigned const int __b) { + unsigned char b0 = (__b & 0x03) * 4; + unsigned char b1 = b0 + 1, b2 = b0 + 2, b3 = b0 + 3; + return vec_perm(__a, __a, + (vector unsigned char)(b0, b1, b2, b3, b0, b1, b2, b3, b0, + b1, b2, b3, b0, b1, b2, b3)); +} + +static vector float __ATTRS_o_ai vec_splat(vector float __a, + unsigned const int __b) { + unsigned char b0 = (__b & 0x03) * 4; + unsigned char b1 = b0 + 1, b2 = b0 + 2, b3 = b0 + 3; + return vec_perm(__a, __a, + (vector unsigned char)(b0, b1, b2, b3, b0, b1, b2, b3, b0, + b1, b2, b3, b0, b1, b2, b3)); +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai vec_splat(vector double __a, + unsigned const int __b) { + unsigned char b0 = (__b & 0x01) * 8; + unsigned char b1 = b0 + 1, b2 = b0 + 2, b3 = b0 + 3, b4 = b0 + 4, + b5 = b0 + 5, b6 = b0 + 6, b7 = b0 + 7; + return vec_perm(__a, __a, + (vector unsigned char)(b0, b1, b2, b3, b4, b5, b6, b7, + b0, b1, b2, b3, b4, b5, b6, b7)); +} +static vector bool long long __ATTRS_o_ai vec_splat(vector bool long long __a, + unsigned const int __b) { + unsigned char b0 = (__b & 0x01) * 8; + unsigned char b1 = b0 + 1, b2 = b0 + 2, b3 = b0 + 3, b4 = b0 + 4, + b5 = b0 + 5, b6 = b0 + 6, b7 = b0 + 7; + return vec_perm(__a, __a, + (vector unsigned char)(b0, b1, b2, b3, b4, b5, b6, b7, + b0, b1, b2, b3, b4, b5, b6, b7)); +} +static vector signed long long __ATTRS_o_ai +vec_splat(vector signed long long __a, unsigned const int __b) { + unsigned char b0 = (__b & 0x01) * 8; + unsigned char b1 = b0 + 1, b2 = b0 + 2, b3 = b0 + 3, b4 = b0 + 4, + b5 = b0 + 5, b6 = b0 + 6, b7 = b0 + 7; + return vec_perm(__a, __a, + (vector unsigned char)(b0, b1, b2, b3, b4, b5, b6, b7, + b0, b1, b2, b3, b4, b5, b6, b7)); +} +static vector unsigned long long __ATTRS_o_ai +vec_splat(vector unsigned long long __a, unsigned const int __b) { + unsigned char b0 = (__b & 0x01) * 8; + unsigned char b1 = b0 + 1, b2 = b0 + 2, b3 = b0 + 3, b4 = b0 + 4, + b5 = b0 + 5, b6 = b0 + 6, b7 = b0 + 7; + return vec_perm(__a, __a, + (vector unsigned char)(b0, b1, b2, b3, b4, b5, b6, b7, + b0, b1, b2, b3, b4, b5, b6, b7)); +} +#endif + +/* vec_vspltb */ + +#define __builtin_altivec_vspltb vec_vspltb + +static vector signed char __ATTRS_o_ai vec_vspltb(vector signed char __a, + unsigned char __b) { + return vec_perm(__a, __a, (vector unsigned char)(__b)); +} + +static vector unsigned char __ATTRS_o_ai vec_vspltb(vector unsigned char __a, + unsigned char __b) { + return vec_perm(__a, __a, (vector unsigned char)(__b)); +} + +static vector bool char __ATTRS_o_ai vec_vspltb(vector bool char __a, + unsigned char __b) { + return vec_perm(__a, __a, (vector unsigned char)(__b)); +} + +/* vec_vsplth */ + +#define __builtin_altivec_vsplth vec_vsplth + +static vector short __ATTRS_o_ai vec_vsplth(vector short __a, + unsigned char __b) { + __b *= 2; + unsigned char b1 = __b + 1; + return vec_perm(__a, __a, + (vector unsigned char)(__b, b1, __b, b1, __b, b1, __b, b1, + __b, b1, __b, b1, __b, b1, __b, b1)); +} + +static vector unsigned short __ATTRS_o_ai vec_vsplth(vector unsigned short __a, + unsigned char __b) { + __b *= 2; + unsigned char b1 = __b + 1; + return vec_perm(__a, __a, + (vector unsigned char)(__b, b1, __b, b1, __b, b1, __b, b1, + __b, b1, __b, b1, __b, b1, __b, b1)); +} + +static vector bool short __ATTRS_o_ai vec_vsplth(vector bool short __a, + unsigned char __b) { + __b *= 2; + unsigned char b1 = __b + 1; + return vec_perm(__a, __a, + (vector unsigned char)(__b, b1, __b, b1, __b, b1, __b, b1, + __b, b1, __b, b1, __b, b1, __b, b1)); +} + +static vector pixel __ATTRS_o_ai vec_vsplth(vector pixel __a, + unsigned char __b) { + __b *= 2; + unsigned char b1 = __b + 1; + return vec_perm(__a, __a, + (vector unsigned char)(__b, b1, __b, b1, __b, b1, __b, b1, + __b, b1, __b, b1, __b, b1, __b, b1)); +} + +/* vec_vspltw */ + +#define __builtin_altivec_vspltw vec_vspltw + +static vector int __ATTRS_o_ai vec_vspltw(vector int __a, unsigned char __b) { + __b *= 4; + unsigned char b1 = __b + 1, b2 = __b + 2, b3 = __b + 3; + return vec_perm(__a, __a, + (vector unsigned char)(__b, b1, b2, b3, __b, b1, b2, b3, __b, + b1, b2, b3, __b, b1, b2, b3)); +} + +static vector unsigned int __ATTRS_o_ai vec_vspltw(vector unsigned int __a, + unsigned char __b) { + __b *= 4; + unsigned char b1 = __b + 1, b2 = __b + 2, b3 = __b + 3; + return vec_perm(__a, __a, + (vector unsigned char)(__b, b1, b2, b3, __b, b1, b2, b3, __b, + b1, b2, b3, __b, b1, b2, b3)); +} + +static vector bool int __ATTRS_o_ai vec_vspltw(vector bool int __a, + unsigned char __b) { + __b *= 4; + unsigned char b1 = __b + 1, b2 = __b + 2, b3 = __b + 3; + return vec_perm(__a, __a, + (vector unsigned char)(__b, b1, b2, b3, __b, b1, b2, b3, __b, + b1, b2, b3, __b, b1, b2, b3)); +} + +static vector float __ATTRS_o_ai vec_vspltw(vector float __a, + unsigned char __b) { + __b *= 4; + unsigned char b1 = __b + 1, b2 = __b + 2, b3 = __b + 3; + return vec_perm(__a, __a, + (vector unsigned char)(__b, b1, b2, b3, __b, b1, b2, b3, __b, + b1, b2, b3, __b, b1, b2, b3)); +} + +/* vec_splat_s8 */ + +#define __builtin_altivec_vspltisb vec_splat_s8 + +// FIXME: parameter should be treated as 5-bit signed literal +static vector signed char __ATTRS_o_ai vec_splat_s8(signed char __a) { + return (vector signed char)(__a); +} + +/* vec_vspltisb */ + +// FIXME: parameter should be treated as 5-bit signed literal +static vector signed char __ATTRS_o_ai vec_vspltisb(signed char __a) { + return (vector signed char)(__a); +} + +/* vec_splat_s16 */ + +#define __builtin_altivec_vspltish vec_splat_s16 + +// FIXME: parameter should be treated as 5-bit signed literal +static vector short __ATTRS_o_ai vec_splat_s16(signed char __a) { + return (vector short)(__a); +} + +/* vec_vspltish */ + +// FIXME: parameter should be treated as 5-bit signed literal +static vector short __ATTRS_o_ai vec_vspltish(signed char __a) { + return (vector short)(__a); +} + +/* vec_splat_s32 */ + +#define __builtin_altivec_vspltisw vec_splat_s32 + +// FIXME: parameter should be treated as 5-bit signed literal +static vector int __ATTRS_o_ai vec_splat_s32(signed char __a) { + return (vector int)(__a); +} + +/* vec_vspltisw */ + +// FIXME: parameter should be treated as 5-bit signed literal +static vector int __ATTRS_o_ai vec_vspltisw(signed char __a) { + return (vector int)(__a); +} + +/* vec_splat_u8 */ + +// FIXME: parameter should be treated as 5-bit signed literal +static vector unsigned char __ATTRS_o_ai vec_splat_u8(unsigned char __a) { + return (vector unsigned char)(__a); +} + +/* vec_splat_u16 */ + +// FIXME: parameter should be treated as 5-bit signed literal +static vector unsigned short __ATTRS_o_ai vec_splat_u16(signed char __a) { + return (vector unsigned short)(__a); +} + +/* vec_splat_u32 */ + +// FIXME: parameter should be treated as 5-bit signed literal +static vector unsigned int __ATTRS_o_ai vec_splat_u32(signed char __a) { + return (vector unsigned int)(__a); +} + +/* vec_sr */ + +static vector signed char __ATTRS_o_ai vec_sr(vector signed char __a, + vector unsigned char __b) { + vector unsigned char __res = (vector unsigned char)__a >> __b; + return (vector signed char)__res; +} + +static vector unsigned char __ATTRS_o_ai vec_sr(vector unsigned char __a, + vector unsigned char __b) { + return __a >> __b; +} + +static vector signed short __ATTRS_o_ai vec_sr(vector signed short __a, + vector unsigned short __b) { + vector unsigned short __res = (vector unsigned short)__a >> __b; + return (vector signed short)__res; +} + +static vector unsigned short __ATTRS_o_ai vec_sr(vector unsigned short __a, + vector unsigned short __b) { + return __a >> __b; +} + +static vector signed int __ATTRS_o_ai vec_sr(vector signed int __a, + vector unsigned int __b) { + vector unsigned int __res = (vector unsigned int)__a >> __b; + return (vector signed int)__res; +} + +static vector unsigned int __ATTRS_o_ai vec_sr(vector unsigned int __a, + vector unsigned int __b) { + return __a >> __b; +} + +#ifdef __POWER8_VECTOR__ +static vector signed long long __ATTRS_o_ai +vec_sr(vector signed long long __a, vector unsigned long long __b) { + vector unsigned long long __res = (vector unsigned long long)__a >> __b; + return (vector signed long long)__res; +} + +static vector unsigned long long __ATTRS_o_ai +vec_sr(vector unsigned long long __a, vector unsigned long long __b) { + return __a >> __b; +} +#endif + +/* vec_vsrb */ + +#define __builtin_altivec_vsrb vec_vsrb + +static vector signed char __ATTRS_o_ai vec_vsrb(vector signed char __a, + vector unsigned char __b) { + return __a >> (vector signed char)__b; +} + +static vector unsigned char __ATTRS_o_ai vec_vsrb(vector unsigned char __a, + vector unsigned char __b) { + return __a >> __b; +} + +/* vec_vsrh */ + +#define __builtin_altivec_vsrh vec_vsrh + +static vector short __ATTRS_o_ai vec_vsrh(vector short __a, + vector unsigned short __b) { + return __a >> (vector short)__b; +} + +static vector unsigned short __ATTRS_o_ai vec_vsrh(vector unsigned short __a, + vector unsigned short __b) { + return __a >> __b; +} + +/* vec_vsrw */ + +#define __builtin_altivec_vsrw vec_vsrw + +static vector int __ATTRS_o_ai vec_vsrw(vector int __a, + vector unsigned int __b) { + return __a >> (vector int)__b; +} + +static vector unsigned int __ATTRS_o_ai vec_vsrw(vector unsigned int __a, + vector unsigned int __b) { + return __a >> __b; +} + +/* vec_sra */ + +static vector signed char __ATTRS_o_ai vec_sra(vector signed char __a, + vector unsigned char __b) { + return (vector signed char)__builtin_altivec_vsrab((vector char)__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_sra(vector unsigned char __a, + vector unsigned char __b) { + return (vector unsigned char)__builtin_altivec_vsrab((vector char)__a, __b); +} + +static vector short __ATTRS_o_ai vec_sra(vector short __a, + vector unsigned short __b) { + return __builtin_altivec_vsrah(__a, (vector unsigned short)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_sra(vector unsigned short __a, + vector unsigned short __b) { + return (vector unsigned short)__builtin_altivec_vsrah((vector short)__a, __b); +} + +static vector int __ATTRS_o_ai vec_sra(vector int __a, + vector unsigned int __b) { + return __builtin_altivec_vsraw(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_sra(vector unsigned int __a, + vector unsigned int __b) { + return (vector unsigned int)__builtin_altivec_vsraw((vector int)__a, __b); +} + +#ifdef __POWER8_VECTOR__ +static vector signed long long __ATTRS_o_ai +vec_sra(vector signed long long __a, vector unsigned long long __b) { + return __a >> __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_sra(vector unsigned long long __a, vector unsigned long long __b) { + return (vector unsigned long long)((vector signed long long)__a >> __b); +} +#endif + +/* vec_vsrab */ + +static vector signed char __ATTRS_o_ai vec_vsrab(vector signed char __a, + vector unsigned char __b) { + return (vector signed char)__builtin_altivec_vsrab((vector char)__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_vsrab(vector unsigned char __a, + vector unsigned char __b) { + return (vector unsigned char)__builtin_altivec_vsrab((vector char)__a, __b); +} + +/* vec_vsrah */ + +static vector short __ATTRS_o_ai vec_vsrah(vector short __a, + vector unsigned short __b) { + return __builtin_altivec_vsrah(__a, (vector unsigned short)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_vsrah(vector unsigned short __a, + vector unsigned short __b) { + return (vector unsigned short)__builtin_altivec_vsrah((vector short)__a, __b); +} + +/* vec_vsraw */ + +static vector int __ATTRS_o_ai vec_vsraw(vector int __a, + vector unsigned int __b) { + return __builtin_altivec_vsraw(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_vsraw(vector unsigned int __a, + vector unsigned int __b) { + return (vector unsigned int)__builtin_altivec_vsraw((vector int)__a, __b); +} + +/* vec_srl */ + +static vector signed char __ATTRS_o_ai vec_srl(vector signed char __a, + vector unsigned char __b) { + return (vector signed char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector signed char __ATTRS_o_ai vec_srl(vector signed char __a, + vector unsigned short __b) { + return (vector signed char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector signed char __ATTRS_o_ai vec_srl(vector signed char __a, + vector unsigned int __b) { + return (vector signed char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_srl(vector unsigned char __a, + vector unsigned char __b) { + return (vector unsigned char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_srl(vector unsigned char __a, + vector unsigned short __b) { + return (vector unsigned char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_srl(vector unsigned char __a, + vector unsigned int __b) { + return (vector unsigned char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool char __ATTRS_o_ai vec_srl(vector bool char __a, + vector unsigned char __b) { + return (vector bool char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool char __ATTRS_o_ai vec_srl(vector bool char __a, + vector unsigned short __b) { + return (vector bool char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool char __ATTRS_o_ai vec_srl(vector bool char __a, + vector unsigned int __b) { + return (vector bool char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_srl(vector short __a, + vector unsigned char __b) { + return (vector short)__builtin_altivec_vsr((vector int)__a, (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_srl(vector short __a, + vector unsigned short __b) { + return (vector short)__builtin_altivec_vsr((vector int)__a, (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_srl(vector short __a, + vector unsigned int __b) { + return (vector short)__builtin_altivec_vsr((vector int)__a, (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_srl(vector unsigned short __a, + vector unsigned char __b) { + return (vector unsigned short)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_srl(vector unsigned short __a, + vector unsigned short __b) { + return (vector unsigned short)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_srl(vector unsigned short __a, + vector unsigned int __b) { + return (vector unsigned short)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool short __ATTRS_o_ai vec_srl(vector bool short __a, + vector unsigned char __b) { + return (vector bool short)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool short __ATTRS_o_ai vec_srl(vector bool short __a, + vector unsigned short __b) { + return (vector bool short)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool short __ATTRS_o_ai vec_srl(vector bool short __a, + vector unsigned int __b) { + return (vector bool short)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_srl(vector pixel __a, + vector unsigned char __b) { + return (vector pixel)__builtin_altivec_vsr((vector int)__a, (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_srl(vector pixel __a, + vector unsigned short __b) { + return (vector pixel)__builtin_altivec_vsr((vector int)__a, (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_srl(vector pixel __a, + vector unsigned int __b) { + return (vector pixel)__builtin_altivec_vsr((vector int)__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_srl(vector int __a, + vector unsigned char __b) { + return (vector int)__builtin_altivec_vsr(__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_srl(vector int __a, + vector unsigned short __b) { + return (vector int)__builtin_altivec_vsr(__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_srl(vector int __a, + vector unsigned int __b) { + return (vector int)__builtin_altivec_vsr(__a, (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_srl(vector unsigned int __a, + vector unsigned char __b) { + return (vector unsigned int)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_srl(vector unsigned int __a, + vector unsigned short __b) { + return (vector unsigned int)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_srl(vector unsigned int __a, + vector unsigned int __b) { + return (vector unsigned int)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool int __ATTRS_o_ai vec_srl(vector bool int __a, + vector unsigned char __b) { + return (vector bool int)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool int __ATTRS_o_ai vec_srl(vector bool int __a, + vector unsigned short __b) { + return (vector bool int)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool int __ATTRS_o_ai vec_srl(vector bool int __a, + vector unsigned int __b) { + return (vector bool int)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +/* vec_vsr */ + +static vector signed char __ATTRS_o_ai vec_vsr(vector signed char __a, + vector unsigned char __b) { + return (vector signed char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector signed char __ATTRS_o_ai vec_vsr(vector signed char __a, + vector unsigned short __b) { + return (vector signed char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector signed char __ATTRS_o_ai vec_vsr(vector signed char __a, + vector unsigned int __b) { + return (vector signed char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_vsr(vector unsigned char __a, + vector unsigned char __b) { + return (vector unsigned char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_vsr(vector unsigned char __a, + vector unsigned short __b) { + return (vector unsigned char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_vsr(vector unsigned char __a, + vector unsigned int __b) { + return (vector unsigned char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool char __ATTRS_o_ai vec_vsr(vector bool char __a, + vector unsigned char __b) { + return (vector bool char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool char __ATTRS_o_ai vec_vsr(vector bool char __a, + vector unsigned short __b) { + return (vector bool char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool char __ATTRS_o_ai vec_vsr(vector bool char __a, + vector unsigned int __b) { + return (vector bool char)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_vsr(vector short __a, + vector unsigned char __b) { + return (vector short)__builtin_altivec_vsr((vector int)__a, (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_vsr(vector short __a, + vector unsigned short __b) { + return (vector short)__builtin_altivec_vsr((vector int)__a, (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_vsr(vector short __a, + vector unsigned int __b) { + return (vector short)__builtin_altivec_vsr((vector int)__a, (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_vsr(vector unsigned short __a, + vector unsigned char __b) { + return (vector unsigned short)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_vsr(vector unsigned short __a, + vector unsigned short __b) { + return (vector unsigned short)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_vsr(vector unsigned short __a, + vector unsigned int __b) { + return (vector unsigned short)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool short __ATTRS_o_ai vec_vsr(vector bool short __a, + vector unsigned char __b) { + return (vector bool short)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool short __ATTRS_o_ai vec_vsr(vector bool short __a, + vector unsigned short __b) { + return (vector bool short)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool short __ATTRS_o_ai vec_vsr(vector bool short __a, + vector unsigned int __b) { + return (vector bool short)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_vsr(vector pixel __a, + vector unsigned char __b) { + return (vector pixel)__builtin_altivec_vsr((vector int)__a, (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_vsr(vector pixel __a, + vector unsigned short __b) { + return (vector pixel)__builtin_altivec_vsr((vector int)__a, (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_vsr(vector pixel __a, + vector unsigned int __b) { + return (vector pixel)__builtin_altivec_vsr((vector int)__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_vsr(vector int __a, + vector unsigned char __b) { + return (vector int)__builtin_altivec_vsr(__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_vsr(vector int __a, + vector unsigned short __b) { + return (vector int)__builtin_altivec_vsr(__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_vsr(vector int __a, + vector unsigned int __b) { + return (vector int)__builtin_altivec_vsr(__a, (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_vsr(vector unsigned int __a, + vector unsigned char __b) { + return (vector unsigned int)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_vsr(vector unsigned int __a, + vector unsigned short __b) { + return (vector unsigned int)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_vsr(vector unsigned int __a, + vector unsigned int __b) { + return (vector unsigned int)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool int __ATTRS_o_ai vec_vsr(vector bool int __a, + vector unsigned char __b) { + return (vector bool int)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool int __ATTRS_o_ai vec_vsr(vector bool int __a, + vector unsigned short __b) { + return (vector bool int)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +static vector bool int __ATTRS_o_ai vec_vsr(vector bool int __a, + vector unsigned int __b) { + return (vector bool int)__builtin_altivec_vsr((vector int)__a, + (vector int)__b); +} + +/* vec_sro */ + +static vector signed char __ATTRS_o_ai vec_sro(vector signed char __a, + vector signed char __b) { + return (vector signed char)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector signed char __ATTRS_o_ai vec_sro(vector signed char __a, + vector unsigned char __b) { + return (vector signed char)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_sro(vector unsigned char __a, + vector signed char __b) { + return (vector unsigned char)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_sro(vector unsigned char __a, + vector unsigned char __b) { + return (vector unsigned char)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_sro(vector short __a, + vector signed char __b) { + return (vector short)__builtin_altivec_vsro((vector int)__a, (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_sro(vector short __a, + vector unsigned char __b) { + return (vector short)__builtin_altivec_vsro((vector int)__a, (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_sro(vector unsigned short __a, + vector signed char __b) { + return (vector unsigned short)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_sro(vector unsigned short __a, + vector unsigned char __b) { + return (vector unsigned short)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_sro(vector pixel __a, + vector signed char __b) { + return (vector pixel)__builtin_altivec_vsro((vector int)__a, (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_sro(vector pixel __a, + vector unsigned char __b) { + return (vector pixel)__builtin_altivec_vsro((vector int)__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_sro(vector int __a, vector signed char __b) { + return (vector int)__builtin_altivec_vsro(__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_sro(vector int __a, + vector unsigned char __b) { + return (vector int)__builtin_altivec_vsro(__a, (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_sro(vector unsigned int __a, + vector signed char __b) { + return (vector unsigned int)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_sro(vector unsigned int __a, + vector unsigned char __b) { + return (vector unsigned int)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector float __ATTRS_o_ai vec_sro(vector float __a, + vector signed char __b) { + return (vector float)__builtin_altivec_vsro((vector int)__a, (vector int)__b); +} + +static vector float __ATTRS_o_ai vec_sro(vector float __a, + vector unsigned char __b) { + return (vector float)__builtin_altivec_vsro((vector int)__a, (vector int)__b); +} + +/* vec_vsro */ + +static vector signed char __ATTRS_o_ai vec_vsro(vector signed char __a, + vector signed char __b) { + return (vector signed char)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector signed char __ATTRS_o_ai vec_vsro(vector signed char __a, + vector unsigned char __b) { + return (vector signed char)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_vsro(vector unsigned char __a, + vector signed char __b) { + return (vector unsigned char)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_vsro(vector unsigned char __a, + vector unsigned char __b) { + return (vector unsigned char)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_vsro(vector short __a, + vector signed char __b) { + return (vector short)__builtin_altivec_vsro((vector int)__a, (vector int)__b); +} + +static vector short __ATTRS_o_ai vec_vsro(vector short __a, + vector unsigned char __b) { + return (vector short)__builtin_altivec_vsro((vector int)__a, (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_vsro(vector unsigned short __a, + vector signed char __b) { + return (vector unsigned short)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_vsro(vector unsigned short __a, + vector unsigned char __b) { + return (vector unsigned short)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_vsro(vector pixel __a, + vector signed char __b) { + return (vector pixel)__builtin_altivec_vsro((vector int)__a, (vector int)__b); +} + +static vector pixel __ATTRS_o_ai vec_vsro(vector pixel __a, + vector unsigned char __b) { + return (vector pixel)__builtin_altivec_vsro((vector int)__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_vsro(vector int __a, + vector signed char __b) { + return (vector int)__builtin_altivec_vsro(__a, (vector int)__b); +} + +static vector int __ATTRS_o_ai vec_vsro(vector int __a, + vector unsigned char __b) { + return (vector int)__builtin_altivec_vsro(__a, (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_vsro(vector unsigned int __a, + vector signed char __b) { + return (vector unsigned int)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_vsro(vector unsigned int __a, + vector unsigned char __b) { + return (vector unsigned int)__builtin_altivec_vsro((vector int)__a, + (vector int)__b); +} + +static vector float __ATTRS_o_ai vec_vsro(vector float __a, + vector signed char __b) { + return (vector float)__builtin_altivec_vsro((vector int)__a, (vector int)__b); +} + +static vector float __ATTRS_o_ai vec_vsro(vector float __a, + vector unsigned char __b) { + return (vector float)__builtin_altivec_vsro((vector int)__a, (vector int)__b); +} + +/* vec_st */ + +static void __ATTRS_o_ai vec_st(vector signed char __a, int __b, + vector signed char *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector signed char __a, int __b, + signed char *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector unsigned char __a, int __b, + vector unsigned char *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector unsigned char __a, int __b, + unsigned char *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector bool char __a, int __b, + signed char *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector bool char __a, int __b, + unsigned char *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector bool char __a, int __b, + vector bool char *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector short __a, int __b, vector short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector short __a, int __b, short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector unsigned short __a, int __b, + vector unsigned short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector unsigned short __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector bool short __a, int __b, short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector bool short __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector bool short __a, int __b, + vector bool short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector pixel __a, int __b, short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector pixel __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector pixel __a, int __b, vector pixel *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector int __a, int __b, vector int *__c) { + __builtin_altivec_stvx(__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector int __a, int __b, int *__c) { + __builtin_altivec_stvx(__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector unsigned int __a, int __b, + vector unsigned int *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector unsigned int __a, int __b, + unsigned int *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector bool int __a, int __b, int *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector bool int __a, int __b, + unsigned int *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector bool int __a, int __b, + vector bool int *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector float __a, int __b, vector float *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_st(vector float __a, int __b, float *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +/* vec_stvx */ + +static void __ATTRS_o_ai vec_stvx(vector signed char __a, int __b, + vector signed char *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector signed char __a, int __b, + signed char *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector unsigned char __a, int __b, + vector unsigned char *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector unsigned char __a, int __b, + unsigned char *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector bool char __a, int __b, + signed char *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector bool char __a, int __b, + unsigned char *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector bool char __a, int __b, + vector bool char *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector short __a, int __b, + vector short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector short __a, int __b, short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector unsigned short __a, int __b, + vector unsigned short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector unsigned short __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector bool short __a, int __b, short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector bool short __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector bool short __a, int __b, + vector bool short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector pixel __a, int __b, short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector pixel __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector pixel __a, int __b, + vector pixel *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector int __a, int __b, vector int *__c) { + __builtin_altivec_stvx(__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector int __a, int __b, int *__c) { + __builtin_altivec_stvx(__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector unsigned int __a, int __b, + vector unsigned int *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector unsigned int __a, int __b, + unsigned int *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector bool int __a, int __b, int *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector bool int __a, int __b, + unsigned int *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector bool int __a, int __b, + vector bool int *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector float __a, int __b, + vector float *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvx(vector float __a, int __b, float *__c) { + __builtin_altivec_stvx((vector int)__a, __b, __c); +} + +/* vec_ste */ + +static void __ATTRS_o_ai vec_ste(vector signed char __a, int __b, + signed char *__c) { + __builtin_altivec_stvebx((vector char)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_ste(vector unsigned char __a, int __b, + unsigned char *__c) { + __builtin_altivec_stvebx((vector char)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_ste(vector bool char __a, int __b, + signed char *__c) { + __builtin_altivec_stvebx((vector char)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_ste(vector bool char __a, int __b, + unsigned char *__c) { + __builtin_altivec_stvebx((vector char)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_ste(vector short __a, int __b, short *__c) { + __builtin_altivec_stvehx(__a, __b, __c); +} + +static void __ATTRS_o_ai vec_ste(vector unsigned short __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvehx((vector short)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_ste(vector bool short __a, int __b, short *__c) { + __builtin_altivec_stvehx((vector short)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_ste(vector bool short __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvehx((vector short)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_ste(vector pixel __a, int __b, short *__c) { + __builtin_altivec_stvehx((vector short)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_ste(vector pixel __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvehx((vector short)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_ste(vector int __a, int __b, int *__c) { + __builtin_altivec_stvewx(__a, __b, __c); +} + +static void __ATTRS_o_ai vec_ste(vector unsigned int __a, int __b, + unsigned int *__c) { + __builtin_altivec_stvewx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_ste(vector bool int __a, int __b, int *__c) { + __builtin_altivec_stvewx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_ste(vector bool int __a, int __b, + unsigned int *__c) { + __builtin_altivec_stvewx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_ste(vector float __a, int __b, float *__c) { + __builtin_altivec_stvewx((vector int)__a, __b, __c); +} + +/* vec_stvebx */ + +static void __ATTRS_o_ai vec_stvebx(vector signed char __a, int __b, + signed char *__c) { + __builtin_altivec_stvebx((vector char)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvebx(vector unsigned char __a, int __b, + unsigned char *__c) { + __builtin_altivec_stvebx((vector char)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvebx(vector bool char __a, int __b, + signed char *__c) { + __builtin_altivec_stvebx((vector char)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvebx(vector bool char __a, int __b, + unsigned char *__c) { + __builtin_altivec_stvebx((vector char)__a, __b, __c); +} + +/* vec_stvehx */ + +static void __ATTRS_o_ai vec_stvehx(vector short __a, int __b, short *__c) { + __builtin_altivec_stvehx(__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvehx(vector unsigned short __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvehx((vector short)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvehx(vector bool short __a, int __b, + short *__c) { + __builtin_altivec_stvehx((vector short)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvehx(vector bool short __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvehx((vector short)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvehx(vector pixel __a, int __b, short *__c) { + __builtin_altivec_stvehx((vector short)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvehx(vector pixel __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvehx((vector short)__a, __b, __c); +} + +/* vec_stvewx */ + +static void __ATTRS_o_ai vec_stvewx(vector int __a, int __b, int *__c) { + __builtin_altivec_stvewx(__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvewx(vector unsigned int __a, int __b, + unsigned int *__c) { + __builtin_altivec_stvewx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvewx(vector bool int __a, int __b, int *__c) { + __builtin_altivec_stvewx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvewx(vector bool int __a, int __b, + unsigned int *__c) { + __builtin_altivec_stvewx((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvewx(vector float __a, int __b, float *__c) { + __builtin_altivec_stvewx((vector int)__a, __b, __c); +} + +/* vec_stl */ + +static void __ATTRS_o_ai vec_stl(vector signed char __a, int __b, + vector signed char *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector signed char __a, int __b, + signed char *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector unsigned char __a, int __b, + vector unsigned char *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector unsigned char __a, int __b, + unsigned char *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector bool char __a, int __b, + signed char *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector bool char __a, int __b, + unsigned char *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector bool char __a, int __b, + vector bool char *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector short __a, int __b, vector short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector short __a, int __b, short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector unsigned short __a, int __b, + vector unsigned short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector unsigned short __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector bool short __a, int __b, short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector bool short __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector bool short __a, int __b, + vector bool short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector pixel __a, int __b, short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector pixel __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector pixel __a, int __b, vector pixel *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector int __a, int __b, vector int *__c) { + __builtin_altivec_stvxl(__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector int __a, int __b, int *__c) { + __builtin_altivec_stvxl(__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector unsigned int __a, int __b, + vector unsigned int *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector unsigned int __a, int __b, + unsigned int *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector bool int __a, int __b, int *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector bool int __a, int __b, + unsigned int *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector bool int __a, int __b, + vector bool int *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector float __a, int __b, vector float *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stl(vector float __a, int __b, float *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +/* vec_stvxl */ + +static void __ATTRS_o_ai vec_stvxl(vector signed char __a, int __b, + vector signed char *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector signed char __a, int __b, + signed char *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector unsigned char __a, int __b, + vector unsigned char *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector unsigned char __a, int __b, + unsigned char *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector bool char __a, int __b, + signed char *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector bool char __a, int __b, + unsigned char *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector bool char __a, int __b, + vector bool char *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector short __a, int __b, + vector short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector short __a, int __b, short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector unsigned short __a, int __b, + vector unsigned short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector unsigned short __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector bool short __a, int __b, short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector bool short __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector bool short __a, int __b, + vector bool short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector pixel __a, int __b, short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector pixel __a, int __b, + unsigned short *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector pixel __a, int __b, + vector pixel *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector int __a, int __b, vector int *__c) { + __builtin_altivec_stvxl(__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector int __a, int __b, int *__c) { + __builtin_altivec_stvxl(__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector unsigned int __a, int __b, + vector unsigned int *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector unsigned int __a, int __b, + unsigned int *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector bool int __a, int __b, int *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector bool int __a, int __b, + unsigned int *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector bool int __a, int __b, + vector bool int *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector float __a, int __b, + vector float *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_stvxl(vector float __a, int __b, float *__c) { + __builtin_altivec_stvxl((vector int)__a, __b, __c); +} + +/* vec_sub */ + +static vector signed char __ATTRS_o_ai vec_sub(vector signed char __a, + vector signed char __b) { + return __a - __b; +} + +static vector signed char __ATTRS_o_ai vec_sub(vector bool char __a, + vector signed char __b) { + return (vector signed char)__a - __b; +} + +static vector signed char __ATTRS_o_ai vec_sub(vector signed char __a, + vector bool char __b) { + return __a - (vector signed char)__b; +} + +static vector unsigned char __ATTRS_o_ai vec_sub(vector unsigned char __a, + vector unsigned char __b) { + return __a - __b; +} + +static vector unsigned char __ATTRS_o_ai vec_sub(vector bool char __a, + vector unsigned char __b) { + return (vector unsigned char)__a - __b; +} + +static vector unsigned char __ATTRS_o_ai vec_sub(vector unsigned char __a, + vector bool char __b) { + return __a - (vector unsigned char)__b; +} + +static vector short __ATTRS_o_ai vec_sub(vector short __a, vector short __b) { + return __a - __b; +} + +static vector short __ATTRS_o_ai vec_sub(vector bool short __a, + vector short __b) { + return (vector short)__a - __b; +} + +static vector short __ATTRS_o_ai vec_sub(vector short __a, + vector bool short __b) { + return __a - (vector short)__b; +} + +static vector unsigned short __ATTRS_o_ai vec_sub(vector unsigned short __a, + vector unsigned short __b) { + return __a - __b; +} + +static vector unsigned short __ATTRS_o_ai vec_sub(vector bool short __a, + vector unsigned short __b) { + return (vector unsigned short)__a - __b; +} + +static vector unsigned short __ATTRS_o_ai vec_sub(vector unsigned short __a, + vector bool short __b) { + return __a - (vector unsigned short)__b; +} + +static vector int __ATTRS_o_ai vec_sub(vector int __a, vector int __b) { + return __a - __b; +} + +static vector int __ATTRS_o_ai vec_sub(vector bool int __a, vector int __b) { + return (vector int)__a - __b; +} + +static vector int __ATTRS_o_ai vec_sub(vector int __a, vector bool int __b) { + return __a - (vector int)__b; +} + +static vector unsigned int __ATTRS_o_ai vec_sub(vector unsigned int __a, + vector unsigned int __b) { + return __a - __b; +} + +static vector unsigned int __ATTRS_o_ai vec_sub(vector bool int __a, + vector unsigned int __b) { + return (vector unsigned int)__a - __b; +} + +static vector unsigned int __ATTRS_o_ai vec_sub(vector unsigned int __a, + vector bool int __b) { + return __a - (vector unsigned int)__b; +} + +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector signed __int128 __ATTRS_o_ai vec_sub(vector signed __int128 __a, + vector signed __int128 __b) { + return __a - __b; +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_sub(vector unsigned __int128 __a, vector unsigned __int128 __b) { + return __a - __b; +} +#endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) + +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai +vec_sub(vector signed long long __a, vector signed long long __b) { + return __a - __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_sub(vector unsigned long long __a, vector unsigned long long __b) { + return __a - __b; +} + +static vector double __ATTRS_o_ai +vec_sub(vector double __a, vector double __b) { + return __a - __b; +} +#endif + +static vector float __ATTRS_o_ai vec_sub(vector float __a, vector float __b) { + return __a - __b; +} + +/* vec_vsububm */ + +#define __builtin_altivec_vsububm vec_vsububm + +static vector signed char __ATTRS_o_ai vec_vsububm(vector signed char __a, + vector signed char __b) { + return __a - __b; +} + +static vector signed char __ATTRS_o_ai vec_vsububm(vector bool char __a, + vector signed char __b) { + return (vector signed char)__a - __b; +} + +static vector signed char __ATTRS_o_ai vec_vsububm(vector signed char __a, + vector bool char __b) { + return __a - (vector signed char)__b; +} + +static vector unsigned char __ATTRS_o_ai vec_vsububm(vector unsigned char __a, + vector unsigned char __b) { + return __a - __b; +} + +static vector unsigned char __ATTRS_o_ai vec_vsububm(vector bool char __a, + vector unsigned char __b) { + return (vector unsigned char)__a - __b; +} + +static vector unsigned char __ATTRS_o_ai vec_vsububm(vector unsigned char __a, + vector bool char __b) { + return __a - (vector unsigned char)__b; +} + +/* vec_vsubuhm */ + +#define __builtin_altivec_vsubuhm vec_vsubuhm + +static vector short __ATTRS_o_ai vec_vsubuhm(vector short __a, + vector short __b) { + return __a - __b; +} + +static vector short __ATTRS_o_ai vec_vsubuhm(vector bool short __a, + vector short __b) { + return (vector short)__a - __b; +} + +static vector short __ATTRS_o_ai vec_vsubuhm(vector short __a, + vector bool short __b) { + return __a - (vector short)__b; +} + +static vector unsigned short __ATTRS_o_ai +vec_vsubuhm(vector unsigned short __a, vector unsigned short __b) { + return __a - __b; +} + +static vector unsigned short __ATTRS_o_ai +vec_vsubuhm(vector bool short __a, vector unsigned short __b) { + return (vector unsigned short)__a - __b; +} + +static vector unsigned short __ATTRS_o_ai vec_vsubuhm(vector unsigned short __a, + vector bool short __b) { + return __a - (vector unsigned short)__b; +} + +/* vec_vsubuwm */ + +#define __builtin_altivec_vsubuwm vec_vsubuwm + +static vector int __ATTRS_o_ai vec_vsubuwm(vector int __a, vector int __b) { + return __a - __b; +} + +static vector int __ATTRS_o_ai vec_vsubuwm(vector bool int __a, + vector int __b) { + return (vector int)__a - __b; +} + +static vector int __ATTRS_o_ai vec_vsubuwm(vector int __a, + vector bool int __b) { + return __a - (vector int)__b; +} + +static vector unsigned int __ATTRS_o_ai vec_vsubuwm(vector unsigned int __a, + vector unsigned int __b) { + return __a - __b; +} + +static vector unsigned int __ATTRS_o_ai vec_vsubuwm(vector bool int __a, + vector unsigned int __b) { + return (vector unsigned int)__a - __b; +} + +static vector unsigned int __ATTRS_o_ai vec_vsubuwm(vector unsigned int __a, + vector bool int __b) { + return __a - (vector unsigned int)__b; +} + +/* vec_vsubfp */ + +#define __builtin_altivec_vsubfp vec_vsubfp + +static vector float __attribute__((__always_inline__)) +vec_vsubfp(vector float __a, vector float __b) { + return __a - __b; +} + +/* vec_subc */ + +static vector unsigned int __ATTRS_o_ai vec_subc(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vsubcuw(__a, __b); +} + +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector unsigned __int128 __ATTRS_o_ai +vec_subc(vector unsigned __int128 __a, vector unsigned __int128 __b) { + return __builtin_altivec_vsubcuq(__a, __b); +} + +static vector signed __int128 __ATTRS_o_ai +vec_subc(vector signed __int128 __a, vector signed __int128 __b) { + return __builtin_altivec_vsubcuq(__a, __b); +} +#endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) + +/* vec_vsubcuw */ + +static vector unsigned int __attribute__((__always_inline__)) +vec_vsubcuw(vector unsigned int __a, vector unsigned int __b) { + return __builtin_altivec_vsubcuw(__a, __b); +} + +/* vec_subs */ + +static vector signed char __ATTRS_o_ai vec_subs(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vsubsbs(__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_subs(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vsubsbs((vector signed char)__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_subs(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vsubsbs(__a, (vector signed char)__b); +} + +static vector unsigned char __ATTRS_o_ai vec_subs(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vsububs(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_subs(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vsububs((vector unsigned char)__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_subs(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vsububs(__a, (vector unsigned char)__b); +} + +static vector short __ATTRS_o_ai vec_subs(vector short __a, vector short __b) { + return __builtin_altivec_vsubshs(__a, __b); +} + +static vector short __ATTRS_o_ai vec_subs(vector bool short __a, + vector short __b) { + return __builtin_altivec_vsubshs((vector short)__a, __b); +} + +static vector short __ATTRS_o_ai vec_subs(vector short __a, + vector bool short __b) { + return __builtin_altivec_vsubshs(__a, (vector short)__b); +} + +static vector unsigned short __ATTRS_o_ai vec_subs(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vsubuhs(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_subs(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vsubuhs((vector unsigned short)__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_subs(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vsubuhs(__a, (vector unsigned short)__b); +} + +static vector int __ATTRS_o_ai vec_subs(vector int __a, vector int __b) { + return __builtin_altivec_vsubsws(__a, __b); +} + +static vector int __ATTRS_o_ai vec_subs(vector bool int __a, vector int __b) { + return __builtin_altivec_vsubsws((vector int)__a, __b); +} + +static vector int __ATTRS_o_ai vec_subs(vector int __a, vector bool int __b) { + return __builtin_altivec_vsubsws(__a, (vector int)__b); +} + +static vector unsigned int __ATTRS_o_ai vec_subs(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vsubuws(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_subs(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vsubuws((vector unsigned int)__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_subs(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vsubuws(__a, (vector unsigned int)__b); +} + +/* vec_vsubsbs */ + +static vector signed char __ATTRS_o_ai vec_vsubsbs(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vsubsbs(__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_vsubsbs(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vsubsbs((vector signed char)__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_vsubsbs(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vsubsbs(__a, (vector signed char)__b); +} + +/* vec_vsububs */ + +static vector unsigned char __ATTRS_o_ai vec_vsububs(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vsububs(__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_vsububs(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vsububs((vector unsigned char)__a, __b); +} + +static vector unsigned char __ATTRS_o_ai vec_vsububs(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vsububs(__a, (vector unsigned char)__b); +} + +/* vec_vsubshs */ + +static vector short __ATTRS_o_ai vec_vsubshs(vector short __a, + vector short __b) { + return __builtin_altivec_vsubshs(__a, __b); +} + +static vector short __ATTRS_o_ai vec_vsubshs(vector bool short __a, + vector short __b) { + return __builtin_altivec_vsubshs((vector short)__a, __b); +} + +static vector short __ATTRS_o_ai vec_vsubshs(vector short __a, + vector bool short __b) { + return __builtin_altivec_vsubshs(__a, (vector short)__b); +} + +/* vec_vsubuhs */ + +static vector unsigned short __ATTRS_o_ai +vec_vsubuhs(vector unsigned short __a, vector unsigned short __b) { + return __builtin_altivec_vsubuhs(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai +vec_vsubuhs(vector bool short __a, vector unsigned short __b) { + return __builtin_altivec_vsubuhs((vector unsigned short)__a, __b); +} + +static vector unsigned short __ATTRS_o_ai vec_vsubuhs(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vsubuhs(__a, (vector unsigned short)__b); +} + +/* vec_vsubsws */ + +static vector int __ATTRS_o_ai vec_vsubsws(vector int __a, vector int __b) { + return __builtin_altivec_vsubsws(__a, __b); +} + +static vector int __ATTRS_o_ai vec_vsubsws(vector bool int __a, + vector int __b) { + return __builtin_altivec_vsubsws((vector int)__a, __b); +} + +static vector int __ATTRS_o_ai vec_vsubsws(vector int __a, + vector bool int __b) { + return __builtin_altivec_vsubsws(__a, (vector int)__b); +} + +/* vec_vsubuws */ + +static vector unsigned int __ATTRS_o_ai vec_vsubuws(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vsubuws(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_vsubuws(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vsubuws((vector unsigned int)__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_vsubuws(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vsubuws(__a, (vector unsigned int)__b); +} + +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +/* vec_vsubuqm */ + +static vector signed __int128 __ATTRS_o_ai +vec_vsubuqm(vector signed __int128 __a, vector signed __int128 __b) { + return __a - __b; +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vsubuqm(vector unsigned __int128 __a, vector unsigned __int128 __b) { + return __a - __b; +} + +/* vec_vsubeuqm */ + +static vector signed __int128 __ATTRS_o_ai +vec_vsubeuqm(vector signed __int128 __a, vector signed __int128 __b, + vector signed __int128 __c) { + return __builtin_altivec_vsubeuqm(__a, __b, __c); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vsubeuqm(vector unsigned __int128 __a, vector unsigned __int128 __b, + vector unsigned __int128 __c) { + return __builtin_altivec_vsubeuqm(__a, __b, __c); +} + +/* vec_vsubcuq */ + +static vector signed __int128 __ATTRS_o_ai +vec_vsubcuq(vector signed __int128 __a, vector signed __int128 __b) { + return __builtin_altivec_vsubcuq(__a, __b); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vsubcuq(vector unsigned __int128 __a, vector unsigned __int128 __b) { + return __builtin_altivec_vsubcuq(__a, __b); +} + +/* vec_vsubecuq */ + +static vector signed __int128 __ATTRS_o_ai +vec_vsubecuq(vector signed __int128 __a, vector signed __int128 __b, + vector signed __int128 __c) { + return __builtin_altivec_vsubecuq(__a, __b, __c); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vsubecuq(vector unsigned __int128 __a, vector unsigned __int128 __b, + vector unsigned __int128 __c) { + return __builtin_altivec_vsubecuq(__a, __b, __c); +} +#endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) + +/* vec_sum4s */ + +static vector int __ATTRS_o_ai vec_sum4s(vector signed char __a, + vector int __b) { + return __builtin_altivec_vsum4sbs(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai vec_sum4s(vector unsigned char __a, + vector unsigned int __b) { + return __builtin_altivec_vsum4ubs(__a, __b); +} + +static vector int __ATTRS_o_ai vec_sum4s(vector signed short __a, + vector int __b) { + return __builtin_altivec_vsum4shs(__a, __b); +} + +/* vec_vsum4sbs */ + +static vector int __attribute__((__always_inline__)) +vec_vsum4sbs(vector signed char __a, vector int __b) { + return __builtin_altivec_vsum4sbs(__a, __b); +} + +/* vec_vsum4ubs */ + +static vector unsigned int __attribute__((__always_inline__)) +vec_vsum4ubs(vector unsigned char __a, vector unsigned int __b) { + return __builtin_altivec_vsum4ubs(__a, __b); +} + +/* vec_vsum4shs */ + +static vector int __attribute__((__always_inline__)) +vec_vsum4shs(vector signed short __a, vector int __b) { + return __builtin_altivec_vsum4shs(__a, __b); +} + +/* vec_sum2s */ + +/* The vsum2sws instruction has a big-endian bias, so that the second + input vector and the result always reference big-endian elements + 1 and 3 (little-endian element 0 and 2). For ease of porting the + programmer wants elements 1 and 3 in both cases, so for little + endian we must perform some permutes. */ + +static vector signed int __attribute__((__always_inline__)) +vec_sum2s(vector int __a, vector int __b) { +#ifdef __LITTLE_ENDIAN__ + vector int __c = (vector signed int)vec_perm( + __b, __b, (vector unsigned char)(4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, + 8, 9, 10, 11)); + __c = __builtin_altivec_vsum2sws(__a, __c); + return (vector signed int)vec_perm( + __c, __c, (vector unsigned char)(4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, + 8, 9, 10, 11)); +#else + return __builtin_altivec_vsum2sws(__a, __b); +#endif +} + +/* vec_vsum2sws */ + +static vector signed int __attribute__((__always_inline__)) +vec_vsum2sws(vector int __a, vector int __b) { +#ifdef __LITTLE_ENDIAN__ + vector int __c = (vector signed int)vec_perm( + __b, __b, (vector unsigned char)(4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, + 8, 9, 10, 11)); + __c = __builtin_altivec_vsum2sws(__a, __c); + return (vector signed int)vec_perm( + __c, __c, (vector unsigned char)(4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, + 8, 9, 10, 11)); +#else + return __builtin_altivec_vsum2sws(__a, __b); +#endif +} + +/* vec_sums */ + +/* The vsumsws instruction has a big-endian bias, so that the second + input vector and the result always reference big-endian element 3 + (little-endian element 0). For ease of porting the programmer + wants element 3 in both cases, so for little endian we must perform + some permutes. */ + +static vector signed int __attribute__((__always_inline__)) +vec_sums(vector signed int __a, vector signed int __b) { +#ifdef __LITTLE_ENDIAN__ + __b = (vector signed int)vec_splat(__b, 3); + __b = __builtin_altivec_vsumsws(__a, __b); + return (vector signed int)(0, 0, 0, __b[0]); +#else + return __builtin_altivec_vsumsws(__a, __b); +#endif +} + +/* vec_vsumsws */ + +static vector signed int __attribute__((__always_inline__)) +vec_vsumsws(vector signed int __a, vector signed int __b) { +#ifdef __LITTLE_ENDIAN__ + __b = (vector signed int)vec_splat(__b, 3); + __b = __builtin_altivec_vsumsws(__a, __b); + return (vector signed int)(0, 0, 0, __b[0]); +#else + return __builtin_altivec_vsumsws(__a, __b); +#endif +} + +/* vec_trunc */ + +static vector float __ATTRS_o_ai +vec_trunc(vector float __a) { +#ifdef __VSX__ + return __builtin_vsx_xvrspiz(__a); +#else + return __builtin_altivec_vrfiz(__a); +#endif +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai vec_trunc(vector double __a) { + return __builtin_vsx_xvrdpiz(__a); +} +#endif + +/* vec_vrfiz */ + +static vector float __attribute__((__always_inline__)) +vec_vrfiz(vector float __a) { + return __builtin_altivec_vrfiz(__a); +} + +/* vec_unpackh */ + +/* The vector unpack instructions all have a big-endian bias, so for + little endian we must reverse the meanings of "high" and "low." */ + +static vector short __ATTRS_o_ai vec_unpackh(vector signed char __a) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vupklsb((vector char)__a); +#else + return __builtin_altivec_vupkhsb((vector char)__a); +#endif +} + +static vector bool short __ATTRS_o_ai vec_unpackh(vector bool char __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool short)__builtin_altivec_vupklsb((vector char)__a); +#else + return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a); +#endif +} + +static vector int __ATTRS_o_ai vec_unpackh(vector short __a) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vupklsh(__a); +#else + return __builtin_altivec_vupkhsh(__a); +#endif +} + +static vector bool int __ATTRS_o_ai vec_unpackh(vector bool short __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool int)__builtin_altivec_vupklsh((vector short)__a); +#else + return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a); +#endif +} + +static vector unsigned int __ATTRS_o_ai vec_unpackh(vector pixel __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a); +#else + return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a); +#endif +} + +#ifdef __POWER8_VECTOR__ +static vector long long __ATTRS_o_ai vec_unpackh(vector int __a) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vupklsw(__a); +#else + return __builtin_altivec_vupkhsw(__a); +#endif +} + +static vector bool long long __ATTRS_o_ai vec_unpackh(vector bool int __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool long long)__builtin_altivec_vupklsw((vector int)__a); +#else + return (vector bool long long)__builtin_altivec_vupkhsw((vector int)__a); +#endif +} +#endif + +/* vec_vupkhsb */ + +static vector short __ATTRS_o_ai vec_vupkhsb(vector signed char __a) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vupklsb((vector char)__a); +#else + return __builtin_altivec_vupkhsb((vector char)__a); +#endif +} + +static vector bool short __ATTRS_o_ai vec_vupkhsb(vector bool char __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool short)__builtin_altivec_vupklsb((vector char)__a); +#else + return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a); +#endif +} + +/* vec_vupkhsh */ + +static vector int __ATTRS_o_ai vec_vupkhsh(vector short __a) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vupklsh(__a); +#else + return __builtin_altivec_vupkhsh(__a); +#endif +} + +static vector bool int __ATTRS_o_ai vec_vupkhsh(vector bool short __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool int)__builtin_altivec_vupklsh((vector short)__a); +#else + return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a); +#endif +} + +static vector unsigned int __ATTRS_o_ai vec_vupkhsh(vector pixel __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a); +#else + return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a); +#endif +} + +/* vec_vupkhsw */ + +#ifdef __POWER8_VECTOR__ +static vector long long __ATTRS_o_ai vec_vupkhsw(vector int __a) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vupklsw(__a); +#else + return __builtin_altivec_vupkhsw(__a); +#endif +} + +static vector bool long long __ATTRS_o_ai vec_vupkhsw(vector bool int __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool long long)__builtin_altivec_vupklsw((vector int)__a); +#else + return (vector bool long long)__builtin_altivec_vupkhsw((vector int)__a); +#endif +} +#endif + +/* vec_unpackl */ + +static vector short __ATTRS_o_ai vec_unpackl(vector signed char __a) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vupkhsb((vector char)__a); +#else + return __builtin_altivec_vupklsb((vector char)__a); +#endif +} + +static vector bool short __ATTRS_o_ai vec_unpackl(vector bool char __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a); +#else + return (vector bool short)__builtin_altivec_vupklsb((vector char)__a); +#endif +} + +static vector int __ATTRS_o_ai vec_unpackl(vector short __a) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vupkhsh(__a); +#else + return __builtin_altivec_vupklsh(__a); +#endif +} + +static vector bool int __ATTRS_o_ai vec_unpackl(vector bool short __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a); +#else + return (vector bool int)__builtin_altivec_vupklsh((vector short)__a); +#endif +} + +static vector unsigned int __ATTRS_o_ai vec_unpackl(vector pixel __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a); +#else + return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a); +#endif +} + +#ifdef __POWER8_VECTOR__ +static vector long long __ATTRS_o_ai vec_unpackl(vector int __a) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vupkhsw(__a); +#else + return __builtin_altivec_vupklsw(__a); +#endif +} + +static vector bool long long __ATTRS_o_ai vec_unpackl(vector bool int __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool long long)__builtin_altivec_vupkhsw((vector int)__a); +#else + return (vector bool long long)__builtin_altivec_vupklsw((vector int)__a); +#endif +} +#endif + +/* vec_vupklsb */ + +static vector short __ATTRS_o_ai vec_vupklsb(vector signed char __a) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vupkhsb((vector char)__a); +#else + return __builtin_altivec_vupklsb((vector char)__a); +#endif +} + +static vector bool short __ATTRS_o_ai vec_vupklsb(vector bool char __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a); +#else + return (vector bool short)__builtin_altivec_vupklsb((vector char)__a); +#endif +} + +/* vec_vupklsh */ + +static vector int __ATTRS_o_ai vec_vupklsh(vector short __a) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vupkhsh(__a); +#else + return __builtin_altivec_vupklsh(__a); +#endif +} + +static vector bool int __ATTRS_o_ai vec_vupklsh(vector bool short __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a); +#else + return (vector bool int)__builtin_altivec_vupklsh((vector short)__a); +#endif +} + +static vector unsigned int __ATTRS_o_ai vec_vupklsh(vector pixel __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a); +#else + return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a); +#endif +} + +/* vec_vupklsw */ + +#ifdef __POWER8_VECTOR__ +static vector long long __ATTRS_o_ai vec_vupklsw(vector int __a) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vupkhsw(__a); +#else + return __builtin_altivec_vupklsw(__a); +#endif +} + +static vector bool long long __ATTRS_o_ai vec_vupklsw(vector bool int __a) { +#ifdef __LITTLE_ENDIAN__ + return (vector bool long long)__builtin_altivec_vupkhsw((vector int)__a); +#else + return (vector bool long long)__builtin_altivec_vupklsw((vector int)__a); +#endif +} +#endif + +/* vec_vsx_ld */ + +#ifdef __VSX__ + +static vector signed int __ATTRS_o_ai vec_vsx_ld(int __a, + const vector signed int *__b) { + return (vector signed int)__builtin_vsx_lxvw4x(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai +vec_vsx_ld(int __a, const vector unsigned int *__b) { + return (vector unsigned int)__builtin_vsx_lxvw4x(__a, __b); +} + +static vector float __ATTRS_o_ai vec_vsx_ld(int __a, const vector float *__b) { + return (vector float)__builtin_vsx_lxvw4x(__a, __b); +} + +static vector signed long long __ATTRS_o_ai +vec_vsx_ld(int __a, const vector signed long long *__b) { + return (vector signed long long)__builtin_vsx_lxvd2x(__a, __b); +} + +static vector unsigned long long __ATTRS_o_ai +vec_vsx_ld(int __a, const vector unsigned long long *__b) { + return (vector unsigned long long)__builtin_vsx_lxvd2x(__a, __b); +} + +static vector double __ATTRS_o_ai vec_vsx_ld(int __a, + const vector double *__b) { + return (vector double)__builtin_vsx_lxvd2x(__a, __b); +} + +#endif + +/* vec_vsx_st */ + +#ifdef __VSX__ + +static void __ATTRS_o_ai vec_vsx_st(vector signed int __a, int __b, + vector signed int *__c) { + __builtin_vsx_stxvw4x((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_vsx_st(vector unsigned int __a, int __b, + vector unsigned int *__c) { + __builtin_vsx_stxvw4x((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_vsx_st(vector float __a, int __b, + vector float *__c) { + __builtin_vsx_stxvw4x((vector int)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_vsx_st(vector signed long long __a, int __b, + vector signed long long *__c) { + __builtin_vsx_stxvd2x((vector double)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_vsx_st(vector unsigned long long __a, int __b, + vector unsigned long long *__c) { + __builtin_vsx_stxvd2x((vector double)__a, __b, __c); +} + +static void __ATTRS_o_ai vec_vsx_st(vector double __a, int __b, + vector double *__c) { + __builtin_vsx_stxvd2x((vector double)__a, __b, __c); +} + +#endif + +/* vec_xor */ + +#define __builtin_altivec_vxor vec_xor + +static vector signed char __ATTRS_o_ai vec_xor(vector signed char __a, + vector signed char __b) { + return __a ^ __b; +} + +static vector signed char __ATTRS_o_ai vec_xor(vector bool char __a, + vector signed char __b) { + return (vector signed char)__a ^ __b; +} + +static vector signed char __ATTRS_o_ai vec_xor(vector signed char __a, + vector bool char __b) { + return __a ^ (vector signed char)__b; +} + +static vector unsigned char __ATTRS_o_ai vec_xor(vector unsigned char __a, + vector unsigned char __b) { + return __a ^ __b; +} + +static vector unsigned char __ATTRS_o_ai vec_xor(vector bool char __a, + vector unsigned char __b) { + return (vector unsigned char)__a ^ __b; +} + +static vector unsigned char __ATTRS_o_ai vec_xor(vector unsigned char __a, + vector bool char __b) { + return __a ^ (vector unsigned char)__b; +} + +static vector bool char __ATTRS_o_ai vec_xor(vector bool char __a, + vector bool char __b) { + return __a ^ __b; +} + +static vector short __ATTRS_o_ai vec_xor(vector short __a, vector short __b) { + return __a ^ __b; +} + +static vector short __ATTRS_o_ai vec_xor(vector bool short __a, + vector short __b) { + return (vector short)__a ^ __b; +} + +static vector short __ATTRS_o_ai vec_xor(vector short __a, + vector bool short __b) { + return __a ^ (vector short)__b; +} + +static vector unsigned short __ATTRS_o_ai vec_xor(vector unsigned short __a, + vector unsigned short __b) { + return __a ^ __b; +} + +static vector unsigned short __ATTRS_o_ai vec_xor(vector bool short __a, + vector unsigned short __b) { + return (vector unsigned short)__a ^ __b; +} + +static vector unsigned short __ATTRS_o_ai vec_xor(vector unsigned short __a, + vector bool short __b) { + return __a ^ (vector unsigned short)__b; +} + +static vector bool short __ATTRS_o_ai vec_xor(vector bool short __a, + vector bool short __b) { + return __a ^ __b; +} + +static vector int __ATTRS_o_ai vec_xor(vector int __a, vector int __b) { + return __a ^ __b; +} + +static vector int __ATTRS_o_ai vec_xor(vector bool int __a, vector int __b) { + return (vector int)__a ^ __b; +} + +static vector int __ATTRS_o_ai vec_xor(vector int __a, vector bool int __b) { + return __a ^ (vector int)__b; +} + +static vector unsigned int __ATTRS_o_ai vec_xor(vector unsigned int __a, + vector unsigned int __b) { + return __a ^ __b; +} + +static vector unsigned int __ATTRS_o_ai vec_xor(vector bool int __a, + vector unsigned int __b) { + return (vector unsigned int)__a ^ __b; +} + +static vector unsigned int __ATTRS_o_ai vec_xor(vector unsigned int __a, + vector bool int __b) { + return __a ^ (vector unsigned int)__b; +} + +static vector bool int __ATTRS_o_ai vec_xor(vector bool int __a, + vector bool int __b) { + return __a ^ __b; +} + +static vector float __ATTRS_o_ai vec_xor(vector float __a, vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a ^ (vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_xor(vector bool int __a, + vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a ^ (vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_xor(vector float __a, + vector bool int __b) { + vector unsigned int __res = + (vector unsigned int)__a ^ (vector unsigned int)__b; + return (vector float)__res; +} + +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai +vec_xor(vector signed long long __a, vector signed long long __b) { + return __a ^ __b; +} + +static vector signed long long __ATTRS_o_ai +vec_xor(vector bool long long __a, vector signed long long __b) { + return (vector signed long long)__a ^ __b; +} + +static vector signed long long __ATTRS_o_ai vec_xor(vector signed long long __a, + vector bool long long __b) { + return __a ^ (vector signed long long)__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_xor(vector unsigned long long __a, vector unsigned long long __b) { + return __a ^ __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_xor(vector bool long long __a, vector unsigned long long __b) { + return (vector unsigned long long)__a ^ __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_xor(vector unsigned long long __a, vector bool long long __b) { + return __a ^ (vector unsigned long long)__b; +} + +static vector bool long long __ATTRS_o_ai vec_xor(vector bool long long __a, + vector bool long long __b) { + return __a ^ __b; +} + +static vector double __ATTRS_o_ai +vec_xor(vector double __a, vector double __b) { + return (vector double)((vector unsigned long long)__a ^ + (vector unsigned long long)__b); +} + +static vector double __ATTRS_o_ai +vec_xor(vector double __a, vector bool long long __b) { + return (vector double)((vector unsigned long long)__a ^ + (vector unsigned long long) __b); +} + +static vector double __ATTRS_o_ai +vec_xor(vector bool long long __a, vector double __b) { + return (vector double)((vector unsigned long long)__a ^ + (vector unsigned long long)__b); +} +#endif + +/* vec_vxor */ + +static vector signed char __ATTRS_o_ai vec_vxor(vector signed char __a, + vector signed char __b) { + return __a ^ __b; +} + +static vector signed char __ATTRS_o_ai vec_vxor(vector bool char __a, + vector signed char __b) { + return (vector signed char)__a ^ __b; +} + +static vector signed char __ATTRS_o_ai vec_vxor(vector signed char __a, + vector bool char __b) { + return __a ^ (vector signed char)__b; +} + +static vector unsigned char __ATTRS_o_ai vec_vxor(vector unsigned char __a, + vector unsigned char __b) { + return __a ^ __b; +} + +static vector unsigned char __ATTRS_o_ai vec_vxor(vector bool char __a, + vector unsigned char __b) { + return (vector unsigned char)__a ^ __b; +} + +static vector unsigned char __ATTRS_o_ai vec_vxor(vector unsigned char __a, + vector bool char __b) { + return __a ^ (vector unsigned char)__b; +} + +static vector bool char __ATTRS_o_ai vec_vxor(vector bool char __a, + vector bool char __b) { + return __a ^ __b; +} + +static vector short __ATTRS_o_ai vec_vxor(vector short __a, vector short __b) { + return __a ^ __b; +} + +static vector short __ATTRS_o_ai vec_vxor(vector bool short __a, + vector short __b) { + return (vector short)__a ^ __b; +} + +static vector short __ATTRS_o_ai vec_vxor(vector short __a, + vector bool short __b) { + return __a ^ (vector short)__b; +} + +static vector unsigned short __ATTRS_o_ai vec_vxor(vector unsigned short __a, + vector unsigned short __b) { + return __a ^ __b; +} + +static vector unsigned short __ATTRS_o_ai vec_vxor(vector bool short __a, + vector unsigned short __b) { + return (vector unsigned short)__a ^ __b; +} + +static vector unsigned short __ATTRS_o_ai vec_vxor(vector unsigned short __a, + vector bool short __b) { + return __a ^ (vector unsigned short)__b; +} + +static vector bool short __ATTRS_o_ai vec_vxor(vector bool short __a, + vector bool short __b) { + return __a ^ __b; +} + +static vector int __ATTRS_o_ai vec_vxor(vector int __a, vector int __b) { + return __a ^ __b; +} + +static vector int __ATTRS_o_ai vec_vxor(vector bool int __a, vector int __b) { + return (vector int)__a ^ __b; +} + +static vector int __ATTRS_o_ai vec_vxor(vector int __a, vector bool int __b) { + return __a ^ (vector int)__b; +} + +static vector unsigned int __ATTRS_o_ai vec_vxor(vector unsigned int __a, + vector unsigned int __b) { + return __a ^ __b; +} + +static vector unsigned int __ATTRS_o_ai vec_vxor(vector bool int __a, + vector unsigned int __b) { + return (vector unsigned int)__a ^ __b; +} + +static vector unsigned int __ATTRS_o_ai vec_vxor(vector unsigned int __a, + vector bool int __b) { + return __a ^ (vector unsigned int)__b; +} + +static vector bool int __ATTRS_o_ai vec_vxor(vector bool int __a, + vector bool int __b) { + return __a ^ __b; +} + +static vector float __ATTRS_o_ai vec_vxor(vector float __a, vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a ^ (vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_vxor(vector bool int __a, + vector float __b) { + vector unsigned int __res = + (vector unsigned int)__a ^ (vector unsigned int)__b; + return (vector float)__res; +} + +static vector float __ATTRS_o_ai vec_vxor(vector float __a, + vector bool int __b) { + vector unsigned int __res = + (vector unsigned int)__a ^ (vector unsigned int)__b; + return (vector float)__res; +} + +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai +vec_vxor(vector signed long long __a, vector signed long long __b) { + return __a ^ __b; +} + +static vector signed long long __ATTRS_o_ai +vec_vxor(vector bool long long __a, vector signed long long __b) { + return (vector signed long long)__a ^ __b; +} + +static vector signed long long __ATTRS_o_ai +vec_vxor(vector signed long long __a, vector bool long long __b) { + return __a ^ (vector signed long long)__b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_vxor(vector unsigned long long __a, vector unsigned long long __b) { + return __a ^ __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_vxor(vector bool long long __a, vector unsigned long long __b) { + return (vector unsigned long long)__a ^ __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_vxor(vector unsigned long long __a, vector bool long long __b) { + return __a ^ (vector unsigned long long)__b; +} + +static vector bool long long __ATTRS_o_ai vec_vxor(vector bool long long __a, + vector bool long long __b) { + return __a ^ __b; +} +#endif + +/* ------------------------ extensions for CBEA ----------------------------- */ + +/* vec_extract */ + +static signed char __ATTRS_o_ai vec_extract(vector signed char __a, int __b) { + return __a[__b]; +} + +static unsigned char __ATTRS_o_ai vec_extract(vector unsigned char __a, + int __b) { + return __a[__b]; +} + +static unsigned char __ATTRS_o_ai vec_extract(vector bool char __a, + int __b) { + return __a[__b]; +} + +static signed short __ATTRS_o_ai vec_extract(vector signed short __a, int __b) { + return __a[__b]; +} + +static unsigned short __ATTRS_o_ai vec_extract(vector unsigned short __a, + int __b) { + return __a[__b]; +} + +static unsigned short __ATTRS_o_ai vec_extract(vector bool short __a, + int __b) { + return __a[__b]; +} + +static signed int __ATTRS_o_ai vec_extract(vector signed int __a, int __b) { + return __a[__b]; +} + +static unsigned int __ATTRS_o_ai vec_extract(vector unsigned int __a, int __b) { + return __a[__b]; +} + +static unsigned int __ATTRS_o_ai vec_extract(vector bool int __a, int __b) { + return __a[__b]; +} + +#ifdef __VSX__ +static signed long long __ATTRS_o_ai vec_extract(vector signed long long __a, + int __b) { + return __a[__b]; +} + +static unsigned long long __ATTRS_o_ai +vec_extract(vector unsigned long long __a, int __b) { + return __a[__b]; +} + +static unsigned long long __ATTRS_o_ai vec_extract(vector bool long long __a, + int __b) { + return __a[__b]; +} + +static double __ATTRS_o_ai vec_extract(vector double __a, int __b) { + return __a[__b]; +} +#endif + +static float __ATTRS_o_ai vec_extract(vector float __a, int __b) { + return __a[__b]; +} + +/* vec_insert */ + +static vector signed char __ATTRS_o_ai vec_insert(signed char __a, + vector signed char __b, + int __c) { + __b[__c] = __a; + return __b; +} + +static vector unsigned char __ATTRS_o_ai vec_insert(unsigned char __a, + vector unsigned char __b, + int __c) { + __b[__c] = __a; + return __b; +} + +static vector bool char __ATTRS_o_ai vec_insert(unsigned char __a, + vector bool char __b, + int __c) { + __b[__c] = __a; + return __b; +} + +static vector signed short __ATTRS_o_ai vec_insert(signed short __a, + vector signed short __b, + int __c) { + __b[__c] = __a; + return __b; +} + +static vector unsigned short __ATTRS_o_ai vec_insert(unsigned short __a, + vector unsigned short __b, + int __c) { + __b[__c] = __a; + return __b; +} + +static vector bool short __ATTRS_o_ai vec_insert(unsigned short __a, + vector bool short __b, + int __c) { + __b[__c] = __a; + return __b; +} + +static vector signed int __ATTRS_o_ai vec_insert(signed int __a, + vector signed int __b, + int __c) { + __b[__c] = __a; + return __b; +} + +static vector unsigned int __ATTRS_o_ai vec_insert(unsigned int __a, + vector unsigned int __b, + int __c) { + __b[__c] = __a; + return __b; +} + +static vector bool int __ATTRS_o_ai vec_insert(unsigned int __a, + vector bool int __b, + int __c) { + __b[__c] = __a; + return __b; +} + +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai +vec_insert(signed long long __a, vector signed long long __b, int __c) { + __b[__c] = __a; + return __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_insert(unsigned long long __a, vector unsigned long long __b, int __c) { + __b[__c] = __a; + return __b; +} + +static vector bool long long __ATTRS_o_ai +vec_insert(unsigned long long __a, vector bool long long __b, int __c) { + __b[__c] = __a; + return __b; +} +static vector double __ATTRS_o_ai vec_insert(double __a, vector double __b, + int __c) { + __b[__c] = __a; + return __b; +} +#endif + +static vector float __ATTRS_o_ai vec_insert(float __a, vector float __b, + int __c) { + __b[__c] = __a; + return __b; +} + +/* vec_lvlx */ + +static vector signed char __ATTRS_o_ai vec_lvlx(int __a, + const signed char *__b) { + return vec_perm(vec_ld(__a, __b), (vector signed char)(0), + vec_lvsl(__a, __b)); +} + +static vector signed char __ATTRS_o_ai vec_lvlx(int __a, + const vector signed char *__b) { + return vec_perm(vec_ld(__a, __b), (vector signed char)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector unsigned char __ATTRS_o_ai vec_lvlx(int __a, + const unsigned char *__b) { + return vec_perm(vec_ld(__a, __b), (vector unsigned char)(0), + vec_lvsl(__a, __b)); +} + +static vector unsigned char __ATTRS_o_ai +vec_lvlx(int __a, const vector unsigned char *__b) { + return vec_perm(vec_ld(__a, __b), (vector unsigned char)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector bool char __ATTRS_o_ai vec_lvlx(int __a, + const vector bool char *__b) { + return vec_perm(vec_ld(__a, __b), (vector bool char)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector short __ATTRS_o_ai vec_lvlx(int __a, const short *__b) { + return vec_perm(vec_ld(__a, __b), (vector short)(0), vec_lvsl(__a, __b)); +} + +static vector short __ATTRS_o_ai vec_lvlx(int __a, const vector short *__b) { + return vec_perm(vec_ld(__a, __b), (vector short)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector unsigned short __ATTRS_o_ai vec_lvlx(int __a, + const unsigned short *__b) { + return vec_perm(vec_ld(__a, __b), (vector unsigned short)(0), + vec_lvsl(__a, __b)); +} + +static vector unsigned short __ATTRS_o_ai +vec_lvlx(int __a, const vector unsigned short *__b) { + return vec_perm(vec_ld(__a, __b), (vector unsigned short)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector bool short __ATTRS_o_ai vec_lvlx(int __a, + const vector bool short *__b) { + return vec_perm(vec_ld(__a, __b), (vector bool short)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector pixel __ATTRS_o_ai vec_lvlx(int __a, const vector pixel *__b) { + return vec_perm(vec_ld(__a, __b), (vector pixel)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector int __ATTRS_o_ai vec_lvlx(int __a, const int *__b) { + return vec_perm(vec_ld(__a, __b), (vector int)(0), vec_lvsl(__a, __b)); +} + +static vector int __ATTRS_o_ai vec_lvlx(int __a, const vector int *__b) { + return vec_perm(vec_ld(__a, __b), (vector int)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector unsigned int __ATTRS_o_ai vec_lvlx(int __a, + const unsigned int *__b) { + return vec_perm(vec_ld(__a, __b), (vector unsigned int)(0), + vec_lvsl(__a, __b)); +} + +static vector unsigned int __ATTRS_o_ai +vec_lvlx(int __a, const vector unsigned int *__b) { + return vec_perm(vec_ld(__a, __b), (vector unsigned int)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector bool int __ATTRS_o_ai vec_lvlx(int __a, + const vector bool int *__b) { + return vec_perm(vec_ld(__a, __b), (vector bool int)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector float __ATTRS_o_ai vec_lvlx(int __a, const float *__b) { + return vec_perm(vec_ld(__a, __b), (vector float)(0), vec_lvsl(__a, __b)); +} + +static vector float __ATTRS_o_ai vec_lvlx(int __a, const vector float *__b) { + return vec_perm(vec_ld(__a, __b), (vector float)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +/* vec_lvlxl */ + +static vector signed char __ATTRS_o_ai vec_lvlxl(int __a, + const signed char *__b) { + return vec_perm(vec_ldl(__a, __b), (vector signed char)(0), + vec_lvsl(__a, __b)); +} + +static vector signed char __ATTRS_o_ai +vec_lvlxl(int __a, const vector signed char *__b) { + return vec_perm(vec_ldl(__a, __b), (vector signed char)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector unsigned char __ATTRS_o_ai vec_lvlxl(int __a, + const unsigned char *__b) { + return vec_perm(vec_ldl(__a, __b), (vector unsigned char)(0), + vec_lvsl(__a, __b)); +} + +static vector unsigned char __ATTRS_o_ai +vec_lvlxl(int __a, const vector unsigned char *__b) { + return vec_perm(vec_ldl(__a, __b), (vector unsigned char)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector bool char __ATTRS_o_ai vec_lvlxl(int __a, + const vector bool char *__b) { + return vec_perm(vec_ldl(__a, __b), (vector bool char)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector short __ATTRS_o_ai vec_lvlxl(int __a, const short *__b) { + return vec_perm(vec_ldl(__a, __b), (vector short)(0), vec_lvsl(__a, __b)); +} + +static vector short __ATTRS_o_ai vec_lvlxl(int __a, const vector short *__b) { + return vec_perm(vec_ldl(__a, __b), (vector short)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector unsigned short __ATTRS_o_ai vec_lvlxl(int __a, + const unsigned short *__b) { + return vec_perm(vec_ldl(__a, __b), (vector unsigned short)(0), + vec_lvsl(__a, __b)); +} + +static vector unsigned short __ATTRS_o_ai +vec_lvlxl(int __a, const vector unsigned short *__b) { + return vec_perm(vec_ldl(__a, __b), (vector unsigned short)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector bool short __ATTRS_o_ai vec_lvlxl(int __a, + const vector bool short *__b) { + return vec_perm(vec_ldl(__a, __b), (vector bool short)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector pixel __ATTRS_o_ai vec_lvlxl(int __a, const vector pixel *__b) { + return vec_perm(vec_ldl(__a, __b), (vector pixel)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector int __ATTRS_o_ai vec_lvlxl(int __a, const int *__b) { + return vec_perm(vec_ldl(__a, __b), (vector int)(0), vec_lvsl(__a, __b)); +} + +static vector int __ATTRS_o_ai vec_lvlxl(int __a, const vector int *__b) { + return vec_perm(vec_ldl(__a, __b), (vector int)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector unsigned int __ATTRS_o_ai vec_lvlxl(int __a, + const unsigned int *__b) { + return vec_perm(vec_ldl(__a, __b), (vector unsigned int)(0), + vec_lvsl(__a, __b)); +} + +static vector unsigned int __ATTRS_o_ai +vec_lvlxl(int __a, const vector unsigned int *__b) { + return vec_perm(vec_ldl(__a, __b), (vector unsigned int)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector bool int __ATTRS_o_ai vec_lvlxl(int __a, + const vector bool int *__b) { + return vec_perm(vec_ldl(__a, __b), (vector bool int)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector float __ATTRS_o_ai vec_lvlxl(int __a, const float *__b) { + return vec_perm(vec_ldl(__a, __b), (vector float)(0), vec_lvsl(__a, __b)); +} + +static vector float __ATTRS_o_ai vec_lvlxl(int __a, vector float *__b) { + return vec_perm(vec_ldl(__a, __b), (vector float)(0), + vec_lvsl(__a, (unsigned char *)__b)); +} + +/* vec_lvrx */ + +static vector signed char __ATTRS_o_ai vec_lvrx(int __a, + const signed char *__b) { + return vec_perm((vector signed char)(0), vec_ld(__a, __b), + vec_lvsl(__a, __b)); +} + +static vector signed char __ATTRS_o_ai vec_lvrx(int __a, + const vector signed char *__b) { + return vec_perm((vector signed char)(0), vec_ld(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector unsigned char __ATTRS_o_ai vec_lvrx(int __a, + const unsigned char *__b) { + return vec_perm((vector unsigned char)(0), vec_ld(__a, __b), + vec_lvsl(__a, __b)); +} + +static vector unsigned char __ATTRS_o_ai +vec_lvrx(int __a, const vector unsigned char *__b) { + return vec_perm((vector unsigned char)(0), vec_ld(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector bool char __ATTRS_o_ai vec_lvrx(int __a, + const vector bool char *__b) { + return vec_perm((vector bool char)(0), vec_ld(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector short __ATTRS_o_ai vec_lvrx(int __a, const short *__b) { + return vec_perm((vector short)(0), vec_ld(__a, __b), vec_lvsl(__a, __b)); +} + +static vector short __ATTRS_o_ai vec_lvrx(int __a, const vector short *__b) { + return vec_perm((vector short)(0), vec_ld(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector unsigned short __ATTRS_o_ai vec_lvrx(int __a, + const unsigned short *__b) { + return vec_perm((vector unsigned short)(0), vec_ld(__a, __b), + vec_lvsl(__a, __b)); +} + +static vector unsigned short __ATTRS_o_ai +vec_lvrx(int __a, const vector unsigned short *__b) { + return vec_perm((vector unsigned short)(0), vec_ld(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector bool short __ATTRS_o_ai vec_lvrx(int __a, + const vector bool short *__b) { + return vec_perm((vector bool short)(0), vec_ld(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector pixel __ATTRS_o_ai vec_lvrx(int __a, const vector pixel *__b) { + return vec_perm((vector pixel)(0), vec_ld(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector int __ATTRS_o_ai vec_lvrx(int __a, const int *__b) { + return vec_perm((vector int)(0), vec_ld(__a, __b), vec_lvsl(__a, __b)); +} + +static vector int __ATTRS_o_ai vec_lvrx(int __a, const vector int *__b) { + return vec_perm((vector int)(0), vec_ld(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector unsigned int __ATTRS_o_ai vec_lvrx(int __a, + const unsigned int *__b) { + return vec_perm((vector unsigned int)(0), vec_ld(__a, __b), + vec_lvsl(__a, __b)); +} + +static vector unsigned int __ATTRS_o_ai +vec_lvrx(int __a, const vector unsigned int *__b) { + return vec_perm((vector unsigned int)(0), vec_ld(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector bool int __ATTRS_o_ai vec_lvrx(int __a, + const vector bool int *__b) { + return vec_perm((vector bool int)(0), vec_ld(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector float __ATTRS_o_ai vec_lvrx(int __a, const float *__b) { + return vec_perm((vector float)(0), vec_ld(__a, __b), vec_lvsl(__a, __b)); +} + +static vector float __ATTRS_o_ai vec_lvrx(int __a, const vector float *__b) { + return vec_perm((vector float)(0), vec_ld(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +/* vec_lvrxl */ + +static vector signed char __ATTRS_o_ai vec_lvrxl(int __a, + const signed char *__b) { + return vec_perm((vector signed char)(0), vec_ldl(__a, __b), + vec_lvsl(__a, __b)); +} + +static vector signed char __ATTRS_o_ai +vec_lvrxl(int __a, const vector signed char *__b) { + return vec_perm((vector signed char)(0), vec_ldl(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector unsigned char __ATTRS_o_ai vec_lvrxl(int __a, + const unsigned char *__b) { + return vec_perm((vector unsigned char)(0), vec_ldl(__a, __b), + vec_lvsl(__a, __b)); +} + +static vector unsigned char __ATTRS_o_ai +vec_lvrxl(int __a, const vector unsigned char *__b) { + return vec_perm((vector unsigned char)(0), vec_ldl(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector bool char __ATTRS_o_ai vec_lvrxl(int __a, + const vector bool char *__b) { + return vec_perm((vector bool char)(0), vec_ldl(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector short __ATTRS_o_ai vec_lvrxl(int __a, const short *__b) { + return vec_perm((vector short)(0), vec_ldl(__a, __b), vec_lvsl(__a, __b)); +} + +static vector short __ATTRS_o_ai vec_lvrxl(int __a, const vector short *__b) { + return vec_perm((vector short)(0), vec_ldl(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector unsigned short __ATTRS_o_ai vec_lvrxl(int __a, + const unsigned short *__b) { + return vec_perm((vector unsigned short)(0), vec_ldl(__a, __b), + vec_lvsl(__a, __b)); +} + +static vector unsigned short __ATTRS_o_ai +vec_lvrxl(int __a, const vector unsigned short *__b) { + return vec_perm((vector unsigned short)(0), vec_ldl(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector bool short __ATTRS_o_ai vec_lvrxl(int __a, + const vector bool short *__b) { + return vec_perm((vector bool short)(0), vec_ldl(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector pixel __ATTRS_o_ai vec_lvrxl(int __a, const vector pixel *__b) { + return vec_perm((vector pixel)(0), vec_ldl(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector int __ATTRS_o_ai vec_lvrxl(int __a, const int *__b) { + return vec_perm((vector int)(0), vec_ldl(__a, __b), vec_lvsl(__a, __b)); +} + +static vector int __ATTRS_o_ai vec_lvrxl(int __a, const vector int *__b) { + return vec_perm((vector int)(0), vec_ldl(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector unsigned int __ATTRS_o_ai vec_lvrxl(int __a, + const unsigned int *__b) { + return vec_perm((vector unsigned int)(0), vec_ldl(__a, __b), + vec_lvsl(__a, __b)); +} + +static vector unsigned int __ATTRS_o_ai +vec_lvrxl(int __a, const vector unsigned int *__b) { + return vec_perm((vector unsigned int)(0), vec_ldl(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector bool int __ATTRS_o_ai vec_lvrxl(int __a, + const vector bool int *__b) { + return vec_perm((vector bool int)(0), vec_ldl(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +static vector float __ATTRS_o_ai vec_lvrxl(int __a, const float *__b) { + return vec_perm((vector float)(0), vec_ldl(__a, __b), vec_lvsl(__a, __b)); +} + +static vector float __ATTRS_o_ai vec_lvrxl(int __a, const vector float *__b) { + return vec_perm((vector float)(0), vec_ldl(__a, __b), + vec_lvsl(__a, (unsigned char *)__b)); +} + +/* vec_stvlx */ + +static void __ATTRS_o_ai vec_stvlx(vector signed char __a, int __b, + signed char *__c) { + return vec_st(vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector signed char __a, int __b, + vector signed char *__c) { + return vec_st( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector unsigned char __a, int __b, + unsigned char *__c) { + return vec_st(vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector unsigned char __a, int __b, + vector unsigned char *__c) { + return vec_st( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector bool char __a, int __b, + vector bool char *__c) { + return vec_st( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector short __a, int __b, short *__c) { + return vec_st(vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector short __a, int __b, + vector short *__c) { + return vec_st( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector unsigned short __a, int __b, + unsigned short *__c) { + return vec_st(vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector unsigned short __a, int __b, + vector unsigned short *__c) { + return vec_st( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector bool short __a, int __b, + vector bool short *__c) { + return vec_st( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector pixel __a, int __b, + vector pixel *__c) { + return vec_st( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector int __a, int __b, int *__c) { + return vec_st(vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector int __a, int __b, vector int *__c) { + return vec_st( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector unsigned int __a, int __b, + unsigned int *__c) { + return vec_st(vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector unsigned int __a, int __b, + vector unsigned int *__c) { + return vec_st( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector bool int __a, int __b, + vector bool int *__c) { + return vec_st( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlx(vector float __a, int __b, + vector float *__c) { + return vec_st( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +/* vec_stvlxl */ + +static void __ATTRS_o_ai vec_stvlxl(vector signed char __a, int __b, + signed char *__c) { + return vec_stl(vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector signed char __a, int __b, + vector signed char *__c) { + return vec_stl( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector unsigned char __a, int __b, + unsigned char *__c) { + return vec_stl(vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector unsigned char __a, int __b, + vector unsigned char *__c) { + return vec_stl( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector bool char __a, int __b, + vector bool char *__c) { + return vec_stl( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector short __a, int __b, short *__c) { + return vec_stl(vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector short __a, int __b, + vector short *__c) { + return vec_stl( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector unsigned short __a, int __b, + unsigned short *__c) { + return vec_stl(vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector unsigned short __a, int __b, + vector unsigned short *__c) { + return vec_stl( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector bool short __a, int __b, + vector bool short *__c) { + return vec_stl( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector pixel __a, int __b, + vector pixel *__c) { + return vec_stl( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector int __a, int __b, int *__c) { + return vec_stl(vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector int __a, int __b, vector int *__c) { + return vec_stl( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector unsigned int __a, int __b, + unsigned int *__c) { + return vec_stl(vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector unsigned int __a, int __b, + vector unsigned int *__c) { + return vec_stl( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector bool int __a, int __b, + vector bool int *__c) { + return vec_stl( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvlxl(vector float __a, int __b, + vector float *__c) { + return vec_stl( + vec_perm(vec_lvrx(__b, __c), __a, vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +/* vec_stvrx */ + +static void __ATTRS_o_ai vec_stvrx(vector signed char __a, int __b, + signed char *__c) { + return vec_st(vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector signed char __a, int __b, + vector signed char *__c) { + return vec_st( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector unsigned char __a, int __b, + unsigned char *__c) { + return vec_st(vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector unsigned char __a, int __b, + vector unsigned char *__c) { + return vec_st( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector bool char __a, int __b, + vector bool char *__c) { + return vec_st( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector short __a, int __b, short *__c) { + return vec_st(vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector short __a, int __b, + vector short *__c) { + return vec_st( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector unsigned short __a, int __b, + unsigned short *__c) { + return vec_st(vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector unsigned short __a, int __b, + vector unsigned short *__c) { + return vec_st( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector bool short __a, int __b, + vector bool short *__c) { + return vec_st( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector pixel __a, int __b, + vector pixel *__c) { + return vec_st( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector int __a, int __b, int *__c) { + return vec_st(vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector int __a, int __b, vector int *__c) { + return vec_st( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector unsigned int __a, int __b, + unsigned int *__c) { + return vec_st(vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector unsigned int __a, int __b, + vector unsigned int *__c) { + return vec_st( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector bool int __a, int __b, + vector bool int *__c) { + return vec_st( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrx(vector float __a, int __b, + vector float *__c) { + return vec_st( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +/* vec_stvrxl */ + +static void __ATTRS_o_ai vec_stvrxl(vector signed char __a, int __b, + signed char *__c) { + return vec_stl(vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector signed char __a, int __b, + vector signed char *__c) { + return vec_stl( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector unsigned char __a, int __b, + unsigned char *__c) { + return vec_stl(vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector unsigned char __a, int __b, + vector unsigned char *__c) { + return vec_stl( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector bool char __a, int __b, + vector bool char *__c) { + return vec_stl( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector short __a, int __b, short *__c) { + return vec_stl(vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector short __a, int __b, + vector short *__c) { + return vec_stl( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector unsigned short __a, int __b, + unsigned short *__c) { + return vec_stl(vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector unsigned short __a, int __b, + vector unsigned short *__c) { + return vec_stl( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector bool short __a, int __b, + vector bool short *__c) { + return vec_stl( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector pixel __a, int __b, + vector pixel *__c) { + return vec_stl( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector int __a, int __b, int *__c) { + return vec_stl(vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector int __a, int __b, vector int *__c) { + return vec_stl( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector unsigned int __a, int __b, + unsigned int *__c) { + return vec_stl(vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, __c)), __b, + __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector unsigned int __a, int __b, + vector unsigned int *__c) { + return vec_stl( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector bool int __a, int __b, + vector bool int *__c) { + return vec_stl( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +static void __ATTRS_o_ai vec_stvrxl(vector float __a, int __b, + vector float *__c) { + return vec_stl( + vec_perm(__a, vec_lvlx(__b, __c), vec_lvsr(__b, (unsigned char *)__c)), + __b, __c); +} + +/* vec_promote */ + +static vector signed char __ATTRS_o_ai vec_promote(signed char __a, int __b) { + vector signed char __res = (vector signed char)(0); + __res[__b] = __a; + return __res; +} + +static vector unsigned char __ATTRS_o_ai vec_promote(unsigned char __a, + int __b) { + vector unsigned char __res = (vector unsigned char)(0); + __res[__b] = __a; + return __res; +} + +static vector short __ATTRS_o_ai vec_promote(short __a, int __b) { + vector short __res = (vector short)(0); + __res[__b] = __a; + return __res; +} + +static vector unsigned short __ATTRS_o_ai vec_promote(unsigned short __a, + int __b) { + vector unsigned short __res = (vector unsigned short)(0); + __res[__b] = __a; + return __res; +} + +static vector int __ATTRS_o_ai vec_promote(int __a, int __b) { + vector int __res = (vector int)(0); + __res[__b] = __a; + return __res; +} + +static vector unsigned int __ATTRS_o_ai vec_promote(unsigned int __a, int __b) { + vector unsigned int __res = (vector unsigned int)(0); + __res[__b] = __a; + return __res; +} + +static vector float __ATTRS_o_ai vec_promote(float __a, int __b) { + vector float __res = (vector float)(0); + __res[__b] = __a; + return __res; +} + +/* vec_splats */ + +static vector signed char __ATTRS_o_ai vec_splats(signed char __a) { + return (vector signed char)(__a); +} + +static vector unsigned char __ATTRS_o_ai vec_splats(unsigned char __a) { + return (vector unsigned char)(__a); +} + +static vector short __ATTRS_o_ai vec_splats(short __a) { + return (vector short)(__a); +} + +static vector unsigned short __ATTRS_o_ai vec_splats(unsigned short __a) { + return (vector unsigned short)(__a); +} + +static vector int __ATTRS_o_ai vec_splats(int __a) { return (vector int)(__a); } + +static vector unsigned int __ATTRS_o_ai vec_splats(unsigned int __a) { + return (vector unsigned int)(__a); +} + +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai vec_splats(signed long long __a) { + return (vector signed long long)(__a); +} + +static vector unsigned long long __ATTRS_o_ai +vec_splats(unsigned long long __a) { + return (vector unsigned long long)(__a); +} + +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector signed __int128 __ATTRS_o_ai vec_splats(signed __int128 __a) { + return (vector signed __int128)(__a); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_splats(unsigned __int128 __a) { + return (vector unsigned __int128)(__a); +} + +#endif + +static vector double __ATTRS_o_ai vec_splats(double __a) { + return (vector double)(__a); +} +#endif + +static vector float __ATTRS_o_ai vec_splats(float __a) { + return (vector float)(__a); +} + +/* ----------------------------- predicates --------------------------------- */ + +/* vec_all_eq */ + +static int __ATTRS_o_ai vec_all_eq(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector bool char __a, vector bool char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector short __a, vector short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT, __a, __b); +} + +static int __ATTRS_o_ai vec_all_eq(vector short __a, vector bool short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT, __a, (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector bool short __a, vector short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector bool short __a, + vector bool short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector pixel __a, vector pixel __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector int __a, vector int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_LT, __a, __b); +} + +static int __ATTRS_o_ai vec_all_eq(vector int __a, vector bool int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_LT, __a, (vector int)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_LT, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_LT, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector bool int __a, vector int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_LT, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_LT, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector bool int __a, vector bool int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_LT, (vector int)__a, + (vector int)__b); +} + +#ifdef __POWER8_VECTOR__ +static int __ATTRS_o_ai vec_all_eq(vector signed long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_LT, __a, __b); +} + +static int __ATTRS_o_ai vec_all_eq(vector long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_LT, __a, (vector long long)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_LT, (vector long long)__a, + (vector long long)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector unsigned long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_LT, (vector long long)__a, + (vector long long)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector bool long long __a, + vector long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_LT, (vector long long)__a, + (vector long long)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector bool long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_LT, (vector long long)__a, + (vector long long)__b); +} + +static int __ATTRS_o_ai vec_all_eq(vector bool long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_LT, (vector long long)__a, + (vector long long)__b); +} +#endif + +static int __ATTRS_o_ai vec_all_eq(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpeqsp_p(__CR6_LT, __a, __b); +#else + return __builtin_altivec_vcmpeqfp_p(__CR6_LT, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_all_eq(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpeqdp_p(__CR6_LT, __a, __b); +} +#endif + +/* vec_all_ge */ + +static int __ATTRS_o_ai vec_all_ge(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_EQ, __b, __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_EQ, (vector signed char)__b, __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ, __b, __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ, (vector unsigned char)__b, __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ, (vector unsigned char)__b, + (vector unsigned char)__a); +} + +static int __ATTRS_o_ai vec_all_ge(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ, __b, (vector unsigned char)__a); +} + +static int __ATTRS_o_ai vec_all_ge(vector bool char __a, vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ, (vector unsigned char)__b, + (vector unsigned char)__a); +} + +static int __ATTRS_o_ai vec_all_ge(vector short __a, vector short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_EQ, __b, __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector short __a, vector bool short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_EQ, (vector short)__b, __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, __b, __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, (vector unsigned short)__b, + __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector bool short __a, vector short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, (vector unsigned short)__b, + (vector unsigned short)__a); +} + +static int __ATTRS_o_ai vec_all_ge(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, __b, + (vector unsigned short)__a); +} + +static int __ATTRS_o_ai vec_all_ge(vector bool short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, (vector unsigned short)__b, + (vector unsigned short)__a); +} + +static int __ATTRS_o_ai vec_all_ge(vector int __a, vector int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_EQ, __b, __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_EQ, (vector int)__b, __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, __b, __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, (vector unsigned int)__b, __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector bool int __a, vector int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, (vector unsigned int)__b, + (vector unsigned int)__a); +} + +static int __ATTRS_o_ai vec_all_ge(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, __b, (vector unsigned int)__a); +} + +static int __ATTRS_o_ai vec_all_ge(vector bool int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, (vector unsigned int)__b, + (vector unsigned int)__a); +} + +#ifdef __POWER8_VECTOR__ +static int __ATTRS_o_ai vec_all_ge(vector signed long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_EQ, __b, __a); +} +static int __ATTRS_o_ai vec_all_ge(vector signed long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_EQ, (vector signed long long)__b, + __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ, __b, __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector unsigned long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ, (vector unsigned long long)__b, + __a); +} + +static int __ATTRS_o_ai vec_all_ge(vector bool long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ, (vector unsigned long long)__b, + (vector unsigned long long)__a); +} + +static int __ATTRS_o_ai vec_all_ge(vector bool long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ, __b, + (vector unsigned long long)__a); +} + +static int __ATTRS_o_ai vec_all_ge(vector bool long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ, (vector unsigned long long)__b, + (vector unsigned long long)__a); +} +#endif + +static int __ATTRS_o_ai vec_all_ge(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgesp_p(__CR6_LT, __a, __b); +#else + return __builtin_altivec_vcmpgefp_p(__CR6_LT, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_all_ge(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgedp_p(__CR6_LT, __a, __b); +} +#endif + +/* vec_all_gt */ + +static int __ATTRS_o_ai vec_all_gt(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_LT, __a, __b); +} + +static int __ATTRS_o_ai vec_all_gt(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_LT, __a, (vector signed char)__b); +} + +static int __ATTRS_o_ai vec_all_gt(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT, __a, __b); +} + +static int __ATTRS_o_ai vec_all_gt(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT, __a, (vector unsigned char)__b); +} + +static int __ATTRS_o_ai vec_all_gt(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT, (vector unsigned char)__a, + (vector unsigned char)__b); +} + +static int __ATTRS_o_ai vec_all_gt(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT, (vector unsigned char)__a, __b); +} + +static int __ATTRS_o_ai vec_all_gt(vector bool char __a, vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT, (vector unsigned char)__a, + (vector unsigned char)__b); +} + +static int __ATTRS_o_ai vec_all_gt(vector short __a, vector short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_LT, __a, __b); +} + +static int __ATTRS_o_ai vec_all_gt(vector short __a, vector bool short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_LT, __a, (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_gt(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT, __a, __b); +} + +static int __ATTRS_o_ai vec_all_gt(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT, __a, + (vector unsigned short)__b); +} + +static int __ATTRS_o_ai vec_all_gt(vector bool short __a, vector short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT, (vector unsigned short)__a, + (vector unsigned short)__b); +} + +static int __ATTRS_o_ai vec_all_gt(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT, (vector unsigned short)__a, + __b); +} + +static int __ATTRS_o_ai vec_all_gt(vector bool short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT, (vector unsigned short)__a, + (vector unsigned short)__b); +} + +static int __ATTRS_o_ai vec_all_gt(vector int __a, vector int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_LT, __a, __b); +} + +static int __ATTRS_o_ai vec_all_gt(vector int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_LT, __a, (vector int)__b); +} + +static int __ATTRS_o_ai vec_all_gt(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT, __a, __b); +} + +static int __ATTRS_o_ai vec_all_gt(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT, __a, (vector unsigned int)__b); +} + +static int __ATTRS_o_ai vec_all_gt(vector bool int __a, vector int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT, (vector unsigned int)__a, + (vector unsigned int)__b); +} + +static int __ATTRS_o_ai vec_all_gt(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT, (vector unsigned int)__a, __b); +} + +static int __ATTRS_o_ai vec_all_gt(vector bool int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT, (vector unsigned int)__a, + (vector unsigned int)__b); +} + +#ifdef __POWER8_VECTOR__ +static int __ATTRS_o_ai vec_all_gt(vector signed long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_LT, __a, __b); +} +static int __ATTRS_o_ai vec_all_gt(vector signed long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_LT, __a, + (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_all_gt(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT, __a, __b); +} + +static int __ATTRS_o_ai vec_all_gt(vector unsigned long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT, __a, + (vector unsigned long long)__b); +} + +static int __ATTRS_o_ai vec_all_gt(vector bool long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT, (vector unsigned long long)__a, + (vector unsigned long long)__b); +} + +static int __ATTRS_o_ai vec_all_gt(vector bool long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT, (vector unsigned long long)__a, + __b); +} + +static int __ATTRS_o_ai vec_all_gt(vector bool long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT, (vector unsigned long long)__a, + (vector unsigned long long)__b); +} +#endif + +static int __ATTRS_o_ai vec_all_gt(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgtsp_p(__CR6_LT, __a, __b); +#else + return __builtin_altivec_vcmpgtfp_p(__CR6_LT, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_all_gt(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgtdp_p(__CR6_LT, __a, __b); +} +#endif + +/* vec_all_in */ + +static int __attribute__((__always_inline__)) +vec_all_in(vector float __a, vector float __b) { + return __builtin_altivec_vcmpbfp_p(__CR6_EQ, __a, __b); +} + +/* vec_all_le */ + +static int __ATTRS_o_ai vec_all_le(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_EQ, __a, __b); +} + +static int __ATTRS_o_ai vec_all_le(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_EQ, __a, (vector signed char)__b); +} + +static int __ATTRS_o_ai vec_all_le(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ, __a, __b); +} + +static int __ATTRS_o_ai vec_all_le(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ, __a, (vector unsigned char)__b); +} + +static int __ATTRS_o_ai vec_all_le(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ, (vector unsigned char)__a, + (vector unsigned char)__b); +} + +static int __ATTRS_o_ai vec_all_le(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ, (vector unsigned char)__a, __b); +} + +static int __ATTRS_o_ai vec_all_le(vector bool char __a, vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ, (vector unsigned char)__a, + (vector unsigned char)__b); +} + +static int __ATTRS_o_ai vec_all_le(vector short __a, vector short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_EQ, __a, __b); +} + +static int __ATTRS_o_ai vec_all_le(vector short __a, vector bool short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_EQ, __a, (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_le(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, __a, __b); +} + +static int __ATTRS_o_ai vec_all_le(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, __a, + (vector unsigned short)__b); +} + +static int __ATTRS_o_ai vec_all_le(vector bool short __a, vector short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, (vector unsigned short)__a, + (vector unsigned short)__b); +} + +static int __ATTRS_o_ai vec_all_le(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, (vector unsigned short)__a, + __b); +} + +static int __ATTRS_o_ai vec_all_le(vector bool short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, (vector unsigned short)__a, + (vector unsigned short)__b); +} + +static int __ATTRS_o_ai vec_all_le(vector int __a, vector int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_EQ, __a, __b); +} + +static int __ATTRS_o_ai vec_all_le(vector int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_EQ, __a, (vector int)__b); +} + +static int __ATTRS_o_ai vec_all_le(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, __a, __b); +} + +static int __ATTRS_o_ai vec_all_le(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, __a, (vector unsigned int)__b); +} + +static int __ATTRS_o_ai vec_all_le(vector bool int __a, vector int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, (vector unsigned int)__a, + (vector unsigned int)__b); +} + +static int __ATTRS_o_ai vec_all_le(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, (vector unsigned int)__a, __b); +} + +static int __ATTRS_o_ai vec_all_le(vector bool int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, (vector unsigned int)__a, + (vector unsigned int)__b); +} + +#ifdef __POWER8_VECTOR__ +static int __ATTRS_o_ai vec_all_le(vector signed long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_EQ, __a, __b); +} + +static int __ATTRS_o_ai vec_all_le(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ, __a, __b); +} + +static int __ATTRS_o_ai vec_all_le(vector signed long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_EQ, __a, + (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_all_le(vector unsigned long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ, __a, + (vector unsigned long long)__b); +} + +static int __ATTRS_o_ai vec_all_le(vector bool long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ, (vector unsigned long long)__a, + (vector unsigned long long)__b); +} + +static int __ATTRS_o_ai vec_all_le(vector bool long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ, (vector unsigned long long)__a, + __b); +} + +static int __ATTRS_o_ai vec_all_le(vector bool long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ, (vector unsigned long long)__a, + (vector unsigned long long)__b); +} +#endif + +static int __ATTRS_o_ai vec_all_le(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgesp_p(__CR6_LT, __b, __a); +#else + return __builtin_altivec_vcmpgefp_p(__CR6_LT, __b, __a); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_all_le(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgedp_p(__CR6_LT, __b, __a); +} +#endif + +/* vec_all_lt */ + +static int __ATTRS_o_ai vec_all_lt(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_LT, __b, __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_LT, (vector signed char)__b, __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT, __b, __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT, (vector unsigned char)__b, __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT, (vector unsigned char)__b, + (vector unsigned char)__a); +} + +static int __ATTRS_o_ai vec_all_lt(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT, __b, (vector unsigned char)__a); +} + +static int __ATTRS_o_ai vec_all_lt(vector bool char __a, vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT, (vector unsigned char)__b, + (vector unsigned char)__a); +} + +static int __ATTRS_o_ai vec_all_lt(vector short __a, vector short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_LT, __b, __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector short __a, vector bool short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_LT, (vector short)__b, __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT, __b, __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT, (vector unsigned short)__b, + __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector bool short __a, vector short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT, (vector unsigned short)__b, + (vector unsigned short)__a); +} + +static int __ATTRS_o_ai vec_all_lt(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT, __b, + (vector unsigned short)__a); +} + +static int __ATTRS_o_ai vec_all_lt(vector bool short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT, (vector unsigned short)__b, + (vector unsigned short)__a); +} + +static int __ATTRS_o_ai vec_all_lt(vector int __a, vector int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_LT, __b, __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_LT, (vector int)__b, __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT, __b, __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT, (vector unsigned int)__b, __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector bool int __a, vector int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT, (vector unsigned int)__b, + (vector unsigned int)__a); +} + +static int __ATTRS_o_ai vec_all_lt(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT, __b, (vector unsigned int)__a); +} + +static int __ATTRS_o_ai vec_all_lt(vector bool int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT, (vector unsigned int)__b, + (vector unsigned int)__a); +} + +#ifdef __POWER8_VECTOR__ +static int __ATTRS_o_ai vec_all_lt(vector signed long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_LT, __b, __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT, __b, __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector signed long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_LT, (vector signed long long)__b, + __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector unsigned long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT, (vector unsigned long long)__b, + __a); +} + +static int __ATTRS_o_ai vec_all_lt(vector bool long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT, (vector unsigned long long)__b, + (vector unsigned long long)__a); +} + +static int __ATTRS_o_ai vec_all_lt(vector bool long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT, __b, + (vector unsigned long long)__a); +} + +static int __ATTRS_o_ai vec_all_lt(vector bool long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT, (vector unsigned long long)__b, + (vector unsigned long long)__a); +} +#endif + +static int __ATTRS_o_ai vec_all_lt(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgtsp_p(__CR6_LT, __b, __a); +#else + return __builtin_altivec_vcmpgtfp_p(__CR6_LT, __b, __a); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_all_lt(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgtdp_p(__CR6_LT, __b, __a); +} +#endif + +/* vec_all_nan */ + +static int __ATTRS_o_ai vec_all_nan(vector float __a) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpeqsp_p(__CR6_EQ, __a, __a); +#else + return __builtin_altivec_vcmpeqfp_p(__CR6_EQ, __a, __a); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_all_nan(vector double __a) { + return __builtin_vsx_xvcmpeqdp_p(__CR6_EQ, __a, __a); +} +#endif + +/* vec_all_ne */ + +static int __ATTRS_o_ai vec_all_ne(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector bool char __a, vector bool char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector short __a, vector short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ, __a, __b); +} + +static int __ATTRS_o_ai vec_all_ne(vector short __a, vector bool short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ, __a, (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector bool short __a, vector short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector bool short __a, + vector bool short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector pixel __a, vector pixel __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector int __a, vector int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_EQ, __a, __b); +} + +static int __ATTRS_o_ai vec_all_ne(vector int __a, vector bool int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_EQ, __a, (vector int)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_EQ, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_EQ, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector bool int __a, vector int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_EQ, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_EQ, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector bool int __a, vector bool int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_EQ, (vector int)__a, + (vector int)__b); +} + +#ifdef __POWER8_VECTOR__ +static int __ATTRS_o_ai vec_all_ne(vector signed long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_EQ, __a, __b); +} + +static int __ATTRS_o_ai vec_all_ne(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_EQ, (vector long long)__a, + (vector long long)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector signed long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_EQ, __a, + (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector unsigned long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_EQ, (vector signed long long)__a, + (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector bool long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_EQ, (vector signed long long)__a, + (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector bool long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_EQ, (vector signed long long)__a, + (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_all_ne(vector bool long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_EQ, (vector signed long long)__a, + (vector signed long long)__b); +} +#endif + +static int __ATTRS_o_ai vec_all_ne(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpeqdp_p(__CR6_EQ, __a, __b); +#else + return __builtin_altivec_vcmpeqfp_p(__CR6_EQ, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_all_ne(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpeqdp_p(__CR6_EQ, __a, __b); +} +#endif + +/* vec_all_nge */ + +static int __ATTRS_o_ai +vec_all_nge(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgesp_p(__CR6_EQ, __a, __b); +#else + return __builtin_altivec_vcmpgefp_p(__CR6_EQ, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai +vec_all_nge(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgedp_p(__CR6_EQ, __a, __b); +} +#endif + +/* vec_all_ngt */ + +static int __ATTRS_o_ai +vec_all_ngt(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgtsp_p(__CR6_EQ, __a, __b); +#else + return __builtin_altivec_vcmpgtfp_p(__CR6_EQ, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai +vec_all_ngt(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgtdp_p(__CR6_EQ, __a, __b); +} +#endif + +/* vec_all_nle */ + +static int __attribute__((__always_inline__)) +vec_all_nle(vector float __a, vector float __b) { + return __builtin_altivec_vcmpgefp_p(__CR6_EQ, __b, __a); +} + +/* vec_all_nlt */ + +static int __attribute__((__always_inline__)) +vec_all_nlt(vector float __a, vector float __b) { + return __builtin_altivec_vcmpgtfp_p(__CR6_EQ, __b, __a); +} + +/* vec_all_numeric */ + +static int __attribute__((__always_inline__)) +vec_all_numeric(vector float __a) { + return __builtin_altivec_vcmpeqfp_p(__CR6_LT, __a, __a); +} + +/* vec_any_eq */ + +static int __ATTRS_o_ai vec_any_eq(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector bool char __a, vector bool char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector short __a, vector short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_eq(vector short __a, vector bool short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, __a, (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector bool short __a, vector short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector bool short __a, + vector bool short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector pixel __a, vector pixel __b) { + return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector int __a, vector int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_eq(vector int __a, vector bool int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, __a, (vector int)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector bool int __a, vector int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector bool int __a, vector bool int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, (vector int)__a, + (vector int)__b); +} + +#ifdef __POWER8_VECTOR__ +static int __ATTRS_o_ai vec_any_eq(vector signed long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_EQ_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_eq(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_EQ_REV, (vector long long)__a, + (vector long long)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector signed long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_EQ_REV, __a, + (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector unsigned long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpequd_p( + __CR6_EQ_REV, (vector signed long long)__a, (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector bool long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpequd_p( + __CR6_EQ_REV, (vector signed long long)__a, (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector bool long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpequd_p( + __CR6_EQ_REV, (vector signed long long)__a, (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_any_eq(vector bool long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpequd_p( + __CR6_EQ_REV, (vector signed long long)__a, (vector signed long long)__b); +} +#endif + +static int __ATTRS_o_ai vec_any_eq(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpeqsp_p(__CR6_EQ_REV, __a, __b); +#else + return __builtin_altivec_vcmpeqfp_p(__CR6_EQ_REV, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_any_eq(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpeqdp_p(__CR6_EQ_REV, __a, __b); +} +#endif + +/* vec_any_ge */ + +static int __ATTRS_o_ai vec_any_ge(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_LT_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_LT_REV, (vector signed char)__b, + __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, (vector unsigned char)__b, + __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, (vector unsigned char)__b, + (vector unsigned char)__a); +} + +static int __ATTRS_o_ai vec_any_ge(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, __b, + (vector unsigned char)__a); +} + +static int __ATTRS_o_ai vec_any_ge(vector bool char __a, vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, (vector unsigned char)__b, + (vector unsigned char)__a); +} + +static int __ATTRS_o_ai vec_any_ge(vector short __a, vector short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_LT_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector short __a, vector bool short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_LT_REV, (vector short)__b, __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, (vector unsigned short)__b, + __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector bool short __a, vector short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, (vector unsigned short)__b, + (vector unsigned short)__a); +} + +static int __ATTRS_o_ai vec_any_ge(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, __b, + (vector unsigned short)__a); +} + +static int __ATTRS_o_ai vec_any_ge(vector bool short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, (vector unsigned short)__b, + (vector unsigned short)__a); +} + +static int __ATTRS_o_ai vec_any_ge(vector int __a, vector int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_LT_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_LT_REV, (vector int)__b, __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, (vector unsigned int)__b, + __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector bool int __a, vector int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, (vector unsigned int)__b, + (vector unsigned int)__a); +} + +static int __ATTRS_o_ai vec_any_ge(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, __b, + (vector unsigned int)__a); +} + +static int __ATTRS_o_ai vec_any_ge(vector bool int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, (vector unsigned int)__b, + (vector unsigned int)__a); +} + +#ifdef __POWER8_VECTOR__ +static int __ATTRS_o_ai vec_any_ge(vector signed long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_LT_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector signed long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_LT_REV, + (vector signed long long)__b, __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector unsigned long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT_REV, + (vector unsigned long long)__b, __a); +} + +static int __ATTRS_o_ai vec_any_ge(vector bool long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT_REV, + (vector unsigned long long)__b, + (vector unsigned long long)__a); +} + +static int __ATTRS_o_ai vec_any_ge(vector bool long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT_REV, __b, + (vector unsigned long long)__a); +} + +static int __ATTRS_o_ai vec_any_ge(vector bool long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT_REV, + (vector unsigned long long)__b, + (vector unsigned long long)__a); +} +#endif + +static int __ATTRS_o_ai vec_any_ge(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgesp_p(__CR6_EQ_REV, __a, __b); +#else + return __builtin_altivec_vcmpgefp_p(__CR6_EQ_REV, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_any_ge(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgedp_p(__CR6_EQ_REV, __a, __b); +} +#endif + +/* vec_any_gt */ + +static int __ATTRS_o_ai vec_any_gt(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_EQ_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_gt(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_EQ_REV, __a, + (vector signed char)__b); +} + +static int __ATTRS_o_ai vec_any_gt(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_gt(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, __a, + (vector unsigned char)__b); +} + +static int __ATTRS_o_ai vec_any_gt(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, (vector unsigned char)__a, + (vector unsigned char)__b); +} + +static int __ATTRS_o_ai vec_any_gt(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, (vector unsigned char)__a, + __b); +} + +static int __ATTRS_o_ai vec_any_gt(vector bool char __a, vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, (vector unsigned char)__a, + (vector unsigned char)__b); +} + +static int __ATTRS_o_ai vec_any_gt(vector short __a, vector short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_EQ_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_gt(vector short __a, vector bool short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_EQ_REV, __a, (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_gt(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_gt(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, __a, + (vector unsigned short)__b); +} + +static int __ATTRS_o_ai vec_any_gt(vector bool short __a, vector short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, (vector unsigned short)__a, + (vector unsigned short)__b); +} + +static int __ATTRS_o_ai vec_any_gt(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, (vector unsigned short)__a, + __b); +} + +static int __ATTRS_o_ai vec_any_gt(vector bool short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, (vector unsigned short)__a, + (vector unsigned short)__b); +} + +static int __ATTRS_o_ai vec_any_gt(vector int __a, vector int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_EQ_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_gt(vector int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_EQ_REV, __a, (vector int)__b); +} + +static int __ATTRS_o_ai vec_any_gt(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_gt(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, __a, + (vector unsigned int)__b); +} + +static int __ATTRS_o_ai vec_any_gt(vector bool int __a, vector int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, (vector unsigned int)__a, + (vector unsigned int)__b); +} + +static int __ATTRS_o_ai vec_any_gt(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, (vector unsigned int)__a, + __b); +} + +static int __ATTRS_o_ai vec_any_gt(vector bool int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, (vector unsigned int)__a, + (vector unsigned int)__b); +} + +#ifdef __POWER8_VECTOR__ +static int __ATTRS_o_ai vec_any_gt(vector signed long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_EQ_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_gt(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_gt(vector signed long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_EQ_REV, __a, + (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_any_gt(vector unsigned long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ_REV, __a, + (vector unsigned long long)__b); +} + +static int __ATTRS_o_ai vec_any_gt(vector bool long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ_REV, + (vector unsigned long long)__a, + (vector unsigned long long)__b); +} + +static int __ATTRS_o_ai vec_any_gt(vector bool long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ_REV, + (vector unsigned long long)__a, __b); +} + +static int __ATTRS_o_ai vec_any_gt(vector bool long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ_REV, + (vector unsigned long long)__a, + (vector unsigned long long)__b); +} +#endif + +static int __ATTRS_o_ai vec_any_gt(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgtsp_p(__CR6_EQ_REV, __a, __b); +#else + return __builtin_altivec_vcmpgtfp_p(__CR6_EQ_REV, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_any_gt(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgtdp_p(__CR6_EQ_REV, __a, __b); +} +#endif + +/* vec_any_le */ + +static int __ATTRS_o_ai vec_any_le(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_LT_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_le(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_LT_REV, __a, + (vector signed char)__b); +} + +static int __ATTRS_o_ai vec_any_le(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_le(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, __a, + (vector unsigned char)__b); +} + +static int __ATTRS_o_ai vec_any_le(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, (vector unsigned char)__a, + (vector unsigned char)__b); +} + +static int __ATTRS_o_ai vec_any_le(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, (vector unsigned char)__a, + __b); +} + +static int __ATTRS_o_ai vec_any_le(vector bool char __a, vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, (vector unsigned char)__a, + (vector unsigned char)__b); +} + +static int __ATTRS_o_ai vec_any_le(vector short __a, vector short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_LT_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_le(vector short __a, vector bool short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_LT_REV, __a, (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_le(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_le(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, __a, + (vector unsigned short)__b); +} + +static int __ATTRS_o_ai vec_any_le(vector bool short __a, vector short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, (vector unsigned short)__a, + (vector unsigned short)__b); +} + +static int __ATTRS_o_ai vec_any_le(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, (vector unsigned short)__a, + __b); +} + +static int __ATTRS_o_ai vec_any_le(vector bool short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, (vector unsigned short)__a, + (vector unsigned short)__b); +} + +static int __ATTRS_o_ai vec_any_le(vector int __a, vector int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_LT_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_le(vector int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_LT_REV, __a, (vector int)__b); +} + +static int __ATTRS_o_ai vec_any_le(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_le(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, __a, + (vector unsigned int)__b); +} + +static int __ATTRS_o_ai vec_any_le(vector bool int __a, vector int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, (vector unsigned int)__a, + (vector unsigned int)__b); +} + +static int __ATTRS_o_ai vec_any_le(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, (vector unsigned int)__a, + __b); +} + +static int __ATTRS_o_ai vec_any_le(vector bool int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, (vector unsigned int)__a, + (vector unsigned int)__b); +} + +#ifdef __POWER8_VECTOR__ +static int __ATTRS_o_ai vec_any_le(vector signed long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_LT_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_le(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_le(vector signed long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_LT_REV, __a, + (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_any_le(vector unsigned long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT_REV, __a, + (vector unsigned long long)__b); +} + +static int __ATTRS_o_ai vec_any_le(vector bool long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT_REV, + (vector unsigned long long)__a, + (vector unsigned long long)__b); +} + +static int __ATTRS_o_ai vec_any_le(vector bool long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT_REV, + (vector unsigned long long)__a, __b); +} + +static int __ATTRS_o_ai vec_any_le(vector bool long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_LT_REV, + (vector unsigned long long)__a, + (vector unsigned long long)__b); +} +#endif + +static int __ATTRS_o_ai vec_any_le(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgesp_p(__CR6_EQ_REV, __b, __a); +#else + return __builtin_altivec_vcmpgefp_p(__CR6_EQ_REV, __b, __a); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_any_le(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgedp_p(__CR6_EQ_REV, __b, __a); +} +#endif + +/* vec_any_lt */ + +static int __ATTRS_o_ai vec_any_lt(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_EQ_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtsb_p(__CR6_EQ_REV, (vector signed char)__b, + __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, (vector unsigned char)__b, + __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, (vector unsigned char)__b, + (vector unsigned char)__a); +} + +static int __ATTRS_o_ai vec_any_lt(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, __b, + (vector unsigned char)__a); +} + +static int __ATTRS_o_ai vec_any_lt(vector bool char __a, vector bool char __b) { + return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, (vector unsigned char)__b, + (vector unsigned char)__a); +} + +static int __ATTRS_o_ai vec_any_lt(vector short __a, vector short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_EQ_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector short __a, vector bool short __b) { + return __builtin_altivec_vcmpgtsh_p(__CR6_EQ_REV, (vector short)__b, __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, (vector unsigned short)__b, + __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector bool short __a, vector short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, (vector unsigned short)__b, + (vector unsigned short)__a); +} + +static int __ATTRS_o_ai vec_any_lt(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, __b, + (vector unsigned short)__a); +} + +static int __ATTRS_o_ai vec_any_lt(vector bool short __a, + vector bool short __b) { + return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, (vector unsigned short)__b, + (vector unsigned short)__a); +} + +static int __ATTRS_o_ai vec_any_lt(vector int __a, vector int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_EQ_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtsw_p(__CR6_EQ_REV, (vector int)__b, __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, (vector unsigned int)__b, + __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector bool int __a, vector int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, (vector unsigned int)__b, + (vector unsigned int)__a); +} + +static int __ATTRS_o_ai vec_any_lt(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, __b, + (vector unsigned int)__a); +} + +static int __ATTRS_o_ai vec_any_lt(vector bool int __a, vector bool int __b) { + return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, (vector unsigned int)__b, + (vector unsigned int)__a); +} + +#ifdef __POWER8_VECTOR__ +static int __ATTRS_o_ai vec_any_lt(vector signed long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_EQ_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ_REV, __b, __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector signed long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtsd_p(__CR6_EQ_REV, + (vector signed long long)__b, __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector unsigned long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ_REV, + (vector unsigned long long)__b, __a); +} + +static int __ATTRS_o_ai vec_any_lt(vector bool long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ_REV, + (vector unsigned long long)__b, + (vector unsigned long long)__a); +} + +static int __ATTRS_o_ai vec_any_lt(vector bool long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ_REV, __b, + (vector unsigned long long)__a); +} + +static int __ATTRS_o_ai vec_any_lt(vector bool long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpgtud_p(__CR6_EQ_REV, + (vector unsigned long long)__b, + (vector unsigned long long)__a); +} +#endif + +static int __ATTRS_o_ai vec_any_lt(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgtsp_p(__CR6_EQ_REV, __b, __a); +#else + return __builtin_altivec_vcmpgtfp_p(__CR6_EQ_REV, __b, __a); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_any_lt(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgtdp_p(__CR6_EQ_REV, __b, __a); +} +#endif + +/* vec_any_nan */ + +static int __attribute__((__always_inline__)) vec_any_nan(vector float __a) { + return __builtin_altivec_vcmpeqfp_p(__CR6_LT_REV, __a, __a); +} + +/* vec_any_ne */ + +static int __ATTRS_o_ai vec_any_ne(vector signed char __a, + vector signed char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector signed char __a, + vector bool char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector unsigned char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector unsigned char __a, + vector bool char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector bool char __a, + vector signed char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector bool char __a, + vector unsigned char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector bool char __a, vector bool char __b) { + return __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)__a, + (vector char)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector short __a, vector short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_ne(vector short __a, vector bool short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT_REV, __a, (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector unsigned short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT_REV, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector unsigned short __a, + vector bool short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT_REV, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector bool short __a, vector short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT_REV, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector bool short __a, + vector unsigned short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT_REV, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector bool short __a, + vector bool short __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT_REV, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector pixel __a, vector pixel __b) { + return __builtin_altivec_vcmpequh_p(__CR6_LT_REV, (vector short)__a, + (vector short)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector int __a, vector int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_LT_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_ne(vector int __a, vector bool int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_LT_REV, __a, (vector int)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector unsigned int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_LT_REV, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector unsigned int __a, + vector bool int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_LT_REV, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector bool int __a, vector int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_LT_REV, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector bool int __a, + vector unsigned int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_LT_REV, (vector int)__a, + (vector int)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector bool int __a, vector bool int __b) { + return __builtin_altivec_vcmpequw_p(__CR6_LT_REV, (vector int)__a, + (vector int)__b); +} + +#ifdef __POWER8_VECTOR__ +static int __ATTRS_o_ai vec_any_ne(vector signed long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_LT_REV, __a, __b); +} + +static int __ATTRS_o_ai vec_any_ne(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_LT_REV, (vector long long)__a, + (vector long long)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector signed long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpequd_p(__CR6_LT_REV, __a, + (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector unsigned long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpequd_p( + __CR6_LT_REV, (vector signed long long)__a, (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector bool long long __a, + vector signed long long __b) { + return __builtin_altivec_vcmpequd_p( + __CR6_LT_REV, (vector signed long long)__a, (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector bool long long __a, + vector unsigned long long __b) { + return __builtin_altivec_vcmpequd_p( + __CR6_LT_REV, (vector signed long long)__a, (vector signed long long)__b); +} + +static int __ATTRS_o_ai vec_any_ne(vector bool long long __a, + vector bool long long __b) { + return __builtin_altivec_vcmpequd_p( + __CR6_LT_REV, (vector signed long long)__a, (vector signed long long)__b); +} +#endif + +static int __ATTRS_o_ai vec_any_ne(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpeqsp_p(__CR6_LT_REV, __a, __b); +#else + return __builtin_altivec_vcmpeqfp_p(__CR6_LT_REV, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_any_ne(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpeqdp_p(__CR6_LT_REV, __a, __b); +} +#endif + +/* vec_any_nge */ + +static int __attribute__((__always_inline__)) +vec_any_nge(vector float __a, vector float __b) { + return __builtin_altivec_vcmpgefp_p(__CR6_LT_REV, __a, __b); +} + +/* vec_any_ngt */ + +static int __attribute__((__always_inline__)) +vec_any_ngt(vector float __a, vector float __b) { + return __builtin_altivec_vcmpgtfp_p(__CR6_LT_REV, __a, __b); +} + +/* vec_any_nle */ + +static int __attribute__((__always_inline__)) +vec_any_nle(vector float __a, vector float __b) { + return __builtin_altivec_vcmpgefp_p(__CR6_LT_REV, __b, __a); +} + +/* vec_any_nlt */ + +static int __attribute__((__always_inline__)) +vec_any_nlt(vector float __a, vector float __b) { + return __builtin_altivec_vcmpgtfp_p(__CR6_LT_REV, __b, __a); +} + +/* vec_any_numeric */ + +static int __attribute__((__always_inline__)) +vec_any_numeric(vector float __a) { + return __builtin_altivec_vcmpeqfp_p(__CR6_EQ_REV, __a, __a); +} + +/* vec_any_out */ + +static int __attribute__((__always_inline__)) +vec_any_out(vector float __a, vector float __b) { + return __builtin_altivec_vcmpbfp_p(__CR6_EQ_REV, __a, __b); +} + +/* Power 8 Crypto functions +Note: We diverge from the current GCC implementation with regard +to cryptography and related functions as follows: +- Only the SHA and AES instructions and builtins are disabled by -mno-crypto +- The remaining ones are only available on Power8 and up so + require -mpower8-vector +The justification for this is that export requirements require that +Category:Vector.Crypto is optional (i.e. compliant hardware may not provide +support). As a result, we need to be able to turn off support for those. +The remaining ones (currently controlled by -mcrypto for GCC) still +need to be provided on compliant hardware even if Vector.Crypto is not +provided. +*/ +#ifdef __CRYPTO__ +#define vec_sbox_be __builtin_altivec_crypto_vsbox +#define vec_cipher_be __builtin_altivec_crypto_vcipher +#define vec_cipherlast_be __builtin_altivec_crypto_vcipherlast +#define vec_ncipher_be __builtin_altivec_crypto_vncipher +#define vec_ncipherlast_be __builtin_altivec_crypto_vncipherlast + +static vector unsigned long long __attribute__((__always_inline__)) +__builtin_crypto_vsbox(vector unsigned long long __a) { + return __builtin_altivec_crypto_vsbox(__a); +} + +static vector unsigned long long __attribute__((__always_inline__)) +__builtin_crypto_vcipher(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_crypto_vcipher(__a, __b); +} + +static vector unsigned long long __attribute__((__always_inline__)) +__builtin_crypto_vcipherlast(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_crypto_vcipherlast(__a, __b); +} + +static vector unsigned long long __attribute__((__always_inline__)) +__builtin_crypto_vncipher(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_crypto_vncipher(__a, __b); +} + +static vector unsigned long long __attribute__((__always_inline__)) +__builtin_crypto_vncipherlast(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_crypto_vncipherlast(__a, __b); +} + +#define __builtin_crypto_vshasigmad __builtin_altivec_crypto_vshasigmad +#define __builtin_crypto_vshasigmaw __builtin_altivec_crypto_vshasigmaw + +#define vec_shasigma_be(X, Y, Z) \ + _Generic((X), vector unsigned int: __builtin_crypto_vshasigmaw, \ + vector unsigned long long: __builtin_crypto_vshasigmad) \ +((X), (Y), (Z)) +#endif + +#ifdef __POWER8_VECTOR__ +static vector unsigned char __ATTRS_o_ai +__builtin_crypto_vpermxor(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return __builtin_altivec_crypto_vpermxor(__a, __b, __c); +} + +static vector unsigned short __ATTRS_o_ai +__builtin_crypto_vpermxor(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c) { + return (vector unsigned short)__builtin_altivec_crypto_vpermxor( + (vector unsigned char)__a, (vector unsigned char)__b, + (vector unsigned char)__c); +} + +static vector unsigned int __ATTRS_o_ai __builtin_crypto_vpermxor( + vector unsigned int __a, vector unsigned int __b, vector unsigned int __c) { + return (vector unsigned int)__builtin_altivec_crypto_vpermxor( + (vector unsigned char)__a, (vector unsigned char)__b, + (vector unsigned char)__c); +} + +static vector unsigned long long __ATTRS_o_ai __builtin_crypto_vpermxor( + vector unsigned long long __a, vector unsigned long long __b, + vector unsigned long long __c) { + return (vector unsigned long long)__builtin_altivec_crypto_vpermxor( + (vector unsigned char)__a, (vector unsigned char)__b, + (vector unsigned char)__c); +} + +static vector unsigned char __ATTRS_o_ai +__builtin_crypto_vpmsumb(vector unsigned char __a, vector unsigned char __b) { + return __builtin_altivec_crypto_vpmsumb(__a, __b); +} + +static vector unsigned short __ATTRS_o_ai +__builtin_crypto_vpmsumb(vector unsigned short __a, vector unsigned short __b) { + return __builtin_altivec_crypto_vpmsumh(__a, __b); +} + +static vector unsigned int __ATTRS_o_ai +__builtin_crypto_vpmsumb(vector unsigned int __a, vector unsigned int __b) { + return __builtin_altivec_crypto_vpmsumw(__a, __b); +} + +static vector unsigned long long __ATTRS_o_ai +__builtin_crypto_vpmsumb(vector unsigned long long __a, + vector unsigned long long __b) { + return __builtin_altivec_crypto_vpmsumd(__a, __b); +} + +static vector signed char __ATTRS_o_ai vec_vgbbd (vector signed char __a) +{ + return __builtin_altivec_vgbbd((vector unsigned char) __a); +} + +#define vec_pmsum_be __builtin_crypto_vpmsumb +#define vec_gb __builtin_altivec_vgbbd + +static vector unsigned char __ATTRS_o_ai vec_vgbbd (vector unsigned char __a) +{ + return __builtin_altivec_vgbbd(__a); +} + +static vector long long __ATTRS_o_ai +vec_vbpermq (vector signed char __a, vector signed char __b) +{ + return __builtin_altivec_vbpermq((vector unsigned char) __a, + (vector unsigned char) __b); +} + +static vector long long __ATTRS_o_ai +vec_vbpermq (vector unsigned char __a, vector unsigned char __b) +{ + return __builtin_altivec_vbpermq(__a, __b); +} + +#ifdef __powerpc64__ +static vector unsigned long long __attribute__((__always_inline__)) +vec_bperm (vector unsigned __int128 __a, vector unsigned char __b) { + return __builtin_altivec_vbpermq((vector unsigned char) __a, + (vector unsigned char) __b); +} +#endif +#endif + +#undef __ATTRS_o_ai + +#endif /* __ALTIVEC_H */ diff --git a/headers/clang/ammintrin.h b/headers/clang/ammintrin.h new file mode 100644 index 0000000000..4880fd7eba --- /dev/null +++ b/headers/clang/ammintrin.h @@ -0,0 +1,209 @@ +/*===---- ammintrin.h - SSE4a intrinsics -----------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __AMMINTRIN_H +#define __AMMINTRIN_H + +#include + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("sse4a"))) + +/// \brief Extracts the specified bits from the lower 64 bits of the 128-bit +/// integer vector operand at the index idx and of the length len. +/// +/// \headerfile +/// +/// \code +/// __m128i _mm_extracti_si64(__m128i x, const int len, const int idx); +/// \endcode +/// +/// \code +/// This intrinsic corresponds to the \c EXTRQ instruction. +/// \endcode +/// +/// \param x +/// The value from which bits are extracted. +/// \param len +/// Bits [5:0] specify the length; the other bits are ignored. If bits [5:0] +/// are zero, the length is interpreted as 64. +/// \param idx +/// Bits [5:0] specify the index of the least significant bit; the other +/// bits are ignored. If the sum of the index and length is greater than +/// 64, the result is undefined. If the length and index are both zero, +/// bits [63:0] of parameter x are extracted. If the length is zero +/// but the index is non-zero, the result is undefined. +/// \returns A 128-bit integer vector whose lower 64 bits contain the bits +/// extracted from the source operand. +#define _mm_extracti_si64(x, len, idx) \ + ((__m128i)__builtin_ia32_extrqi((__v2di)(__m128i)(x), \ + (char)(len), (char)(idx))) + +/// \brief Extracts the specified bits from the lower 64 bits of the 128-bit +/// integer vector operand at the index and of the length specified by __y. +/// +/// \headerfile +/// +/// \code +/// This intrinsic corresponds to the \c EXTRQ instruction. +/// \endcode +/// +/// \param __x +/// The value from which bits are extracted. +/// \param __y +/// Specifies the index of the least significant bit at [13:8] +/// and the length at [5:0]; all other bits are ignored. +/// If bits [5:0] are zero, the length is interpreted as 64. +/// If the sum of the index and length is greater than 64, the result is +/// undefined. If the length and index are both zero, bits [63:0] of +/// parameter __x are extracted. If the length is zero but the index is +/// non-zero, the result is undefined. +/// \returns A 128-bit vector whose lower 64 bits contain the bits extracted +/// from the source operand. +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_extract_si64(__m128i __x, __m128i __y) +{ + return (__m128i)__builtin_ia32_extrq((__v2di)__x, (__v16qi)__y); +} + +/// \brief Inserts bits of a specified length from the source integer vector +/// y into the lower 64 bits of the destination integer vector x at the +/// index idx and of the length len. +/// +/// \headerfile +/// +/// \code +/// __m128i _mm_inserti_si64(__m128i x, __m128i y, const int len, +/// const int idx); +/// \endcode +/// +/// \code +/// This intrinsic corresponds to the \c INSERTQ instruction. +/// \endcode +/// +/// \param x +/// The destination operand where bits will be inserted. The inserted bits +/// are defined by the length len and by the index idx specifying the least +/// significant bit. +/// \param y +/// The source operand containing the bits to be extracted. The extracted +/// bits are the least significant bits of operand y of length len. +/// \param len +/// Bits [5:0] specify the length; the other bits are ignored. If bits [5:0] +/// are zero, the length is interpreted as 64. +/// \param idx +/// Bits [5:0] specify the index of the least significant bit; the other +/// bits are ignored. If the sum of the index and length is greater than +/// 64, the result is undefined. If the length and index are both zero, +/// bits [63:0] of parameter y are inserted into parameter x. If the +/// length is zero but the index is non-zero, the result is undefined. +/// \returns A 128-bit integer vector containing the original lower 64-bits +/// of destination operand x with the specified bitfields replaced by the +/// lower bits of source operand y. The upper 64 bits of the return value +/// are undefined. + +#define _mm_inserti_si64(x, y, len, idx) \ + ((__m128i)__builtin_ia32_insertqi((__v2di)(__m128i)(x), \ + (__v2di)(__m128i)(y), \ + (char)(len), (char)(idx))) + +/// \brief Inserts bits of a specified length from the source integer vector +/// __y into the lower 64 bits of the destination integer vector __x at +/// the index and of the length specified by __y. +/// +/// \headerfile +/// +/// \code +/// This intrinsic corresponds to the \c INSERTQ instruction. +/// \endcode +/// +/// \param __x +/// The destination operand where bits will be inserted. The inserted bits +/// are defined by the length and by the index of the least significant bit +/// specified by operand __y. +/// \param __y +/// The source operand containing the bits to be extracted. The extracted +/// bits are the least significant bits of operand __y with length specified +/// by bits [69:64]. These are inserted into the destination at the index +/// specified by bits [77:72]; all other bits are ignored. +/// If bits [69:64] are zero, the length is interpreted as 64. +/// If the sum of the index and length is greater than 64, the result is +/// undefined. If the length and index are both zero, bits [63:0] of +/// parameter __y are inserted into parameter __x. If the length +/// is zero but the index is non-zero, the result is undefined. +/// \returns A 128-bit integer vector containing the original lower 64-bits +/// of destination operand __x with the specified bitfields replaced by the +/// lower bits of source operand __y. The upper 64 bits of the return value +/// are undefined. + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_insert_si64(__m128i __x, __m128i __y) +{ + return (__m128i)__builtin_ia32_insertq((__v2di)__x, (__v2di)__y); +} + +/// \brief Stores a 64-bit double-precision value in a 64-bit memory location. +/// To minimize caching, the data is flagged as non-temporal (unlikely to be +/// used again soon). +/// +/// \headerfile +/// +/// \code +/// This intrinsic corresponds to the \c MOVNTSD instruction. +/// \endcode +/// +/// \param __p +/// The 64-bit memory location used to store the register value. +/// \param __a +/// The 64-bit double-precision floating-point register value to +/// be stored. +static __inline__ void __DEFAULT_FN_ATTRS +_mm_stream_sd(double *__p, __m128d __a) +{ + __builtin_ia32_movntsd(__p, (__v2df)__a); +} + +/// \brief Stores a 32-bit single-precision floating-point value in a 32-bit +/// memory location. To minimize caching, the data is flagged as +/// non-temporal (unlikely to be used again soon). +/// +/// \headerfile +/// +/// \code +/// This intrinsic corresponds to the \c MOVNTSS instruction. +/// \endcode +/// +/// \param __p +/// The 32-bit memory location used to store the register value. +/// \param __a +/// The 32-bit single-precision floating-point register value to +/// be stored. +static __inline__ void __DEFAULT_FN_ATTRS +_mm_stream_ss(float *__p, __m128 __a) +{ + __builtin_ia32_movntss(__p, (__v4sf)__a); +} + +#undef __DEFAULT_FN_ATTRS + +#endif /* __AMMINTRIN_H */ diff --git a/headers/clang/arm_acle.h b/headers/clang/arm_acle.h new file mode 100644 index 0000000000..73a7e76ce3 --- /dev/null +++ b/headers/clang/arm_acle.h @@ -0,0 +1,304 @@ +/*===---- arm_acle.h - ARM Non-Neon intrinsics -----------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __ARM_ACLE_H +#define __ARM_ACLE_H + +#ifndef __ARM_ACLE +#error "ACLE intrinsics support not enabled." +#endif + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */ +/* 8.3 Memory barriers */ +#if !defined(_MSC_VER) +#define __dmb(i) __builtin_arm_dmb(i) +#define __dsb(i) __builtin_arm_dsb(i) +#define __isb(i) __builtin_arm_isb(i) +#endif + +/* 8.4 Hints */ + +#if !defined(_MSC_VER) +static __inline__ void __attribute__((__always_inline__, __nodebug__)) __wfi(void) { + __builtin_arm_wfi(); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) __wfe(void) { + __builtin_arm_wfe(); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) __sev(void) { + __builtin_arm_sev(); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) __sevl(void) { + __builtin_arm_sevl(); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) __yield(void) { + __builtin_arm_yield(); +} +#endif + +#if __ARM_32BIT_STATE +#define __dbg(t) __builtin_arm_dbg(t) +#endif + +/* 8.5 Swap */ +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) + __swp(uint32_t x, volatile uint32_t *p) { + uint32_t v; + do v = __builtin_arm_ldrex(p); while (__builtin_arm_strex(x, p)); + return v; +} + +/* 8.6 Memory prefetch intrinsics */ +/* 8.6.1 Data prefetch */ +#define __pld(addr) __pldx(0, 0, 0, addr) + +#if __ARM_32BIT_STATE +#define __pldx(access_kind, cache_level, retention_policy, addr) \ + __builtin_arm_prefetch(addr, access_kind, 1) +#else +#define __pldx(access_kind, cache_level, retention_policy, addr) \ + __builtin_arm_prefetch(addr, access_kind, cache_level, retention_policy, 1) +#endif + +/* 8.6.2 Instruction prefetch */ +#define __pli(addr) __plix(0, 0, addr) + +#if __ARM_32BIT_STATE +#define __plix(cache_level, retention_policy, addr) \ + __builtin_arm_prefetch(addr, 0, 0) +#else +#define __plix(cache_level, retention_policy, addr) \ + __builtin_arm_prefetch(addr, 0, cache_level, retention_policy, 0) +#endif + +/* 8.7 NOP */ +static __inline__ void __attribute__((__always_inline__, __nodebug__)) __nop(void) { + __builtin_arm_nop(); +} + +/* 9 DATA-PROCESSING INTRINSICS */ +/* 9.2 Miscellaneous data-processing intrinsics */ +/* ROR */ +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) + __ror(uint32_t x, uint32_t y) { + y %= 32; + if (y == 0) return x; + return (x >> y) | (x << (32 - y)); +} + +static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__)) + __rorll(uint64_t x, uint32_t y) { + y %= 64; + if (y == 0) return x; + return (x >> y) | (x << (64 - y)); +} + +static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__)) + __rorl(unsigned long x, uint32_t y) { +#if __SIZEOF_LONG__ == 4 + return __ror(x, y); +#else + return __rorll(x, y); +#endif +} + + +/* CLZ */ +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) + __clz(uint32_t t) { + return __builtin_clz(t); +} + +static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__)) + __clzl(unsigned long t) { + return __builtin_clzl(t); +} + +static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__)) + __clzll(uint64_t t) { + return __builtin_clzll(t); +} + +/* REV */ +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) + __rev(uint32_t t) { + return __builtin_bswap32(t); +} + +static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__)) + __revl(unsigned long t) { +#if __SIZEOF_LONG__ == 4 + return __builtin_bswap32(t); +#else + return __builtin_bswap64(t); +#endif +} + +static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__)) + __revll(uint64_t t) { + return __builtin_bswap64(t); +} + +/* REV16 */ +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) + __rev16(uint32_t t) { + return __ror(__rev(t), 16); +} + +static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__)) + __rev16l(unsigned long t) { + return __rorl(__revl(t), sizeof(long) / 2); +} + +static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__)) + __rev16ll(uint64_t t) { + return __rorll(__revll(t), 32); +} + +/* REVSH */ +static __inline__ int16_t __attribute__((__always_inline__, __nodebug__)) + __revsh(int16_t t) { + return __builtin_bswap16(t); +} + +/* RBIT */ +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) + __rbit(uint32_t t) { + return __builtin_arm_rbit(t); +} + +static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__)) + __rbitll(uint64_t t) { +#if __ARM_32BIT_STATE + return (((uint64_t) __builtin_arm_rbit(t)) << 32) | + __builtin_arm_rbit(t >> 32); +#else + return __builtin_arm_rbit64(t); +#endif +} + +static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__)) + __rbitl(unsigned long t) { +#if __SIZEOF_LONG__ == 4 + return __rbit(t); +#else + return __rbitll(t); +#endif +} + +/* + * 9.4 Saturating intrinsics + * + * FIXME: Change guard to their corrosponding __ARM_FEATURE flag when Q flag + * intrinsics are implemented and the flag is enabled. + */ +/* 9.4.1 Width-specified saturation intrinsics */ +#if __ARM_32BIT_STATE +#define __ssat(x, y) __builtin_arm_ssat(x, y) +#define __usat(x, y) __builtin_arm_usat(x, y) +#endif + +/* 9.4.2 Saturating addition and subtraction intrinsics */ +#if __ARM_32BIT_STATE +static __inline__ int32_t __attribute__((__always_inline__, __nodebug__)) + __qadd(int32_t t, int32_t v) { + return __builtin_arm_qadd(t, v); +} + +static __inline__ int32_t __attribute__((__always_inline__, __nodebug__)) + __qsub(int32_t t, int32_t v) { + return __builtin_arm_qsub(t, v); +} + +static __inline__ int32_t __attribute__((__always_inline__, __nodebug__)) +__qdbl(int32_t t) { + return __builtin_arm_qadd(t, t); +} +#endif + +/* 9.7 CRC32 intrinsics */ +#if __ARM_FEATURE_CRC32 +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) + __crc32b(uint32_t a, uint8_t b) { + return __builtin_arm_crc32b(a, b); +} + +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) + __crc32h(uint32_t a, uint16_t b) { + return __builtin_arm_crc32h(a, b); +} + +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) + __crc32w(uint32_t a, uint32_t b) { + return __builtin_arm_crc32w(a, b); +} + +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) + __crc32d(uint32_t a, uint64_t b) { + return __builtin_arm_crc32d(a, b); +} + +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) + __crc32cb(uint32_t a, uint8_t b) { + return __builtin_arm_crc32cb(a, b); +} + +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) + __crc32ch(uint32_t a, uint16_t b) { + return __builtin_arm_crc32ch(a, b); +} + +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) + __crc32cw(uint32_t a, uint32_t b) { + return __builtin_arm_crc32cw(a, b); +} + +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) + __crc32cd(uint32_t a, uint64_t b) { + return __builtin_arm_crc32cd(a, b); +} +#endif + +/* 10.1 Special register intrinsics */ +#define __arm_rsr(sysreg) __builtin_arm_rsr(sysreg) +#define __arm_rsr64(sysreg) __builtin_arm_rsr64(sysreg) +#define __arm_rsrp(sysreg) __builtin_arm_rsrp(sysreg) +#define __arm_wsr(sysreg, v) __builtin_arm_wsr(sysreg, v) +#define __arm_wsr64(sysreg, v) __builtin_arm_wsr64(sysreg, v) +#define __arm_wsrp(sysreg, v) __builtin_arm_wsrp(sysreg, v) + +#if defined(__cplusplus) +} +#endif + +#endif /* __ARM_ACLE_H */ diff --git a/headers/clang/avx2intrin.h b/headers/clang/avx2intrin.h new file mode 100644 index 0000000000..b2a92f12b0 --- /dev/null +++ b/headers/clang/avx2intrin.h @@ -0,0 +1,1258 @@ +/*===---- avx2intrin.h - AVX2 intrinsics -----------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __AVX2INTRIN_H +#define __AVX2INTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx2"))) + +/* SSE4 Multiple Packed Sums of Absolute Difference. */ +#define _mm256_mpsadbw_epu8(X, Y, M) __builtin_ia32_mpsadbw256((X), (Y), (M)) + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_abs_epi8(__m256i __a) +{ + return (__m256i)__builtin_ia32_pabsb256((__v32qi)__a); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_abs_epi16(__m256i __a) +{ + return (__m256i)__builtin_ia32_pabsw256((__v16hi)__a); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_abs_epi32(__m256i __a) +{ + return (__m256i)__builtin_ia32_pabsd256((__v8si)__a); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_packs_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_packsswb256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_packs_epi32(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_packssdw256((__v8si)__a, (__v8si)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_packus_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_packuswb256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_packus_epi32(__m256i __V1, __m256i __V2) +{ + return (__m256i) __builtin_ia32_packusdw256((__v8si)__V1, (__v8si)__V2); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_add_epi8(__m256i __a, __m256i __b) +{ + return (__m256i)((__v32qi)__a + (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_add_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)((__v16hi)__a + (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_add_epi32(__m256i __a, __m256i __b) +{ + return (__m256i)((__v8si)__a + (__v8si)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_add_epi64(__m256i __a, __m256i __b) +{ + return __a + __b; +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_adds_epi8(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_paddsb256((__v32qi)__a, (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_adds_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_paddsw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_adds_epu8(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_paddusb256((__v32qi)__a, (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_adds_epu16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_paddusw256((__v16hi)__a, (__v16hi)__b); +} + +#define _mm256_alignr_epi8(a, b, n) __extension__ ({ \ + __m256i __a = (a); \ + __m256i __b = (b); \ + (__m256i)__builtin_ia32_palignr256((__v32qi)__a, (__v32qi)__b, (n)); }) + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_and_si256(__m256i __a, __m256i __b) +{ + return __a & __b; +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_andnot_si256(__m256i __a, __m256i __b) +{ + return ~__a & __b; +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_avg_epu8(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pavgb256((__v32qi)__a, (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_avg_epu16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pavgw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_blendv_epi8(__m256i __V1, __m256i __V2, __m256i __M) +{ + return (__m256i)__builtin_ia32_pblendvb256((__v32qi)__V1, (__v32qi)__V2, + (__v32qi)__M); +} + +#define _mm256_blend_epi16(V1, V2, M) __extension__ ({ \ + __m256i __V1 = (V1); \ + __m256i __V2 = (V2); \ + (__m256i)__builtin_shufflevector((__v16hi)__V1, (__v16hi)__V2, \ + (((M) & 0x01) ? 16 : 0), \ + (((M) & 0x02) ? 17 : 1), \ + (((M) & 0x04) ? 18 : 2), \ + (((M) & 0x08) ? 19 : 3), \ + (((M) & 0x10) ? 20 : 4), \ + (((M) & 0x20) ? 21 : 5), \ + (((M) & 0x40) ? 22 : 6), \ + (((M) & 0x80) ? 23 : 7), \ + (((M) & 0x01) ? 24 : 8), \ + (((M) & 0x02) ? 25 : 9), \ + (((M) & 0x04) ? 26 : 10), \ + (((M) & 0x08) ? 27 : 11), \ + (((M) & 0x10) ? 28 : 12), \ + (((M) & 0x20) ? 29 : 13), \ + (((M) & 0x40) ? 30 : 14), \ + (((M) & 0x80) ? 31 : 15)); }) + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cmpeq_epi8(__m256i __a, __m256i __b) +{ + return (__m256i)((__v32qi)__a == (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cmpeq_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)((__v16hi)__a == (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cmpeq_epi32(__m256i __a, __m256i __b) +{ + return (__m256i)((__v8si)__a == (__v8si)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cmpeq_epi64(__m256i __a, __m256i __b) +{ + return (__m256i)(__a == __b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cmpgt_epi8(__m256i __a, __m256i __b) +{ + /* This function always performs a signed comparison, but __v32qi is a char + which may be signed or unsigned, so use __v32qs. */ + return (__m256i)((__v32qs)__a > (__v32qs)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cmpgt_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)((__v16hi)__a > (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cmpgt_epi32(__m256i __a, __m256i __b) +{ + return (__m256i)((__v8si)__a > (__v8si)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cmpgt_epi64(__m256i __a, __m256i __b) +{ + return (__m256i)(__a > __b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_hadd_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_phaddw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_hadd_epi32(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_phaddd256((__v8si)__a, (__v8si)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_hadds_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_phaddsw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_hsub_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_phsubw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_hsub_epi32(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_phsubd256((__v8si)__a, (__v8si)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_hsubs_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_phsubsw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maddubs_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pmaddubsw256((__v32qi)__a, (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_madd_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pmaddwd256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_max_epi8(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pmaxsb256((__v32qi)__a, (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_max_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pmaxsw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_max_epi32(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pmaxsd256((__v8si)__a, (__v8si)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_max_epu8(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pmaxub256((__v32qi)__a, (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_max_epu16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pmaxuw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_max_epu32(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pmaxud256((__v8si)__a, (__v8si)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_min_epi8(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pminsb256((__v32qi)__a, (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_min_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pminsw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_min_epi32(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pminsd256((__v8si)__a, (__v8si)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_min_epu8(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pminub256((__v32qi)__a, (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_min_epu16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pminuw256 ((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_min_epu32(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pminud256((__v8si)__a, (__v8si)__b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm256_movemask_epi8(__m256i __a) +{ + return __builtin_ia32_pmovmskb256((__v32qi)__a); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtepi8_epi16(__m128i __V) +{ + return (__m256i)__builtin_ia32_pmovsxbw256((__v16qi)__V); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtepi8_epi32(__m128i __V) +{ + return (__m256i)__builtin_ia32_pmovsxbd256((__v16qi)__V); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtepi8_epi64(__m128i __V) +{ + return (__m256i)__builtin_ia32_pmovsxbq256((__v16qi)__V); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtepi16_epi32(__m128i __V) +{ + return (__m256i)__builtin_ia32_pmovsxwd256((__v8hi)__V); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtepi16_epi64(__m128i __V) +{ + return (__m256i)__builtin_ia32_pmovsxwq256((__v8hi)__V); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtepi32_epi64(__m128i __V) +{ + return (__m256i)__builtin_ia32_pmovsxdq256((__v4si)__V); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtepu8_epi16(__m128i __V) +{ + return (__m256i)__builtin_ia32_pmovzxbw256((__v16qi)__V); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtepu8_epi32(__m128i __V) +{ + return (__m256i)__builtin_ia32_pmovzxbd256((__v16qi)__V); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtepu8_epi64(__m128i __V) +{ + return (__m256i)__builtin_ia32_pmovzxbq256((__v16qi)__V); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtepu16_epi32(__m128i __V) +{ + return (__m256i)__builtin_ia32_pmovzxwd256((__v8hi)__V); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtepu16_epi64(__m128i __V) +{ + return (__m256i)__builtin_ia32_pmovzxwq256((__v8hi)__V); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtepu32_epi64(__m128i __V) +{ + return (__m256i)__builtin_ia32_pmovzxdq256((__v4si)__V); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mul_epi32(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pmuldq256((__v8si)__a, (__v8si)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mulhrs_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pmulhrsw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mulhi_epu16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pmulhuw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mulhi_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pmulhw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mullo_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)((__v16hi)__a * (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mullo_epi32 (__m256i __a, __m256i __b) +{ + return (__m256i)((__v8si)__a * (__v8si)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mul_epu32(__m256i __a, __m256i __b) +{ + return __builtin_ia32_pmuludq256((__v8si)__a, (__v8si)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_or_si256(__m256i __a, __m256i __b) +{ + return __a | __b; +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sad_epu8(__m256i __a, __m256i __b) +{ + return __builtin_ia32_psadbw256((__v32qi)__a, (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_shuffle_epi8(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_pshufb256((__v32qi)__a, (__v32qi)__b); +} + +#define _mm256_shuffle_epi32(a, imm) __extension__ ({ \ + __m256i __a = (a); \ + (__m256i)__builtin_shufflevector((__v8si)__a, (__v8si)_mm256_set1_epi32(0), \ + (imm) & 0x3, ((imm) & 0xc) >> 2, \ + ((imm) & 0x30) >> 4, ((imm) & 0xc0) >> 6, \ + 4 + (((imm) & 0x03) >> 0), \ + 4 + (((imm) & 0x0c) >> 2), \ + 4 + (((imm) & 0x30) >> 4), \ + 4 + (((imm) & 0xc0) >> 6)); }) + +#define _mm256_shufflehi_epi16(a, imm) __extension__ ({ \ + __m256i __a = (a); \ + (__m256i)__builtin_shufflevector((__v16hi)__a, (__v16hi)_mm256_set1_epi16(0), \ + 0, 1, 2, 3, \ + 4 + (((imm) & 0x03) >> 0), \ + 4 + (((imm) & 0x0c) >> 2), \ + 4 + (((imm) & 0x30) >> 4), \ + 4 + (((imm) & 0xc0) >> 6), \ + 8, 9, 10, 11, \ + 12 + (((imm) & 0x03) >> 0), \ + 12 + (((imm) & 0x0c) >> 2), \ + 12 + (((imm) & 0x30) >> 4), \ + 12 + (((imm) & 0xc0) >> 6)); }) + +#define _mm256_shufflelo_epi16(a, imm) __extension__ ({ \ + __m256i __a = (a); \ + (__m256i)__builtin_shufflevector((__v16hi)__a, (__v16hi)_mm256_set1_epi16(0), \ + (imm) & 0x3,((imm) & 0xc) >> 2, \ + ((imm) & 0x30) >> 4, ((imm) & 0xc0) >> 6, \ + 4, 5, 6, 7, \ + 8 + (((imm) & 0x03) >> 0), \ + 8 + (((imm) & 0x0c) >> 2), \ + 8 + (((imm) & 0x30) >> 4), \ + 8 + (((imm) & 0xc0) >> 6), \ + 12, 13, 14, 15); }) + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sign_epi8(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_psignb256((__v32qi)__a, (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sign_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_psignw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sign_epi32(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_psignd256((__v8si)__a, (__v8si)__b); +} + +#define _mm256_slli_si256(a, count) __extension__ ({ \ + __m256i __a = (a); \ + (__m256i)__builtin_ia32_pslldqi256(__a, (count)*8); }) + +#define _mm256_bslli_epi128(a, count) _mm256_slli_si256((a), (count)) + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_slli_epi16(__m256i __a, int __count) +{ + return (__m256i)__builtin_ia32_psllwi256((__v16hi)__a, __count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sll_epi16(__m256i __a, __m128i __count) +{ + return (__m256i)__builtin_ia32_psllw256((__v16hi)__a, (__v8hi)__count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_slli_epi32(__m256i __a, int __count) +{ + return (__m256i)__builtin_ia32_pslldi256((__v8si)__a, __count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sll_epi32(__m256i __a, __m128i __count) +{ + return (__m256i)__builtin_ia32_pslld256((__v8si)__a, (__v4si)__count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_slli_epi64(__m256i __a, int __count) +{ + return __builtin_ia32_psllqi256(__a, __count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sll_epi64(__m256i __a, __m128i __count) +{ + return __builtin_ia32_psllq256(__a, __count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_srai_epi16(__m256i __a, int __count) +{ + return (__m256i)__builtin_ia32_psrawi256((__v16hi)__a, __count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sra_epi16(__m256i __a, __m128i __count) +{ + return (__m256i)__builtin_ia32_psraw256((__v16hi)__a, (__v8hi)__count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_srai_epi32(__m256i __a, int __count) +{ + return (__m256i)__builtin_ia32_psradi256((__v8si)__a, __count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sra_epi32(__m256i __a, __m128i __count) +{ + return (__m256i)__builtin_ia32_psrad256((__v8si)__a, (__v4si)__count); +} + +#define _mm256_srli_si256(a, count) __extension__ ({ \ + __m256i __a = (a); \ + (__m256i)__builtin_ia32_psrldqi256(__a, (count)*8); }) + +#define _mm256_bsrli_epi128(a, count) _mm256_srli_si256((a), (count)) + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_srli_epi16(__m256i __a, int __count) +{ + return (__m256i)__builtin_ia32_psrlwi256((__v16hi)__a, __count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_srl_epi16(__m256i __a, __m128i __count) +{ + return (__m256i)__builtin_ia32_psrlw256((__v16hi)__a, (__v8hi)__count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_srli_epi32(__m256i __a, int __count) +{ + return (__m256i)__builtin_ia32_psrldi256((__v8si)__a, __count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_srl_epi32(__m256i __a, __m128i __count) +{ + return (__m256i)__builtin_ia32_psrld256((__v8si)__a, (__v4si)__count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_srli_epi64(__m256i __a, int __count) +{ + return __builtin_ia32_psrlqi256(__a, __count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_srl_epi64(__m256i __a, __m128i __count) +{ + return __builtin_ia32_psrlq256(__a, __count); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sub_epi8(__m256i __a, __m256i __b) +{ + return (__m256i)((__v32qi)__a - (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sub_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)((__v16hi)__a - (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sub_epi32(__m256i __a, __m256i __b) +{ + return (__m256i)((__v8si)__a - (__v8si)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sub_epi64(__m256i __a, __m256i __b) +{ + return __a - __b; +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_subs_epi8(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_psubsb256((__v32qi)__a, (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_subs_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_psubsw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_subs_epu8(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_psubusb256((__v32qi)__a, (__v32qi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_subs_epu16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_psubusw256((__v16hi)__a, (__v16hi)__b); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_unpackhi_epi8(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_shufflevector((__v32qi)__a, (__v32qi)__b, 8, 32+8, 9, 32+9, 10, 32+10, 11, 32+11, 12, 32+12, 13, 32+13, 14, 32+14, 15, 32+15, 24, 32+24, 25, 32+25, 26, 32+26, 27, 32+27, 28, 32+28, 29, 32+29, 30, 32+30, 31, 32+31); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_unpackhi_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_shufflevector((__v16hi)__a, (__v16hi)__b, 4, 16+4, 5, 16+5, 6, 16+6, 7, 16+7, 12, 16+12, 13, 16+13, 14, 16+14, 15, 16+15); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_unpackhi_epi32(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_shufflevector((__v8si)__a, (__v8si)__b, 2, 8+2, 3, 8+3, 6, 8+6, 7, 8+7); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_unpackhi_epi64(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_shufflevector(__a, __b, 1, 4+1, 3, 4+3); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_unpacklo_epi8(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_shufflevector((__v32qi)__a, (__v32qi)__b, 0, 32+0, 1, 32+1, 2, 32+2, 3, 32+3, 4, 32+4, 5, 32+5, 6, 32+6, 7, 32+7, 16, 32+16, 17, 32+17, 18, 32+18, 19, 32+19, 20, 32+20, 21, 32+21, 22, 32+22, 23, 32+23); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_unpacklo_epi16(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_shufflevector((__v16hi)__a, (__v16hi)__b, 0, 16+0, 1, 16+1, 2, 16+2, 3, 16+3, 8, 16+8, 9, 16+9, 10, 16+10, 11, 16+11); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_unpacklo_epi32(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_shufflevector((__v8si)__a, (__v8si)__b, 0, 8+0, 1, 8+1, 4, 8+4, 5, 8+5); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_unpacklo_epi64(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_shufflevector(__a, __b, 0, 4+0, 2, 4+2); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_xor_si256(__m256i __a, __m256i __b) +{ + return __a ^ __b; +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_stream_load_si256(__m256i const *__V) +{ + return (__m256i)__builtin_ia32_movntdqa256((const __v4di *)__V); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_broadcastss_ps(__m128 __X) +{ + return (__m128)__builtin_shufflevector((__v4sf)__X, (__v4sf)__X, 0, 0, 0, 0); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_broadcastsd_pd(__m128d __a) +{ + return __builtin_shufflevector(__a, __a, 0, 0); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_broadcastss_ps(__m128 __X) +{ + return (__m256)__builtin_shufflevector((__v4sf)__X, (__v4sf)__X, 0, 0, 0, 0, 0, 0, 0, 0); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_broadcastsd_pd(__m128d __X) +{ + return (__m256d)__builtin_shufflevector((__v2df)__X, (__v2df)__X, 0, 0, 0, 0); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_broadcastsi128_si256(__m128i __X) +{ + return (__m256i)__builtin_shufflevector(__X, __X, 0, 1, 0, 1); +} + +#define _mm_blend_epi32(V1, V2, M) __extension__ ({ \ + __m128i __V1 = (V1); \ + __m128i __V2 = (V2); \ + (__m128i)__builtin_shufflevector((__v4si)__V1, (__v4si)__V2, \ + (((M) & 0x01) ? 4 : 0), \ + (((M) & 0x02) ? 5 : 1), \ + (((M) & 0x04) ? 6 : 2), \ + (((M) & 0x08) ? 7 : 3)); }) + +#define _mm256_blend_epi32(V1, V2, M) __extension__ ({ \ + __m256i __V1 = (V1); \ + __m256i __V2 = (V2); \ + (__m256i)__builtin_shufflevector((__v8si)__V1, (__v8si)__V2, \ + (((M) & 0x01) ? 8 : 0), \ + (((M) & 0x02) ? 9 : 1), \ + (((M) & 0x04) ? 10 : 2), \ + (((M) & 0x08) ? 11 : 3), \ + (((M) & 0x10) ? 12 : 4), \ + (((M) & 0x20) ? 13 : 5), \ + (((M) & 0x40) ? 14 : 6), \ + (((M) & 0x80) ? 15 : 7)); }) + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_broadcastb_epi8(__m128i __X) +{ + return (__m256i)__builtin_shufflevector((__v16qi)__X, (__v16qi)__X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_broadcastw_epi16(__m128i __X) +{ + return (__m256i)__builtin_shufflevector((__v8hi)__X, (__v8hi)__X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_broadcastd_epi32(__m128i __X) +{ + return (__m256i)__builtin_shufflevector((__v4si)__X, (__v4si)__X, 0, 0, 0, 0, 0, 0, 0, 0); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_broadcastq_epi64(__m128i __X) +{ + return (__m256i)__builtin_shufflevector(__X, __X, 0, 0, 0, 0); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_broadcastb_epi8(__m128i __X) +{ + return (__m128i)__builtin_shufflevector((__v16qi)__X, (__v16qi)__X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_broadcastw_epi16(__m128i __X) +{ + return (__m128i)__builtin_shufflevector((__v8hi)__X, (__v8hi)__X, 0, 0, 0, 0, 0, 0, 0, 0); +} + + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_broadcastd_epi32(__m128i __X) +{ + return (__m128i)__builtin_shufflevector((__v4si)__X, (__v4si)__X, 0, 0, 0, 0); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_broadcastq_epi64(__m128i __X) +{ + return (__m128i)__builtin_shufflevector(__X, __X, 0, 0); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_permutevar8x32_epi32(__m256i __a, __m256i __b) +{ + return (__m256i)__builtin_ia32_permvarsi256((__v8si)__a, (__v8si)__b); +} + +#define _mm256_permute4x64_pd(V, M) __extension__ ({ \ + __m256d __V = (V); \ + (__m256d)__builtin_shufflevector((__v4df)__V, (__v4df) _mm256_setzero_pd(), \ + (M) & 0x3, ((M) & 0xc) >> 2, \ + ((M) & 0x30) >> 4, ((M) & 0xc0) >> 6); }) + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_permutevar8x32_ps(__m256 __a, __m256 __b) +{ + return (__m256)__builtin_ia32_permvarsf256((__v8sf)__a, (__v8sf)__b); +} + +#define _mm256_permute4x64_epi64(V, M) __extension__ ({ \ + __m256i __V = (V); \ + (__m256i)__builtin_shufflevector((__v4di)__V, (__v4di) _mm256_setzero_si256(), \ + (M) & 0x3, ((M) & 0xc) >> 2, \ + ((M) & 0x30) >> 4, ((M) & 0xc0) >> 6); }) + +#define _mm256_permute2x128_si256(V1, V2, M) __extension__ ({ \ + __m256i __V1 = (V1); \ + __m256i __V2 = (V2); \ + (__m256i)__builtin_ia32_permti256(__V1, __V2, (M)); }) + +#define _mm256_extracti128_si256(V, M) __extension__ ({ \ + (__m128i)__builtin_shufflevector( \ + (__v4di)(V), \ + (__v4di)(_mm256_setzero_si256()), \ + (((M) & 1) ? 2 : 0), \ + (((M) & 1) ? 3 : 1) );}) + +#define _mm256_inserti128_si256(V1, V2, M) __extension__ ({ \ + (__m256i)__builtin_shufflevector( \ + (__v4di)(V1), \ + (__v4di)_mm256_castsi128_si256((__m128i)(V2)), \ + (((M) & 1) ? 0 : 4), \ + (((M) & 1) ? 1 : 5), \ + (((M) & 1) ? 4 : 2), \ + (((M) & 1) ? 5 : 3) );}) + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskload_epi32(int const *__X, __m256i __M) +{ + return (__m256i)__builtin_ia32_maskloadd256((const __v8si *)__X, (__v8si)__M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskload_epi64(long long const *__X, __m256i __M) +{ + return (__m256i)__builtin_ia32_maskloadq256((const __v4di *)__X, __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskload_epi32(int const *__X, __m128i __M) +{ + return (__m128i)__builtin_ia32_maskloadd((const __v4si *)__X, (__v4si)__M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskload_epi64(long long const *__X, __m128i __M) +{ + return (__m128i)__builtin_ia32_maskloadq((const __v2di *)__X, (__v2di)__M); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm256_maskstore_epi32(int *__X, __m256i __M, __m256i __Y) +{ + __builtin_ia32_maskstored256((__v8si *)__X, (__v8si)__M, (__v8si)__Y); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm256_maskstore_epi64(long long *__X, __m256i __M, __m256i __Y) +{ + __builtin_ia32_maskstoreq256((__v4di *)__X, __M, __Y); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_maskstore_epi32(int *__X, __m128i __M, __m128i __Y) +{ + __builtin_ia32_maskstored((__v4si *)__X, (__v4si)__M, (__v4si)__Y); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_maskstore_epi64(long long *__X, __m128i __M, __m128i __Y) +{ + __builtin_ia32_maskstoreq(( __v2di *)__X, __M, __Y); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sllv_epi32(__m256i __X, __m256i __Y) +{ + return (__m256i)__builtin_ia32_psllv8si((__v8si)__X, (__v8si)__Y); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sllv_epi32(__m128i __X, __m128i __Y) +{ + return (__m128i)__builtin_ia32_psllv4si((__v4si)__X, (__v4si)__Y); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_sllv_epi64(__m256i __X, __m256i __Y) +{ + return (__m256i)__builtin_ia32_psllv4di(__X, __Y); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sllv_epi64(__m128i __X, __m128i __Y) +{ + return (__m128i)__builtin_ia32_psllv2di(__X, __Y); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_srav_epi32(__m256i __X, __m256i __Y) +{ + return (__m256i)__builtin_ia32_psrav8si((__v8si)__X, (__v8si)__Y); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_srav_epi32(__m128i __X, __m128i __Y) +{ + return (__m128i)__builtin_ia32_psrav4si((__v4si)__X, (__v4si)__Y); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_srlv_epi32(__m256i __X, __m256i __Y) +{ + return (__m256i)__builtin_ia32_psrlv8si((__v8si)__X, (__v8si)__Y); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_srlv_epi32(__m128i __X, __m128i __Y) +{ + return (__m128i)__builtin_ia32_psrlv4si((__v4si)__X, (__v4si)__Y); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_srlv_epi64(__m256i __X, __m256i __Y) +{ + return (__m256i)__builtin_ia32_psrlv4di(__X, __Y); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_srlv_epi64(__m128i __X, __m128i __Y) +{ + return (__m128i)__builtin_ia32_psrlv2di(__X, __Y); +} + +#define _mm_mask_i32gather_pd(a, m, i, mask, s) __extension__ ({ \ + __m128d __a = (a); \ + double const *__m = (m); \ + __m128i __i = (i); \ + __m128d __mask = (mask); \ + (__m128d)__builtin_ia32_gatherd_pd((__v2df)__a, (const __v2df *)__m, \ + (__v4si)__i, (__v2df)__mask, (s)); }) + +#define _mm256_mask_i32gather_pd(a, m, i, mask, s) __extension__ ({ \ + __m256d __a = (a); \ + double const *__m = (m); \ + __m128i __i = (i); \ + __m256d __mask = (mask); \ + (__m256d)__builtin_ia32_gatherd_pd256((__v4df)__a, (const __v4df *)__m, \ + (__v4si)__i, (__v4df)__mask, (s)); }) + +#define _mm_mask_i64gather_pd(a, m, i, mask, s) __extension__ ({ \ + __m128d __a = (a); \ + double const *__m = (m); \ + __m128i __i = (i); \ + __m128d __mask = (mask); \ + (__m128d)__builtin_ia32_gatherq_pd((__v2df)__a, (const __v2df *)__m, \ + (__v2di)__i, (__v2df)__mask, (s)); }) + +#define _mm256_mask_i64gather_pd(a, m, i, mask, s) __extension__ ({ \ + __m256d __a = (a); \ + double const *__m = (m); \ + __m256i __i = (i); \ + __m256d __mask = (mask); \ + (__m256d)__builtin_ia32_gatherq_pd256((__v4df)__a, (const __v4df *)__m, \ + (__v4di)__i, (__v4df)__mask, (s)); }) + +#define _mm_mask_i32gather_ps(a, m, i, mask, s) __extension__ ({ \ + __m128 __a = (a); \ + float const *__m = (m); \ + __m128i __i = (i); \ + __m128 __mask = (mask); \ + (__m128)__builtin_ia32_gatherd_ps((__v4sf)__a, (const __v4sf *)__m, \ + (__v4si)__i, (__v4sf)__mask, (s)); }) + +#define _mm256_mask_i32gather_ps(a, m, i, mask, s) __extension__ ({ \ + __m256 __a = (a); \ + float const *__m = (m); \ + __m256i __i = (i); \ + __m256 __mask = (mask); \ + (__m256)__builtin_ia32_gatherd_ps256((__v8sf)__a, (const __v8sf *)__m, \ + (__v8si)__i, (__v8sf)__mask, (s)); }) + +#define _mm_mask_i64gather_ps(a, m, i, mask, s) __extension__ ({ \ + __m128 __a = (a); \ + float const *__m = (m); \ + __m128i __i = (i); \ + __m128 __mask = (mask); \ + (__m128)__builtin_ia32_gatherq_ps((__v4sf)__a, (const __v4sf *)__m, \ + (__v2di)__i, (__v4sf)__mask, (s)); }) + +#define _mm256_mask_i64gather_ps(a, m, i, mask, s) __extension__ ({ \ + __m128 __a = (a); \ + float const *__m = (m); \ + __m256i __i = (i); \ + __m128 __mask = (mask); \ + (__m128)__builtin_ia32_gatherq_ps256((__v4sf)__a, (const __v4sf *)__m, \ + (__v4di)__i, (__v4sf)__mask, (s)); }) + +#define _mm_mask_i32gather_epi32(a, m, i, mask, s) __extension__ ({ \ + __m128i __a = (a); \ + int const *__m = (m); \ + __m128i __i = (i); \ + __m128i __mask = (mask); \ + (__m128i)__builtin_ia32_gatherd_d((__v4si)__a, (const __v4si *)__m, \ + (__v4si)__i, (__v4si)__mask, (s)); }) + +#define _mm256_mask_i32gather_epi32(a, m, i, mask, s) __extension__ ({ \ + __m256i __a = (a); \ + int const *__m = (m); \ + __m256i __i = (i); \ + __m256i __mask = (mask); \ + (__m256i)__builtin_ia32_gatherd_d256((__v8si)__a, (const __v8si *)__m, \ + (__v8si)__i, (__v8si)__mask, (s)); }) + +#define _mm_mask_i64gather_epi32(a, m, i, mask, s) __extension__ ({ \ + __m128i __a = (a); \ + int const *__m = (m); \ + __m128i __i = (i); \ + __m128i __mask = (mask); \ + (__m128i)__builtin_ia32_gatherq_d((__v4si)__a, (const __v4si *)__m, \ + (__v2di)__i, (__v4si)__mask, (s)); }) + +#define _mm256_mask_i64gather_epi32(a, m, i, mask, s) __extension__ ({ \ + __m128i __a = (a); \ + int const *__m = (m); \ + __m256i __i = (i); \ + __m128i __mask = (mask); \ + (__m128i)__builtin_ia32_gatherq_d256((__v4si)__a, (const __v4si *)__m, \ + (__v4di)__i, (__v4si)__mask, (s)); }) + +#define _mm_mask_i32gather_epi64(a, m, i, mask, s) __extension__ ({ \ + __m128i __a = (a); \ + long long const *__m = (m); \ + __m128i __i = (i); \ + __m128i __mask = (mask); \ + (__m128i)__builtin_ia32_gatherd_q((__v2di)__a, (const __v2di *)__m, \ + (__v4si)__i, (__v2di)__mask, (s)); }) + +#define _mm256_mask_i32gather_epi64(a, m, i, mask, s) __extension__ ({ \ + __m256i __a = (a); \ + long long const *__m = (m); \ + __m128i __i = (i); \ + __m256i __mask = (mask); \ + (__m256i)__builtin_ia32_gatherd_q256((__v4di)__a, (const __v4di *)__m, \ + (__v4si)__i, (__v4di)__mask, (s)); }) + +#define _mm_mask_i64gather_epi64(a, m, i, mask, s) __extension__ ({ \ + __m128i __a = (a); \ + long long const *__m = (m); \ + __m128i __i = (i); \ + __m128i __mask = (mask); \ + (__m128i)__builtin_ia32_gatherq_q((__v2di)__a, (const __v2di *)__m, \ + (__v2di)__i, (__v2di)__mask, (s)); }) + +#define _mm256_mask_i64gather_epi64(a, m, i, mask, s) __extension__ ({ \ + __m256i __a = (a); \ + long long const *__m = (m); \ + __m256i __i = (i); \ + __m256i __mask = (mask); \ + (__m256i)__builtin_ia32_gatherq_q256((__v4di)__a, (const __v4di *)__m, \ + (__v4di)__i, (__v4di)__mask, (s)); }) + +#define _mm_i32gather_pd(m, i, s) __extension__ ({ \ + double const *__m = (m); \ + __m128i __i = (i); \ + (__m128d)__builtin_ia32_gatherd_pd((__v2df)_mm_setzero_pd(), \ + (const __v2df *)__m, (__v4si)__i, \ + (__v2df)_mm_set1_pd((double)(long long int)-1), (s)); }) + +#define _mm256_i32gather_pd(m, i, s) __extension__ ({ \ + double const *__m = (m); \ + __m128i __i = (i); \ + (__m256d)__builtin_ia32_gatherd_pd256((__v4df)_mm256_setzero_pd(), \ + (const __v4df *)__m, (__v4si)__i, \ + (__v4df)_mm256_set1_pd((double)(long long int)-1), (s)); }) + +#define _mm_i64gather_pd(m, i, s) __extension__ ({ \ + double const *__m = (m); \ + __m128i __i = (i); \ + (__m128d)__builtin_ia32_gatherq_pd((__v2df)_mm_setzero_pd(), \ + (const __v2df *)__m, (__v2di)__i, \ + (__v2df)_mm_set1_pd((double)(long long int)-1), (s)); }) + +#define _mm256_i64gather_pd(m, i, s) __extension__ ({ \ + double const *__m = (m); \ + __m256i __i = (i); \ + (__m256d)__builtin_ia32_gatherq_pd256((__v4df)_mm256_setzero_pd(), \ + (const __v4df *)__m, (__v4di)__i, \ + (__v4df)_mm256_set1_pd((double)(long long int)-1), (s)); }) + +#define _mm_i32gather_ps(m, i, s) __extension__ ({ \ + float const *__m = (m); \ + __m128i __i = (i); \ + (__m128)__builtin_ia32_gatherd_ps((__v4sf)_mm_setzero_ps(), \ + (const __v4sf *)__m, (__v4si)__i, \ + (__v4sf)_mm_set1_ps((float)(int)-1), (s)); }) + +#define _mm256_i32gather_ps(m, i, s) __extension__ ({ \ + float const *__m = (m); \ + __m256i __i = (i); \ + (__m256)__builtin_ia32_gatherd_ps256((__v8sf)_mm256_setzero_ps(), \ + (const __v8sf *)__m, (__v8si)__i, \ + (__v8sf)_mm256_set1_ps((float)(int)-1), (s)); }) + +#define _mm_i64gather_ps(m, i, s) __extension__ ({ \ + float const *__m = (m); \ + __m128i __i = (i); \ + (__m128)__builtin_ia32_gatherq_ps((__v4sf)_mm_setzero_ps(), \ + (const __v4sf *)__m, (__v2di)__i, \ + (__v4sf)_mm_set1_ps((float)(int)-1), (s)); }) + +#define _mm256_i64gather_ps(m, i, s) __extension__ ({ \ + float const *__m = (m); \ + __m256i __i = (i); \ + (__m128)__builtin_ia32_gatherq_ps256((__v4sf)_mm_setzero_ps(), \ + (const __v4sf *)__m, (__v4di)__i, \ + (__v4sf)_mm_set1_ps((float)(int)-1), (s)); }) + +#define _mm_i32gather_epi32(m, i, s) __extension__ ({ \ + int const *__m = (m); \ + __m128i __i = (i); \ + (__m128i)__builtin_ia32_gatherd_d((__v4si)_mm_setzero_si128(), \ + (const __v4si *)__m, (__v4si)__i, \ + (__v4si)_mm_set1_epi32(-1), (s)); }) + +#define _mm256_i32gather_epi32(m, i, s) __extension__ ({ \ + int const *__m = (m); \ + __m256i __i = (i); \ + (__m256i)__builtin_ia32_gatherd_d256((__v8si)_mm256_setzero_si256(), \ + (const __v8si *)__m, (__v8si)__i, \ + (__v8si)_mm256_set1_epi32(-1), (s)); }) + +#define _mm_i64gather_epi32(m, i, s) __extension__ ({ \ + int const *__m = (m); \ + __m128i __i = (i); \ + (__m128i)__builtin_ia32_gatherq_d((__v4si)_mm_setzero_si128(), \ + (const __v4si *)__m, (__v2di)__i, \ + (__v4si)_mm_set1_epi32(-1), (s)); }) + +#define _mm256_i64gather_epi32(m, i, s) __extension__ ({ \ + int const *__m = (m); \ + __m256i __i = (i); \ + (__m128i)__builtin_ia32_gatherq_d256((__v4si)_mm_setzero_si128(), \ + (const __v4si *)__m, (__v4di)__i, \ + (__v4si)_mm_set1_epi32(-1), (s)); }) + +#define _mm_i32gather_epi64(m, i, s) __extension__ ({ \ + long long const *__m = (m); \ + __m128i __i = (i); \ + (__m128i)__builtin_ia32_gatherd_q((__v2di)_mm_setzero_si128(), \ + (const __v2di *)__m, (__v4si)__i, \ + (__v2di)_mm_set1_epi64x(-1), (s)); }) + +#define _mm256_i32gather_epi64(m, i, s) __extension__ ({ \ + long long const *__m = (m); \ + __m128i __i = (i); \ + (__m256i)__builtin_ia32_gatherd_q256((__v4di)_mm256_setzero_si256(), \ + (const __v4di *)__m, (__v4si)__i, \ + (__v4di)_mm256_set1_epi64x(-1), (s)); }) + +#define _mm_i64gather_epi64(m, i, s) __extension__ ({ \ + long long const *__m = (m); \ + __m128i __i = (i); \ + (__m128i)__builtin_ia32_gatherq_q((__v2di)_mm_setzero_si128(), \ + (const __v2di *)__m, (__v2di)__i, \ + (__v2di)_mm_set1_epi64x(-1), (s)); }) + +#define _mm256_i64gather_epi64(m, i, s) __extension__ ({ \ + long long const *__m = (m); \ + __m256i __i = (i); \ + (__m256i)__builtin_ia32_gatherq_q256((__v4di)_mm256_setzero_si256(), \ + (const __v4di *)__m, (__v4di)__i, \ + (__v4di)_mm256_set1_epi64x(-1), (s)); }) + +#undef __DEFAULT_FN_ATTRS + +#endif /* __AVX2INTRIN_H */ diff --git a/headers/clang/avx512bwintrin.h b/headers/clang/avx512bwintrin.h new file mode 100644 index 0000000000..f289ed71a3 --- /dev/null +++ b/headers/clang/avx512bwintrin.h @@ -0,0 +1,1542 @@ +/*===------------- avx512bwintrin.h - AVX512BW intrinsics ------------------=== + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __AVX512BWINTRIN_H +#define __AVX512BWINTRIN_H + +typedef unsigned int __mmask32; +typedef unsigned long long __mmask64; +typedef char __v64qi __attribute__ ((__vector_size__ (64))); +typedef short __v32hi __attribute__ ((__vector_size__ (64))); + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512bw"))) + +static __inline __v64qi __DEFAULT_FN_ATTRS +_mm512_setzero_qi(void) { + return (__v64qi){ 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; +} + +static __inline __v32hi __DEFAULT_FN_ATTRS +_mm512_setzero_hi(void) { + return (__v32hi){ 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; +} + +/* Integer compare */ + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_cmpeq_epi8_mask(__m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_pcmpeqb512_mask((__v64qi)__a, (__v64qi)__b, + (__mmask64)-1); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_mask_cmpeq_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_pcmpeqb512_mask((__v64qi)__a, (__v64qi)__b, + __u); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_cmpeq_epu8_mask(__m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 0, + (__mmask64)-1); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_mask_cmpeq_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 0, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_cmpeq_epi16_mask(__m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_pcmpeqw512_mask((__v32hi)__a, (__v32hi)__b, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_mask_cmpeq_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_pcmpeqw512_mask((__v32hi)__a, (__v32hi)__b, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_cmpeq_epu16_mask(__m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 0, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_mask_cmpeq_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 0, + __u); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_cmpge_epi8_mask(__m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 5, + (__mmask64)-1); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_mask_cmpge_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 5, + __u); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_cmpge_epu8_mask(__m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 5, + (__mmask64)-1); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_mask_cmpge_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 5, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_cmpge_epi16_mask(__m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 5, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_mask_cmpge_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 5, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_cmpge_epu16_mask(__m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 5, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_mask_cmpge_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 5, + __u); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_cmpgt_epi8_mask(__m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_pcmpgtb512_mask((__v64qi)__a, (__v64qi)__b, + (__mmask64)-1); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_mask_cmpgt_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_pcmpgtb512_mask((__v64qi)__a, (__v64qi)__b, + __u); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_cmpgt_epu8_mask(__m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 6, + (__mmask64)-1); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_mask_cmpgt_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 6, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_cmpgt_epi16_mask(__m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_pcmpgtw512_mask((__v32hi)__a, (__v32hi)__b, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_mask_cmpgt_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_pcmpgtw512_mask((__v32hi)__a, (__v32hi)__b, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_cmpgt_epu16_mask(__m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 6, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_mask_cmpgt_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 6, + __u); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_cmple_epi8_mask(__m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 2, + (__mmask64)-1); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_mask_cmple_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 2, + __u); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_cmple_epu8_mask(__m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 2, + (__mmask64)-1); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_mask_cmple_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 2, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_cmple_epi16_mask(__m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 2, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_mask_cmple_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 2, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_cmple_epu16_mask(__m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 2, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_mask_cmple_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 2, + __u); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_cmplt_epi8_mask(__m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 1, + (__mmask64)-1); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_mask_cmplt_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 1, + __u); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_cmplt_epu8_mask(__m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 1, + (__mmask64)-1); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_mask_cmplt_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 1, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_cmplt_epi16_mask(__m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 1, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_mask_cmplt_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 1, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_cmplt_epu16_mask(__m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 1, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_mask_cmplt_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 1, + __u); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_cmpneq_epi8_mask(__m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 4, + (__mmask64)-1); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_mask_cmpneq_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 4, + __u); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_cmpneq_epu8_mask(__m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 4, + (__mmask64)-1); +} + +static __inline__ __mmask64 __DEFAULT_FN_ATTRS +_mm512_mask_cmpneq_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { + return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 4, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_cmpneq_epi16_mask(__m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 4, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_mask_cmpneq_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 4, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_cmpneq_epu16_mask(__m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 4, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm512_mask_cmpneq_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { + return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 4, + __u); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_add_epi8 (__m512i __A, __m512i __B) { + return (__m512i) ((__v64qi) __A + (__v64qi) __B); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_add_epi8 (__m512i __W, __mmask64 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_paddb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) __W, + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_add_epi8 (__mmask64 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_paddb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_sub_epi8 (__m512i __A, __m512i __B) { + return (__m512i) ((__v64qi) __A - (__v64qi) __B); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_sub_epi8 (__m512i __W, __mmask64 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_psubb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) __W, + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_sub_epi8 (__mmask64 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_psubb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_add_epi16 (__m512i __A, __m512i __B) { + return (__m512i) ((__v32hi) __A + (__v32hi) __B); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_add_epi16 (__m512i __W, __mmask32 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_paddw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_add_epi16 (__mmask32 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_paddw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_sub_epi16 (__m512i __A, __m512i __B) { + return (__m512i) ((__v32hi) __A - (__v32hi) __B); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_sub_epi16 (__m512i __W, __mmask32 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_psubw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_sub_epi16 (__mmask32 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_psubw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mullo_epi16 (__m512i __A, __m512i __B) { + return (__m512i) ((__v32hi) __A * (__v32hi) __B); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_mullo_epi16 (__m512i __W, __mmask32 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_pmullw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_mullo_epi16 (__mmask32 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_pmullw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_blend_epi8 (__mmask64 __U, __m512i __A, __m512i __W) +{ + return (__m512i) __builtin_ia32_blendmb_512_mask ((__v64qi) __A, + (__v64qi) __W, + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_blend_epi16 (__mmask32 __U, __m512i __A, __m512i __W) +{ + return (__m512i) __builtin_ia32_blendmw_512_mask ((__v32hi) __A, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_abs_epi8 (__m512i __A) +{ + return (__m512i) __builtin_ia32_pabsb512_mask ((__v64qi) __A, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_abs_epi8 (__m512i __W, __mmask64 __U, __m512i __A) +{ + return (__m512i) __builtin_ia32_pabsb512_mask ((__v64qi) __A, + (__v64qi) __W, + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_abs_epi8 (__mmask64 __U, __m512i __A) +{ + return (__m512i) __builtin_ia32_pabsb512_mask ((__v64qi) __A, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_abs_epi16 (__m512i __A) +{ + return (__m512i) __builtin_ia32_pabsw512_mask ((__v32hi) __A, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_abs_epi16 (__m512i __W, __mmask32 __U, __m512i __A) +{ + return (__m512i) __builtin_ia32_pabsw512_mask ((__v32hi) __A, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_abs_epi16 (__mmask32 __U, __m512i __A) +{ + return (__m512i) __builtin_ia32_pabsw512_mask ((__v32hi) __A, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_packs_epi32 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_packssdw512_mask ((__v16si) __A, + (__v16si) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_packs_epi32 (__mmask32 __M, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_packssdw512_mask ((__v16si) __A, + (__v16si) __B, + (__v32hi) _mm512_setzero_hi(), + __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_packs_epi32 (__m512i __W, __mmask32 __M, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_packssdw512_mask ((__v16si) __A, + (__v16si) __B, + (__v32hi) __W, + __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_packs_epi16 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_packsswb512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_packs_epi16 (__m512i __W, __mmask64 __M, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_packsswb512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v64qi) __W, + (__mmask64) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_packs_epi16 (__mmask64 __M, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_packsswb512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v64qi) _mm512_setzero_qi(), + __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_packus_epi32 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_packusdw512_mask ((__v16si) __A, + (__v16si) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_packus_epi32 (__mmask32 __M, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_packusdw512_mask ((__v16si) __A, + (__v16si) __B, + (__v32hi) _mm512_setzero_hi(), + __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_packus_epi32 (__m512i __W, __mmask32 __M, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_packusdw512_mask ((__v16si) __A, + (__v16si) __B, + (__v32hi) __W, + __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_packus_epi16 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_packuswb512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_packus_epi16 (__m512i __W, __mmask64 __M, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_packuswb512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v64qi) __W, + (__mmask64) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_packus_epi16 (__mmask64 __M, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_packuswb512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_adds_epi8 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_paddsb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_adds_epi8 (__m512i __W, __mmask64 __U, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_paddsb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) __W, + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_adds_epi8 (__mmask64 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_paddsb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_adds_epi16 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_paddsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_adds_epi16 (__m512i __W, __mmask32 __U, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_paddsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_adds_epi16 (__mmask32 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_paddsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_adds_epu8 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_paddusb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_adds_epu8 (__m512i __W, __mmask64 __U, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_paddusb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) __W, + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_adds_epu8 (__mmask64 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_paddusb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_adds_epu16 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_paddusw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_adds_epu16 (__m512i __W, __mmask32 __U, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_paddusw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_adds_epu16 (__mmask32 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_paddusw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_avg_epu8 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pavgb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_avg_epu8 (__m512i __W, __mmask64 __U, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_pavgb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) __W, + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_avg_epu8 (__mmask64 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pavgb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_avg_epu16 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pavgw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_avg_epu16 (__m512i __W, __mmask32 __U, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_pavgw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_avg_epu16 (__mmask32 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pavgw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_max_epi8 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxsb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_max_epi8 (__mmask64 __M, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxsb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_max_epi8 (__m512i __W, __mmask64 __M, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxsb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) __W, + (__mmask64) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_max_epi16 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_max_epi16 (__mmask32 __M, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_max_epi16 (__m512i __W, __mmask32 __M, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_max_epu8 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxub512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_max_epu8 (__mmask64 __M, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxub512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_max_epu8 (__m512i __W, __mmask64 __M, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxub512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) __W, + (__mmask64) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_max_epu16 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxuw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_max_epu16 (__mmask32 __M, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxuw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_max_epu16 (__m512i __W, __mmask32 __M, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxuw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_min_epi8 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pminsb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_min_epi8 (__mmask64 __M, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pminsb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_min_epi8 (__m512i __W, __mmask64 __M, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_pminsb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) __W, + (__mmask64) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_min_epi16 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pminsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_min_epi16 (__mmask32 __M, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pminsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_min_epi16 (__m512i __W, __mmask32 __M, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_pminsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_min_epu8 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pminub512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_min_epu8 (__mmask64 __M, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pminub512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_min_epu8 (__m512i __W, __mmask64 __M, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_pminub512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) __W, + (__mmask64) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_min_epu16 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pminuw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_min_epu16 (__mmask32 __M, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pminuw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_min_epu16 (__m512i __W, __mmask32 __M, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_pminuw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_shuffle_epi8 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pshufb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_shuffle_epi8 (__m512i __W, __mmask64 __U, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_pshufb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) __W, + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_shuffle_epi8 (__mmask64 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pshufb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_subs_epi8 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_psubsb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_subs_epi8 (__m512i __W, __mmask64 __U, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_psubsb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) __W, + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_subs_epi8 (__mmask64 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_psubsb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_subs_epi16 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_psubsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_subs_epi16 (__m512i __W, __mmask32 __U, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_psubsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_subs_epi16 (__mmask32 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_psubsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_subs_epu8 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_psubusb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_subs_epu8 (__m512i __W, __mmask64 __U, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_psubusb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) __W, + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_subs_epu8 (__mmask64 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_psubusb512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_subs_epu16 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_psubusw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_subs_epu16 (__m512i __W, __mmask32 __U, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_psubusw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_subs_epu16 (__mmask32 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_psubusw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask2_permutex2var_epi16 (__m512i __A, __m512i __I, + __mmask32 __U, __m512i __B) +{ + return (__m512i) __builtin_ia32_vpermi2varhi512_mask ((__v32hi) __A, + (__v32hi) __I /* idx */ , + (__v32hi) __B, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_permutex2var_epi16 (__m512i __A, __m512i __I, __m512i __B) +{ + return (__m512i) __builtin_ia32_vpermt2varhi512_mask ((__v32hi) __I /* idx */, + (__v32hi) __A, + (__v32hi) __B, + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_permutex2var_epi16 (__m512i __A, __mmask32 __U, + __m512i __I, __m512i __B) +{ + return (__m512i) __builtin_ia32_vpermt2varhi512_mask ((__v32hi) __I /* idx */, + (__v32hi) __A, + (__v32hi) __B, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_permutex2var_epi16 (__mmask32 __U, __m512i __A, + __m512i __I, __m512i __B) +{ + return (__m512i) __builtin_ia32_vpermt2varhi512_maskz ((__v32hi) __I + /* idx */ , + (__v32hi) __A, + (__v32hi) __B, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mulhrs_epi16 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmulhrsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_mulhrs_epi16 (__m512i __W, __mmask32 __U, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_pmulhrsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_mulhrs_epi16 (__mmask32 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmulhrsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mulhi_epi16 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmulhw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_mulhi_epi16 (__m512i __W, __mmask32 __U, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_pmulhw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_mulhi_epi16 (__mmask32 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmulhw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mulhi_epu16 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmulhuw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_mulhi_epu16 (__m512i __W, __mmask32 __U, __m512i __A, + __m512i __B) +{ + return (__m512i) __builtin_ia32_pmulhuw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_mulhi_epu16 (__mmask32 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmulhuw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maddubs_epi16 (__m512i __X, __m512i __Y) { + return (__m512i) __builtin_ia32_pmaddubsw512_mask ((__v64qi) __X, + (__v64qi) __Y, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_maddubs_epi16 (__m512i __W, __mmask32 __U, __m512i __X, + __m512i __Y) { + return (__m512i) __builtin_ia32_pmaddubsw512_mask ((__v64qi) __X, + (__v64qi) __Y, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_maddubs_epi16 (__mmask32 __U, __m512i __X, __m512i __Y) { + return (__m512i) __builtin_ia32_pmaddubsw512_mask ((__v64qi) __X, + (__v64qi) __Y, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_madd_epi16 (__m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_pmaddwd512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v16si) _mm512_setzero_si512(), + (__mmask16) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_madd_epi16 (__m512i __W, __mmask16 __U, __m512i __A, + __m512i __B) { + return (__m512i) __builtin_ia32_pmaddwd512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v16si) __W, + (__mmask16) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_madd_epi16 (__mmask16 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_pmaddwd512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v16si) _mm512_setzero_si512(), + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm512_cvtsepi16_epi8 (__m512i __A) { + return (__m256i) __builtin_ia32_pmovswb512_mask ((__v32hi) __A, + (__v32qi)_mm256_setzero_si256(), + (__mmask32) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm512_mask_cvtsepi16_epi8 (__m256i __O, __mmask32 __M, __m512i __A) { + return (__m256i) __builtin_ia32_pmovswb512_mask ((__v32hi) __A, + (__v32qi)__O, + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm512_maskz_cvtsepi16_epi8 (__mmask32 __M, __m512i __A) { + return (__m256i) __builtin_ia32_pmovswb512_mask ((__v32hi) __A, + (__v32qi) _mm256_setzero_si256(), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm512_cvtusepi16_epi8 (__m512i __A) { + return (__m256i) __builtin_ia32_pmovuswb512_mask ((__v32hi) __A, + (__v32qi) _mm256_setzero_si256(), + (__mmask32) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm512_mask_cvtusepi16_epi8 (__m256i __O, __mmask32 __M, __m512i __A) { + return (__m256i) __builtin_ia32_pmovuswb512_mask ((__v32hi) __A, + (__v32qi) __O, + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm512_maskz_cvtusepi16_epi8 (__mmask32 __M, __m512i __A) { + return (__m256i) __builtin_ia32_pmovuswb512_mask ((__v32hi) __A, + (__v32qi) _mm256_setzero_si256(), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm512_cvtepi16_epi8 (__m512i __A) { + return (__m256i) __builtin_ia32_pmovwb512_mask ((__v32hi) __A, + (__v32qi) _mm256_setzero_si256(), + (__mmask32) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm512_mask_cvtepi16_epi8 (__m256i __O, __mmask32 __M, __m512i __A) { + return (__m256i) __builtin_ia32_pmovwb512_mask ((__v32hi) __A, + (__v32qi) __O, + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm512_maskz_cvtepi16_epi8 (__mmask32 __M, __m512i __A) { + return (__m256i) __builtin_ia32_pmovwb512_mask ((__v32hi) __A, + (__v32qi) _mm256_setzero_si256(), + __M); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_unpackhi_epi8 (__m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_punpckhbw512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_unpackhi_epi8 (__m512i __W, __mmask64 __U, __m512i __A, + __m512i __B) { + return (__m512i) __builtin_ia32_punpckhbw512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) __W, + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_unpackhi_epi8 (__mmask64 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_punpckhbw512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_unpackhi_epi16 (__m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_punpckhwd512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_unpackhi_epi16 (__m512i __W, __mmask32 __U, __m512i __A, + __m512i __B) { + return (__m512i) __builtin_ia32_punpckhwd512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_unpackhi_epi16 (__mmask32 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_punpckhwd512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_unpacklo_epi8 (__m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_punpcklbw512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_unpacklo_epi8 (__m512i __W, __mmask64 __U, __m512i __A, + __m512i __B) { + return (__m512i) __builtin_ia32_punpcklbw512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) __W, + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_unpacklo_epi8 (__mmask64 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_punpcklbw512_mask ((__v64qi) __A, + (__v64qi) __B, + (__v64qi) _mm512_setzero_qi(), + (__mmask64) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_unpacklo_epi16 (__m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_punpcklwd512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_unpacklo_epi16 (__m512i __W, __mmask32 __U, __m512i __A, + __m512i __B) { + return (__m512i) __builtin_ia32_punpcklwd512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + (__mmask32) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_unpacklo_epi16 (__mmask32 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_punpcklwd512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) _mm512_setzero_hi(), + (__mmask32) __U); +} + +#define _mm512_cmp_epi8_mask(a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_cmpb512_mask((__v64qi)(__m512i)(a), \ + (__v64qi)(__m512i)(b), \ + (p), (__mmask64)-1); }) + +#define _mm512_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_cmpb512_mask((__v64qi)(__m512i)(a), \ + (__v64qi)(__m512i)(b), \ + (p), (__mmask64)(m)); }) + +#define _mm512_cmp_epu8_mask(a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_ucmpb512_mask((__v64qi)(__m512i)(a), \ + (__v64qi)(__m512i)(b), \ + (p), (__mmask64)-1); }) + +#define _mm512_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_ucmpb512_mask((__v64qi)(__m512i)(a), \ + (__v64qi)(__m512i)(b), \ + (p), (__mmask64)(m)); }) + +#define _mm512_cmp_epi16_mask(a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_cmpw512_mask((__v32hi)(__m512i)(a), \ + (__v32hi)(__m512i)(b), \ + (p), (__mmask32)-1); }) + +#define _mm512_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_cmpw512_mask((__v32hi)(__m512i)(a), \ + (__v32hi)(__m512i)(b), \ + (p), (__mmask32)(m)); }) + +#define _mm512_cmp_epu16_mask(a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_ucmpw512_mask((__v32hi)(__m512i)(a), \ + (__v32hi)(__m512i)(b), \ + (p), (__mmask32)-1); }) + +#define _mm512_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_ucmpw512_mask((__v32hi)(__m512i)(a), \ + (__v32hi)(__m512i)(b), \ + (p), (__mmask32)(m)); }) + + +#undef __DEFAULT_FN_ATTRS + +#endif diff --git a/headers/clang/avx512cdintrin.h b/headers/clang/avx512cdintrin.h new file mode 100644 index 0000000000..3894b29f57 --- /dev/null +++ b/headers/clang/avx512cdintrin.h @@ -0,0 +1,131 @@ +/*===------------- avx512cdintrin.h - AVX512CD intrinsics ------------------=== + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __AVX512CDINTRIN_H +#define __AVX512CDINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512cd"))) + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_conflict_epi64 (__m512i __A) +{ + return (__m512i) __builtin_ia32_vpconflictdi_512_mask ((__v8di) __A, + (__v8di) _mm512_setzero_si512 (), + (__mmask8) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_conflict_epi64 (__m512i __W, __mmask8 __U, __m512i __A) +{ + return (__m512i) __builtin_ia32_vpconflictdi_512_mask ((__v8di) __A, + (__v8di) __W, + (__mmask8) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_conflict_epi64 (__mmask8 __U, __m512i __A) +{ + return (__m512i) __builtin_ia32_vpconflictdi_512_mask ((__v8di) __A, + (__v8di) _mm512_setzero_si512 (), + (__mmask8) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_conflict_epi32 (__m512i __A) +{ + return (__m512i) __builtin_ia32_vpconflictsi_512_mask ((__v16si) __A, + (__v16si) _mm512_setzero_si512 (), + (__mmask16) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_conflict_epi32 (__m512i __W, __mmask16 __U, __m512i __A) +{ + return (__m512i) __builtin_ia32_vpconflictsi_512_mask ((__v16si) __A, + (__v16si) __W, + (__mmask16) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_conflict_epi32 (__mmask16 __U, __m512i __A) +{ + return (__m512i) __builtin_ia32_vpconflictsi_512_mask ((__v16si) __A, + (__v16si) _mm512_setzero_si512 (), + (__mmask16) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_lzcnt_epi32 (__m512i __A) +{ + return (__m512i) __builtin_ia32_vplzcntd_512_mask ((__v16si) __A, + (__v16si) _mm512_setzero_si512 (), + (__mmask16) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_lzcnt_epi32 (__m512i __W, __mmask16 __U, __m512i __A) +{ + return (__m512i) __builtin_ia32_vplzcntd_512_mask ((__v16si) __A, + (__v16si) __W, + (__mmask16) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_lzcnt_epi32 (__mmask16 __U, __m512i __A) +{ + return (__m512i) __builtin_ia32_vplzcntd_512_mask ((__v16si) __A, + (__v16si) _mm512_setzero_si512 (), + (__mmask16) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_lzcnt_epi64 (__m512i __A) +{ + return (__m512i) __builtin_ia32_vplzcntq_512_mask ((__v8di) __A, + (__v8di) _mm512_setzero_si512 (), + (__mmask8) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_lzcnt_epi64 (__m512i __W, __mmask8 __U, __m512i __A) +{ + return (__m512i) __builtin_ia32_vplzcntq_512_mask ((__v8di) __A, + (__v8di) __W, + (__mmask8) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_lzcnt_epi64 (__mmask8 __U, __m512i __A) +{ + return (__m512i) __builtin_ia32_vplzcntq_512_mask ((__v8di) __A, + (__v8di) _mm512_setzero_si512 (), + (__mmask8) __U); +} +#undef __DEFAULT_FN_ATTRS + +#endif diff --git a/headers/clang/avx512dqintrin.h b/headers/clang/avx512dqintrin.h new file mode 100644 index 0000000000..afee4903ba --- /dev/null +++ b/headers/clang/avx512dqintrin.h @@ -0,0 +1,778 @@ +/*===---- avx512dqintrin.h - AVX512DQ intrinsics ---------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __AVX512DQINTRIN_H +#define __AVX512DQINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512dq"))) + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mullo_epi64 (__m512i __A, __m512i __B) { + return (__m512i) ((__v8di) __A * (__v8di) __B); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_mullo_epi64 (__m512i __W, __mmask8 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_pmullq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) __W, + (__mmask8) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_mullo_epi64 (__mmask8 __U, __m512i __A, __m512i __B) { + return (__m512i) __builtin_ia32_pmullq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) __U); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_xor_pd (__m512d __A, __m512d __B) { + return (__m512d) ((__v8di) __A ^ (__v8di) __B); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_xor_pd (__m512d __W, __mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_xorpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) __W, + (__mmask8) __U); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_xor_pd (__mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_xorpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_xor_ps (__m512 __A, __m512 __B) { + return (__m512) ((__v16si) __A ^ (__v16si) __B); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask_xor_ps (__m512 __W, __mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_xorps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __W, + (__mmask16) __U); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_xor_ps (__mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_xorps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) __U); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_or_pd (__m512d __A, __m512d __B) { + return (__m512d) ((__v8di) __A | (__v8di) __B); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_or_pd (__m512d __W, __mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_orpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) __W, + (__mmask8) __U); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_or_pd (__mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_orpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_or_ps (__m512 __A, __m512 __B) { + return (__m512) ((__v16si) __A | (__v16si) __B); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask_or_ps (__m512 __W, __mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_orps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __W, + (__mmask16) __U); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_or_ps (__mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_orps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) __U); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_and_pd (__m512d __A, __m512d __B) { + return (__m512d) ((__v8di) __A & (__v8di) __B); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_and_pd (__m512d __W, __mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_andpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) __W, + (__mmask8) __U); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_and_pd (__mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_andpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_and_ps (__m512 __A, __m512 __B) { + return (__m512) ((__v16si) __A & (__v16si) __B); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask_and_ps (__m512 __W, __mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_andps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __W, + (__mmask16) __U); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_and_ps (__mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_andps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) __U); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_andnot_pd (__m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_andnpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) -1); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_andnot_pd (__m512d __W, __mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_andnpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) __W, + (__mmask8) __U); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_andnot_pd (__mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_andnpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_andnot_ps (__m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_andnps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) -1); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask_andnot_ps (__m512 __W, __mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_andnps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __W, + (__mmask16) __U); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_andnot_ps (__mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_andnps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_cvtpd_epi64 (__m512d __A) { + return (__m512i) __builtin_ia32_cvtpd2qq512_mask ((__v8df) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_cvtpd_epi64 (__m512i __W, __mmask8 __U, __m512d __A) { + return (__m512i) __builtin_ia32_cvtpd2qq512_mask ((__v8df) __A, + (__v8di) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_cvtpd_epi64 (__mmask8 __U, __m512d __A) { + return (__m512i) __builtin_ia32_cvtpd2qq512_mask ((__v8df) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_cvt_roundpd_epi64(__A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvtpd2qq512_mask ((__v8df) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) -1, __R);}) + +#define _mm512_mask_cvt_roundpd_epi64(__W, __U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvtpd2qq512_mask ((__v8df) __A, \ + (__v8di) __W, (__mmask8) __U, __R);}) + +#define _mm512_maskz_cvt_roundpd_epi64(__U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvtpd2qq512_mask ((__v8df) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) __U, __R); }) + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_cvtpd_epu64 (__m512d __A) { + return (__m512i) __builtin_ia32_cvtpd2uqq512_mask ((__v8df) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_cvtpd_epu64 (__m512i __W, __mmask8 __U, __m512d __A) { + return (__m512i) __builtin_ia32_cvtpd2uqq512_mask ((__v8df) __A, + (__v8di) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_cvtpd_epu64 (__mmask8 __U, __m512d __A) { + return (__m512i) __builtin_ia32_cvtpd2uqq512_mask ((__v8df) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_cvt_roundpd_epu64(__A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvtpd2uqq512_mask ((__v8df) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) -1, __R);}) + +#define _mm512_mask_cvt_roundpd_epu64(__W, __U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvtpd2uqq512_mask ((__v8df) __A, \ + (__v8di) __W, (__mmask8) __U, __R);}) + +#define _mm512_maskz_cvt_roundpd_epu64(__U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvtpd2uqq512_mask ((__v8df) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) __U, __R);}) + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_cvtps_epi64 (__m256 __A) { + return (__m512i) __builtin_ia32_cvtps2qq512_mask ((__v8sf) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_cvtps_epi64 (__m512i __W, __mmask8 __U, __m256 __A) { + return (__m512i) __builtin_ia32_cvtps2qq512_mask ((__v8sf) __A, + (__v8di) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_cvtps_epi64 (__mmask8 __U, __m256 __A) { + return (__m512i) __builtin_ia32_cvtps2qq512_mask ((__v8sf) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_cvt_roundps_epi64(__A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvtps2qq512_mask ((__v8sf) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) -1, __R);}) + +#define _mm512_mask_cvt_roundps_epi64(__W, __U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvtps2qq512_mask ((__v8sf) __A, \ + (__v8di) __W, (__mmask8) __U, __R);}) + +#define _mm512_maskz_cvt_roundps_epi64(__U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvtps2qq512_mask ((__v8sf) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) __U, __R);}) + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_cvtps_epu64 (__m256 __A) { + return (__m512i) __builtin_ia32_cvtps2uqq512_mask ((__v8sf) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_cvtps_epu64 (__m512i __W, __mmask8 __U, __m256 __A) { + return (__m512i) __builtin_ia32_cvtps2uqq512_mask ((__v8sf) __A, + (__v8di) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_cvtps_epu64 (__mmask8 __U, __m256 __A) { + return (__m512i) __builtin_ia32_cvtps2uqq512_mask ((__v8sf) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_cvt_roundps_epu64(__A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvtps2uqq512_mask ((__v8sf) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) -1, __R);}) + +#define _mm512_mask_cvt_roundps_epu64(__W, __U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvtps2uqq512_mask ((__v8sf) __A, \ + (__v8di) __W, (__mmask8) __U, __R);}) + +#define _mm512_maskz_cvt_roundps_epu64(__U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvtps2uqq512_mask ((__v8sf) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) __U, __R);}) + + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_cvtepi64_pd (__m512i __A) { + return (__m512d) __builtin_ia32_cvtqq2pd512_mask ((__v8di) __A, + (__v8df) _mm512_setzero_pd(), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_cvtepi64_pd (__m512d __W, __mmask8 __U, __m512i __A) { + return (__m512d) __builtin_ia32_cvtqq2pd512_mask ((__v8di) __A, + (__v8df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_cvtepi64_pd (__mmask8 __U, __m512i __A) { + return (__m512d) __builtin_ia32_cvtqq2pd512_mask ((__v8di) __A, + (__v8df) _mm512_setzero_pd(), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_cvt_roundepi64_pd(__A, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_cvtqq2pd512_mask ((__v8di) __A, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) -1, __R);}) + +#define _mm512_mask_cvt_roundepi64_pd(__W, __U, __A, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_cvtqq2pd512_mask ((__v8di) __A, \ + (__v8df) __W, (__mmask8) __U, __R);}) + +#define _mm512_maskz_cvt_roundepi64_pd(__U, __A, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_cvtqq2pd512_mask ((__v8di) __A, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) __U, __R);}) + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm512_cvtepi64_ps (__m512i __A) { + return (__m256) __builtin_ia32_cvtqq2ps512_mask ((__v8di) __A, + (__v8sf) _mm256_setzero_ps(), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm512_mask_cvtepi64_ps (__m256 __W, __mmask8 __U, __m512i __A) { + return (__m256) __builtin_ia32_cvtqq2ps512_mask ((__v8di) __A, + (__v8sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm512_maskz_cvtepi64_ps (__mmask8 __U, __m512i __A) { + return (__m256) __builtin_ia32_cvtqq2ps512_mask ((__v8di) __A, + (__v8sf) _mm256_setzero_ps(), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_cvt_roundepi64_ps(__A, __R) __extension__ ({ \ + (__m256) __builtin_ia32_cvtqq2ps512_mask ((__v8di) __A, \ + (__v8sf) _mm256_setzero_ps(), (__mmask8) -1, __R);}) + +#define _mm512_mask_cvt_roundepi64_ps(__W, __U, __A, __R) __extension__ ({ \ + (__m256) __builtin_ia32_cvtqq2ps512_mask ((__v8di) __A, \ + (__v8sf) __W, (__mmask8) __U, __R);}) + +#define _mm512_maskz_cvt_roundepi64_ps(__U, __A, __R) __extension__ ({ \ + (__m256) __builtin_ia32_cvtqq2ps512_mask ((__v8di) __A, \ + (__v8sf) _mm256_setzero_ps(), (__mmask8) __U, __R);}) + + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_cvttpd_epi64 (__m512d __A) { + return (__m512i) __builtin_ia32_cvttpd2qq512_mask ((__v8df) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_cvttpd_epi64 (__m512i __W, __mmask8 __U, __m512d __A) { + return (__m512i) __builtin_ia32_cvttpd2qq512_mask ((__v8df) __A, + (__v8di) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_cvttpd_epi64 (__mmask8 __U, __m512d __A) { + return (__m512i) __builtin_ia32_cvttpd2qq512_mask ((__v8df) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_cvtt_roundpd_epi64(__A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvttpd2qq512_mask ((__v8df) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) -1, __R);}) + +#define _mm512_mask_cvtt_roundpd_epi64(__W, __U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvttpd2qq512_mask ((__v8df) __A, \ + (__v8di) __W, (__mmask8) __U, __R);}) + +#define _mm512_maskz_cvtt_roundpd_epi64(__U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvttpd2qq512_mask ((__v8df) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) __U, __R);}) + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_cvttpd_epu64 (__m512d __A) { + return (__m512i) __builtin_ia32_cvttpd2uqq512_mask ((__v8df) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_cvttpd_epu64 (__m512i __W, __mmask8 __U, __m512d __A) { + return (__m512i) __builtin_ia32_cvttpd2uqq512_mask ((__v8df) __A, + (__v8di) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_cvttpd_epu64 (__mmask8 __U, __m512d __A) { + return (__m512i) __builtin_ia32_cvttpd2uqq512_mask ((__v8df) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_cvtt_roundpd_epu64(__A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvttpd2uqq512_mask ((__v8df) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) -1, __R);}) + +#define _mm512_mask_cvtt_roundpd_epu64(__W, __U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvttpd2uqq512_mask ((__v8df) __A, \ + (__v8di) __W, (__mmask8) __U, __R);}) + +#define _mm512_maskz_cvtt_roundpd_epu64(__U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvttpd2uqq512_mask ((__v8df) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) __U, __R);}) + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_cvttps_epi64 (__m256 __A) { + return (__m512i) __builtin_ia32_cvttps2qq512_mask ((__v8sf) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_cvttps_epi64 (__m512i __W, __mmask8 __U, __m256 __A) { + return (__m512i) __builtin_ia32_cvttps2qq512_mask ((__v8sf) __A, + (__v8di) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_cvttps_epi64 (__mmask8 __U, __m256 __A) { + return (__m512i) __builtin_ia32_cvttps2qq512_mask ((__v8sf) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_cvtt_roundps_epi64(__A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvttps2qq512_mask ((__v8sf) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) -1, __R);}) + +#define _mm512_mask_cvtt_roundps_epi64(__W, __U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvttps2qq512_mask ((__v8sf) __A, \ + (__v8di) __W, (__mmask8) __U, __R);}) + +#define _mm512_maskz_cvtt_roundps_epi64(__U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvttps2qq512_mask ((__v8sf) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) __U, __R);}) + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_cvttps_epu64 (__m256 __A) { + return (__m512i) __builtin_ia32_cvttps2uqq512_mask ((__v8sf) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_cvttps_epu64 (__m512i __W, __mmask8 __U, __m256 __A) { + return (__m512i) __builtin_ia32_cvttps2uqq512_mask ((__v8sf) __A, + (__v8di) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_cvttps_epu64 (__mmask8 __U, __m256 __A) { + return (__m512i) __builtin_ia32_cvttps2uqq512_mask ((__v8sf) __A, + (__v8di) _mm512_setzero_si512(), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_cvtt_roundps_epu64(__A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvttps2uqq512_mask ((__v8sf) __A, \ + (__v8di) _mm512_setzero_si512(),(__mmask8) -1, __R);}) + +#define _mm512_mask_cvtt_roundps_epu64(__W, __U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvttps2uqq512_mask ((__v8sf) __A, \ + (__v8di) __W, (__mmask8) __U, __R);}) + +#define _mm512_maskz_cvtt_roundps_epu64(__U, __A, __R) __extension__ ({ \ + (__m512i) __builtin_ia32_cvttps2uqq512_mask ((__v8sf) __A, \ + (__v8di) _mm512_setzero_si512(), (__mmask8) __U, __R);}) + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_cvtepu64_pd (__m512i __A) { + return (__m512d) __builtin_ia32_cvtuqq2pd512_mask ((__v8di) __A, + (__v8df) _mm512_setzero_pd(), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_cvtepu64_pd (__m512d __W, __mmask8 __U, __m512i __A) { + return (__m512d) __builtin_ia32_cvtuqq2pd512_mask ((__v8di) __A, + (__v8df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_cvtepu64_pd (__mmask8 __U, __m512i __A) { + return (__m512d) __builtin_ia32_cvtuqq2pd512_mask ((__v8di) __A, + (__v8df) _mm512_setzero_pd(), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_cvt_roundepu64_pd(__A, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_cvtuqq2pd512_mask ((__v8di) __A, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) -1, __R);}) + +#define _mm512_mask_cvt_roundepu64_pd(__W, __U, __A, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_cvtuqq2pd512_mask ((__v8di) __A, \ + (__v8df) __W, (__mmask8) __U, __R);}) + + +#define _mm512_maskz_cvt_roundepu64_pd(__U, __A, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_cvtuqq2pd512_mask ((__v8di) __A, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) __U, __R);}) + + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm512_cvtepu64_ps (__m512i __A) { + return (__m256) __builtin_ia32_cvtuqq2ps512_mask ((__v8di) __A, + (__v8sf) _mm256_setzero_ps(), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm512_mask_cvtepu64_ps (__m256 __W, __mmask8 __U, __m512i __A) { + return (__m256) __builtin_ia32_cvtuqq2ps512_mask ((__v8di) __A, + (__v8sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm512_maskz_cvtepu64_ps (__mmask8 __U, __m512i __A) { + return (__m256) __builtin_ia32_cvtuqq2ps512_mask ((__v8di) __A, + (__v8sf) _mm256_setzero_ps(), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_cvt_roundepu64_ps(__A, __R) __extension__ ({ \ + (__m256) __builtin_ia32_cvtuqq2ps512_mask ((__v8di) __A, \ + (__v8sf) _mm256_setzero_ps(), (__mmask8) -1, __R);}) + +#define _mm512_mask_cvt_roundepu64_ps(__W, __U, __A, __R) __extension__ ({ \ + (__m256) __builtin_ia32_cvtuqq2ps512_mask ((__v8di) __A, \ + (__v8sf) __W, (__mmask8) __U, __R);}) + +#define _mm512_maskz_cvt_roundepu64_ps(__U, __A, __R) __extension__ ({ \ + (__m256) __builtin_ia32_cvtuqq2ps512_mask ((__v8di) __A, \ + (__v8sf) _mm256_setzero_ps(), (__mmask8) __U, __R);}) + +#define _mm512_range_pd(__A, __B, __C) __extension__ ({ \ + (__m512d) __builtin_ia32_rangepd512_mask ((__v8df) __A, (__v8df) __B, __C,\ + (__v8df) _mm512_setzero_pd(), (__mmask8) -1, \ + _MM_FROUND_CUR_DIRECTION);}) + +#define _mm512_mask_range_pd(__W, __U, __A, __B, __C) __extension__ ({ \ + (__m512d) __builtin_ia32_rangepd512_mask ((__v8df) __A, (__v8df) __B, __C,\ + (__v8df) __W, (__mmask8) __U, _MM_FROUND_CUR_DIRECTION);}) + +#define _mm512_maskz_range_pd(__U, __A, __B, __C) __extension__ ({ \ + (__m512d) __builtin_ia32_rangepd512_mask ((__v8df) __A, (__v8df) __B, __C, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) __U, \ + _MM_FROUND_CUR_DIRECTION);}) + +#define _mm512_range_round_pd(__A, __B, __C, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_rangepd512_mask ((__v8df) __A, (__v8df) __B, __C, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) -1, __R);}) + +#define _mm512_mask_range_round_pd(__W, __U, __A, __B, __C, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_rangepd512_mask ((__v8df) __A, (__v8df) __B, __C, \ + (__v8df) __W, (__mmask8) __U, __R);}) + +#define _mm512_maskz_range_round_pd(__U, __A, __B, __C, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_rangepd512_mask ((__v8df) __A, (__v8df) __B, __C, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) __U, __R);}) + +#define _mm512_range_ps(__A, __B, __C) __extension__ ({ \ + (__m512) __builtin_ia32_rangeps512_mask ((__v16sf) __A, (__v16sf) __B, __C, \ + (__v16sf) _mm512_setzero_ps(), (__mmask16) -1, \ + _MM_FROUND_CUR_DIRECTION);}) + +#define _mm512_mask_range_ps(__W, __U, __A, __B, __C) __extension__ ({ \ + (__m512) __builtin_ia32_rangeps512_mask ((__v16sf) __A, (__v16sf) __B, \ + __C, (__v16sf) __W, (__mmask16) __U, _MM_FROUND_CUR_DIRECTION);}) + +#define _mm512_maskz_range_ps(__U, __A, __B, __C) __extension__ ({ \ + (__m512) __builtin_ia32_rangeps512_mask ((__v16sf) __A,(__v16sf) __B, \ + __C, (__v16sf) _mm512_setzero_ps(), (__mmask16) __U, \ + _MM_FROUND_CUR_DIRECTION);}) + +#define _mm512_range_round_ps(__A, __B, __C, __R) __extension__ ({ \ + (__m512) __builtin_ia32_rangeps512_mask ((__v16sf) __A, (__v16sf) __B, \ + __C, (__v16sf) _mm512_setzero_ps(), (__mmask16) -1, __R);}) + +#define _mm512_mask_range_round_ps(__W, __U, __A, __B, __C, __R) __extension__ ({ \ + (__m512) __builtin_ia32_rangeps512_mask ((__v16sf) __A, (__v16sf) __B, \ + __C, (__v16sf) __W, (__mmask16) __U, __R);}) + +#define _mm512_maskz_range_round_ps(__U, __A, __B, __C, __R) __extension__ ({ \ + (__m512) __builtin_ia32_rangeps512_mask ((__v16sf) __A, (__v16sf) __B, \ + __C, (__v16sf) _mm512_setzero_ps(), (__mmask16) __U, __R);}) + +#define _mm512_reduce_pd(__A, __B) __extension__ ({ \ + (__m512d) __builtin_ia32_reducepd512_mask ((__v8df) __A, __B, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) -1, _MM_FROUND_CUR_DIRECTION);}) + +#define _mm512_mask_reduce_pd(__W, __U, __A, __B) __extension__ ({ \ + (__m512d) __builtin_ia32_reducepd512_mask ((__v8df) __A, __B, \ + (__v8df) __W,(__mmask8) __U, _MM_FROUND_CUR_DIRECTION);}) + +#define _mm512_maskz_reduce_pd(__U, __A, __B) __extension__ ({ \ + (__m512d) __builtin_ia32_reducepd512_mask ((__v8df) __A, __B, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) __U, _MM_FROUND_CUR_DIRECTION);}) + +#define _mm512_reduce_ps(__A, __B) __extension__ ({ \ + (__m512) __builtin_ia32_reduceps512_mask ((__v16sf) __A, __B, \ + (__v16sf) _mm512_setzero_ps(), (__mmask16) -1, _MM_FROUND_CUR_DIRECTION);}) + +#define _mm512_mask_reduce_ps(__W, __U, __A, __B) __extension__ ({ \ + (__m512) __builtin_ia32_reduceps512_mask ((__v16sf) __A, __B, \ + (__v16sf) __W, (__mmask16) __U, _MM_FROUND_CUR_DIRECTION);}) + +#define _mm512_maskz_reduce_ps(__U, __A, __B) __extension__ ({ \ + (__m512) __builtin_ia32_reduceps512_mask ((__v16sf) __A, __B, \ + (__v16sf) _mm512_setzero_ps(), (__mmask16) __U, _MM_FROUND_CUR_DIRECTION);}) + +#define _mm512_reduce_round_pd(__A, __B, __R) __extension__ ({\ + (__m512d) __builtin_ia32_reducepd512_mask ((__v8df) __A, __B, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) -1, __R);}) + +#define _mm512_mask_reduce_round_pd(__W, __U, __A, __B, __R) __extension__ ({\ + (__m512d) __builtin_ia32_reducepd512_mask ((__v8df) __A, __B, \ + (__v8df) __W,(__mmask8) __U, __R);}) + +#define _mm512_maskz_reduce_round_pd(__U, __A, __B, __R) __extension__ ({\ + (__m512d) __builtin_ia32_reducepd512_mask ((__v8df) __A, __B, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) __U, __R);}) + +#define _mm512_reduce_round_ps(__A, __B, __R) __extension__ ({\ + (__m512) __builtin_ia32_reduceps512_mask ((__v16sf) __A, __B, \ + (__v16sf) _mm512_setzero_ps(), (__mmask16) -1, __R);}) + +#define _mm512_mask_reduce_round_ps(__W, __U, __A, __B, __R) __extension__ ({\ + (__m512) __builtin_ia32_reduceps512_mask ((__v16sf) __A, __B, \ + (__v16sf) __W, (__mmask16) __U, __R);}) + +#define _mm512_maskz_reduce_round_ps(__U, __A, __B, __R) __extension__ ({\ + (__m512) __builtin_ia32_reduceps512_mask ((__v16sf) __A, __B, \ + (__v16sf) _mm512_setzero_ps(), (__mmask16) __U, __R);}) + +#undef __DEFAULT_FN_ATTRS + +#endif diff --git a/headers/clang/avx512erintrin.h b/headers/clang/avx512erintrin.h new file mode 100644 index 0000000000..607f2c024c --- /dev/null +++ b/headers/clang/avx512erintrin.h @@ -0,0 +1,285 @@ +/*===---- avx512erintrin.h - AVX512ER intrinsics ---------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __AVX512ERINTRIN_H +#define __AVX512ERINTRIN_H + +// exp2a23 +#define _mm512_exp2a23_round_pd(A, R) __extension__ ({ \ + (__m512d)__builtin_ia32_exp2pd_mask((__v8df)(__m512d)(A), \ + (__v8df)_mm512_setzero_pd(), \ + (__mmask8)-1, (R)); }) + +#define _mm512_mask_exp2a23_round_pd(S, M, A, R) __extension__ ({ \ + (__m512d)__builtin_ia32_exp2pd_mask((__v8df)(__m512d)(A), \ + (__v8df)(__m512d)(S), \ + (__mmask8)(M), (R)); }) + +#define _mm512_maskz_exp2a23_round_pd(M, A, R) __extension__ ({ \ + (__m512d)__builtin_ia32_exp2pd_mask((__v8df)(__m512d)(A), \ + (__v8df)_mm512_setzero_pd(), \ + (__mmask8)(M), (R)); }) + +#define _mm512_exp2a23_pd(A) \ + _mm512_exp2a23_round_pd((A), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_mask_exp2a23_pd(S, M, A) \ + _mm512_mask_exp2a23_round_pd((S), (M), (A), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_maskz_exp2a23_pd(M, A) \ + _mm512_maskz_exp2a23_round_pd((M), (A), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_exp2a23_round_ps(A, R) __extension__ ({ \ + (__m512)__builtin_ia32_exp2ps_mask((__v16sf)(__m512)(A), \ + (__v16sf)_mm512_setzero_ps(), \ + (__mmask8)-1, (R)); }) + +#define _mm512_mask_exp2a23_round_ps(S, M, A, R) __extension__ ({ \ + (__m512)__builtin_ia32_exp2ps_mask((__v16sf)(__m512)(A), \ + (__v16sf)(__m512)(S), \ + (__mmask8)(M), (R)); }) + +#define _mm512_maskz_exp2a23_round_ps(M, A, R) __extension__ ({ \ + (__m512)__builtin_ia32_exp2ps_mask((__v16sf)(__m512)(A), \ + (__v16sf)_mm512_setzero_ps(), \ + (__mmask8)(M), (R)); }) + +#define _mm512_exp2a23_ps(A) \ + _mm512_exp2a23_round_ps((A), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_mask_exp2a23_ps(S, M, A) \ + _mm512_mask_exp2a23_round_ps((S), (M), (A), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_maskz_exp2a23_ps(M, A) \ + _mm512_maskz_exp2a23_round_ps((M), (A), _MM_FROUND_CUR_DIRECTION) + +// rsqrt28 +#define _mm512_rsqrt28_round_pd(A, R) __extension__ ({ \ + (__m512d)__builtin_ia32_rsqrt28pd_mask((__v8df)(__m512d)(A), \ + (__v8df)_mm512_setzero_pd(), \ + (__mmask8)-1, (R)); }) + +#define _mm512_mask_rsqrt28_round_pd(S, M, A, R) __extension__ ({ \ + (__m512d)__builtin_ia32_rsqrt28pd_mask((__v8df)(__m512d)(A), \ + (__v8df)(__m512d)(S), \ + (__mmask8)(M), (R)); }) + +#define _mm512_maskz_rsqrt28_round_pd(M, A, R) __extension__ ({ \ + (__m512d)__builtin_ia32_rsqrt28pd_mask((__v8df)(__m512d)(A), \ + (__v8df)_mm512_setzero_pd(), \ + (__mmask8)(M), (R)); }) + +#define _mm512_rsqrt28_pd(A) \ + _mm512_rsqrt28_round_pd((A), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_mask_rsqrt28_pd(S, M, A) \ + _mm512_mask_rsqrt28_round_pd((S), (M), (A), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_maskz_rsqrt28_pd(M, A) \ + _mm512_maskz_rsqrt28_round_pd((M), (A), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_rsqrt28_round_ps(A, R) __extension__ ({ \ + (__m512)__builtin_ia32_rsqrt28ps_mask((__v16sf)(__m512)(A), \ + (__v16sf)_mm512_setzero_ps(), \ + (__mmask16)-1, (R)); }) + +#define _mm512_mask_rsqrt28_round_ps(S, M, A, R) __extension__ ({ \ + (__m512)__builtin_ia32_rsqrt28ps_mask((__v16sf)(__m512)(A), \ + (__v16sf)(__m512)(S), \ + (__mmask16)(M), (R)); }) + +#define _mm512_maskz_rsqrt28_round_ps(M, A, R) __extension__ ({ \ + (__m512)__builtin_ia32_rsqrt28ps_mask((__v16sf)(__m512)(A), \ + (__v16sf)_mm512_setzero_ps(), \ + (__mmask16)(M), (R)); }) + +#define _mm512_rsqrt28_ps(A) \ + _mm512_rsqrt28_round_ps((A), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_mask_rsqrt28_ps(S, M, A) \ + _mm512_mask_rsqrt28_round_ps((S), (M), A, _MM_FROUND_CUR_DIRECTION) + +#define _mm512_maskz_rsqrt28_ps(M, A) \ + _mm512_maskz_rsqrt28_round_ps((M), (A), _MM_FROUND_CUR_DIRECTION) + +#define _mm_rsqrt28_round_ss(A, B, R) __extension__ ({ \ + (__m128)__builtin_ia32_rsqrt28ss_mask((__v4sf)(__m128)(A), \ + (__v4sf)(__m128)(B), \ + (__v4sf)_mm_setzero_ps(), \ + (__mmask8)-1, (R)); }) + +#define _mm_mask_rsqrt28_round_ss(S, M, A, B, R) __extension__ ({ \ + (__m128)__builtin_ia32_rsqrt28ss_mask((__v4sf)(__m128)(A), \ + (__v4sf)(__m128)(B), \ + (__v4sf)(__m128)(S), \ + (__mmask8)(M), (R)); }) + +#define _mm_maskz_rsqrt28_round_ss(M, A, B, R) __extension__ ({ \ + (__m128)__builtin_ia32_rsqrt28ss_mask((__v4sf)(__m128)(A), \ + (__v4sf)(__m128)(B), \ + (__v4sf)_mm_setzero_ps(), \ + (__mmask8)(M), (R)); }) + +#define _mm_rsqrt28_ss(A, B) \ + _mm_rsqrt28_round_ss((A), (B), _MM_FROUND_CUR_DIRECTION) + +#define _mm_mask_rsqrt28_ss(S, M, A, B) \ + _mm_mask_rsqrt28_round_ss((S), (M), (A), (B), _MM_FROUND_CUR_DIRECTION) + +#define _mm_maskz_rsqrt28_ss(M, A, B) \ + _mm_maskz_rsqrt28_round_ss((M), (A), (B), _MM_FROUND_CUR_DIRECTION) + +#define _mm_rsqrt28_round_sd(A, B, R) __extension__ ({ \ + (__m128d)__builtin_ia32_rsqrt28sd_mask((__v2df)(__m128d)(A), \ + (__v2df)(__m128d)(B), \ + (__v2df)_mm_setzero_pd(), \ + (__mmask8)-1, (R)); }) + +#define _mm_mask_rsqrt28_round_sd(S, M, A, B, R) __extension__ ({ \ + (__m128d)__builtin_ia32_rsqrt28sd_mask((__v2df)(__m128d)(A), \ + (__v2df)(__m128d)(B), \ + (__v2df)(__m128d)(S), \ + (__mmask8)(M), (R)); }) + +#define _mm_maskz_rsqrt28_round_sd(M, A, B, R) __extension__ ({ \ + (__m128d)__builtin_ia32_rsqrt28sd_mask((__v2df)(__m128d)(A), \ + (__v2df)(__m128d)(B), \ + (__v2df)_mm_setzero_pd(), \ + (__mmask8)(M), (R)); }) + +#define _mm_rsqrt28_sd(A, B) \ + _mm_rsqrt28_round_sd((A), (B), _MM_FROUND_CUR_DIRECTION) + +#define _mm_mask_rsqrt28_sd(S, M, A, B) \ + _mm_mask_rsqrt28_round_sd((S), (M), (A), (B), _MM_FROUND_CUR_DIRECTION) + +#define _mm_maskz_rsqrt28_sd(M, A, B) \ + _mm_mask_rsqrt28_round_sd((M), (A), (B), _MM_FROUND_CUR_DIRECTION) + +// rcp28 +#define _mm512_rcp28_round_pd(A, R) __extension__ ({ \ + (__m512d)__builtin_ia32_rcp28pd_mask((__v8df)(__m512d)(A), \ + (__v8df)_mm512_setzero_pd(), \ + (__mmask8)-1, (R)); }) + +#define _mm512_mask_rcp28_round_pd(S, M, A, R) __extension__ ({ \ + (__m512d)__builtin_ia32_rcp28pd_mask((__v8df)(__m512d)(A), \ + (__v8df)(__m512d)(S), \ + (__mmask8)(M), (R)); }) + +#define _mm512_maskz_rcp28_round_pd(M, A, R) __extension__ ({ \ + (__m512d)__builtin_ia32_rcp28pd_mask((__v8df)(__m512d)(A), \ + (__v8df)_mm512_setzero_pd(), \ + (__mmask8)(M), (R)); }) + +#define _mm512_rcp28_pd(A) \ + _mm512_rcp28_round_pd((A), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_mask_rcp28_pd(S, M, A) \ + _mm512_mask_rcp28_round_pd((S), (M), (A), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_maskz_rcp28_pd(M, A) \ + _mm512_maskz_rcp28_round_pd((M), (A), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_rcp28_round_ps(A, R) __extension__ ({ \ + (__m512)__builtin_ia32_rcp28ps_mask((__v16sf)(__m512)(A), \ + (__v16sf)_mm512_setzero_ps(), \ + (__mmask16)-1, (R)); }) + +#define _mm512_mask_rcp28_round_ps(S, M, A, R) __extension__ ({ \ + (__m512)__builtin_ia32_rcp28ps_mask((__v16sf)(__m512)(A), \ + (__v16sf)(__m512)(S), \ + (__mmask16)(M), (R)); }) + +#define _mm512_maskz_rcp28_round_ps(M, A, R) __extension__ ({ \ + (__m512)__builtin_ia32_rcp28ps_mask((__v16sf)(__m512)(A), \ + (__v16sf)_mm512_setzero_ps(), \ + (__mmask16)(M), (R)); }) + +#define _mm512_rcp28_ps(A) \ + _mm512_rcp28_round_ps((A), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_mask_rcp28_ps(S, M, A) \ + _mm512_mask_rcp28_round_ps((S), (M), (A), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_maskz_rcp28_ps(M, A) \ + _mm512_maskz_rcp28_round_ps((M), (A), _MM_FROUND_CUR_DIRECTION) + +#define _mm_rcp28_round_ss(A, B, R) __extension__ ({ \ + (__m128)__builtin_ia32_rcp28ss_mask((__v4sf)(__m128)(A), \ + (__v4sf)(__m128)(B), \ + (__v4sf)_mm_setzero_ps(), \ + (__mmask8)-1, (R)); }) + +#define _mm_mask_rcp28_round_ss(S, M, A, B, R) __extension__ ({ \ + (__m128)__builtin_ia32_rcp28ss_mask((__v4sf)(__m128)(A), \ + (__v4sf)(__m128)(B), \ + (__v4sf)(__m128)(S), \ + (__mmask8)(M), (R)); }) + +#define _mm_maskz_rcp28_round_ss(M, A, B, R) __extension__ ({ \ + (__m128)__builtin_ia32_rcp28ss_mask((__v4sf)(__m128)(A), \ + (__v4sf)(__m128)(B), \ + (__v4sf)_mm_setzero_ps(), \ + (__mmask8)(M), (R)); }) + +#define _mm_rcp28_ss(A, B) \ + _mm_rcp28_round_ss((A), (B), _MM_FROUND_CUR_DIRECTION) + +#define _mm_mask_rcp28_ss(S, M, A, B) \ + _mm_mask_rcp28_round_ss((S), (M), (A), (B), _MM_FROUND_CUR_DIRECTION) + +#define _mm_maskz_rcp28_ss(M, A, B) \ + _mm_maskz_rcp28_round_ss((M), (A), (B), _MM_FROUND_CUR_DIRECTION) + +#define _mm_rcp28_round_sd(A, B, R) __extension__ ({ \ + (__m128d)__builtin_ia32_rcp28sd_mask((__v2df)(__m128d)(A), \ + (__v2df)(__m128d)(B), \ + (__v2df)_mm_setzero_pd(), \ + (__mmask8)-1, (R)); }) + +#define _mm_mask_rcp28_round_sd(S, M, A, B, R) __extension__ ({ \ + (__m128d)__builtin_ia32_rcp28sd_mask((__v2df)(__m128d)(A), \ + (__v2df)(__m128d)(B), \ + (__v2df)(__m128d)(S), \ + (__mmask8)(M), (R)); }) + +#define _mm_maskz_rcp28_round_sd(M, A, B, R) __extension__ ({ \ + (__m128d)__builtin_ia32_rcp28sd_mask((__v2df)(__m128d)(A), \ + (__v2df)(__m128d)(B), \ + (__v2df)_mm_setzero_pd(), \ + (__mmask8)(M), (R)); }) + +#define _mm_rcp28_sd(A, B) \ + _mm_rcp28_round_sd((A), (B), _MM_FROUND_CUR_DIRECTION) + +#define _mm_mask_rcp28_sd(S, M, A, B) \ + _mm_mask_rcp28_round_sd((S), (M), (A), (B), _MM_FROUND_CUR_DIRECTION) + +#define _mm_maskz_rcp28_sd(M, A, B) \ + _mm_maskz_rcp28_round_sd((M), (A), (B), _MM_FROUND_CUR_DIRECTION) + +#endif // __AVX512ERINTRIN_H diff --git a/headers/clang/avx512fintrin.h b/headers/clang/avx512fintrin.h new file mode 100644 index 0000000000..9d31da7cb9 --- /dev/null +++ b/headers/clang/avx512fintrin.h @@ -0,0 +1,3084 @@ +/*===---- avx512fintrin.h - AVX512F intrinsics -----------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __AVX512FINTRIN_H +#define __AVX512FINTRIN_H + +typedef double __v8df __attribute__((__vector_size__(64))); +typedef float __v16sf __attribute__((__vector_size__(64))); +typedef long long __v8di __attribute__((__vector_size__(64))); +typedef int __v16si __attribute__((__vector_size__(64))); + +typedef float __m512 __attribute__((__vector_size__(64))); +typedef double __m512d __attribute__((__vector_size__(64))); +typedef long long __m512i __attribute__((__vector_size__(64))); + +typedef unsigned char __mmask8; +typedef unsigned short __mmask16; + +/* Rounding mode macros. */ +#define _MM_FROUND_TO_NEAREST_INT 0x00 +#define _MM_FROUND_TO_NEG_INF 0x01 +#define _MM_FROUND_TO_POS_INF 0x02 +#define _MM_FROUND_TO_ZERO 0x03 +#define _MM_FROUND_CUR_DIRECTION 0x04 + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512f"))) + +/* Create vectors with repeated elements */ + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_setzero_si512(void) +{ + return (__m512i)(__v8di){ 0, 0, 0, 0, 0, 0, 0, 0 }; +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_undefined_pd() +{ + return (__m512d)__builtin_ia32_undef512(); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_undefined() +{ + return (__m512)__builtin_ia32_undef512(); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_undefined_ps() +{ + return (__m512)__builtin_ia32_undef512(); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_undefined_epi32() +{ + return (__m512i)__builtin_ia32_undef512(); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_set1_epi32(__mmask16 __M, int __A) +{ + return (__m512i) __builtin_ia32_pbroadcastd512_gpr_mask (__A, + (__v16si) + _mm512_setzero_si512 (), + __M); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_set1_epi64(__mmask8 __M, long long __A) +{ +#ifdef __x86_64__ + return (__m512i) __builtin_ia32_pbroadcastq512_gpr_mask (__A, + (__v8di) + _mm512_setzero_si512 (), + __M); +#else + return (__m512i) __builtin_ia32_pbroadcastq512_mem_mask (__A, + (__v8di) + _mm512_setzero_si512 (), + __M); +#endif +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_setzero_ps(void) +{ + return (__m512){ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; +} +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_setzero_pd(void) +{ + return (__m512d){ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_set1_ps(float __w) +{ + return (__m512){ __w, __w, __w, __w, __w, __w, __w, __w, + __w, __w, __w, __w, __w, __w, __w, __w }; +} + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_set1_pd(double __w) +{ + return (__m512d){ __w, __w, __w, __w, __w, __w, __w, __w }; +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_set1_epi32(int __s) +{ + return (__m512i)(__v16si){ __s, __s, __s, __s, __s, __s, __s, __s, + __s, __s, __s, __s, __s, __s, __s, __s }; +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_set1_epi64(long long __d) +{ + return (__m512i)(__v8di){ __d, __d, __d, __d, __d, __d, __d, __d }; +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_broadcastss_ps(__m128 __X) +{ + float __f = __X[0]; + return (__v16sf){ __f, __f, __f, __f, + __f, __f, __f, __f, + __f, __f, __f, __f, + __f, __f, __f, __f }; +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_broadcastsd_pd(__m128d __X) +{ + double __d = __X[0]; + return (__v8df){ __d, __d, __d, __d, + __d, __d, __d, __d }; +} + +/* Cast between vector types */ + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_castpd256_pd512(__m256d __a) +{ + return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, -1, -1, -1, -1); +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_castps256_ps512(__m256 __a) +{ + return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, 4, 5, 6, 7, + -1, -1, -1, -1, -1, -1, -1, -1); +} + +static __inline __m128d __DEFAULT_FN_ATTRS +_mm512_castpd512_pd128(__m512d __a) +{ + return __builtin_shufflevector(__a, __a, 0, 1); +} + +static __inline __m128 __DEFAULT_FN_ATTRS +_mm512_castps512_ps128(__m512 __a) +{ + return __builtin_shufflevector(__a, __a, 0, 1, 2, 3); +} + +/* Bitwise operators */ +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_and_epi32(__m512i __a, __m512i __b) +{ + return __a & __b; +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_and_epi32(__m512i __src, __mmask16 __k, __m512i __a, __m512i __b) +{ + return (__m512i) __builtin_ia32_pandd512_mask((__v16si) __a, + (__v16si) __b, + (__v16si) __src, + (__mmask16) __k); +} +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_and_epi32(__mmask16 __k, __m512i __a, __m512i __b) +{ + return (__m512i) __builtin_ia32_pandd512_mask((__v16si) __a, + (__v16si) __b, + (__v16si) + _mm512_setzero_si512 (), + (__mmask16) __k); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_and_epi64(__m512i __a, __m512i __b) +{ + return __a & __b; +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_and_epi64(__m512i __src, __mmask8 __k, __m512i __a, __m512i __b) +{ + return (__m512i) __builtin_ia32_pandq512_mask ((__v8di) __a, + (__v8di) __b, + (__v8di) __src, + (__mmask8) __k); +} +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_and_epi64(__mmask8 __k, __m512i __a, __m512i __b) +{ + return (__m512i) __builtin_ia32_pandq512_mask ((__v8di) __a, + (__v8di) __b, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) __k); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_andnot_epi32 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pandnd512_mask ((__v16si) __A, + (__v16si) __B, + (__v16si) + _mm512_setzero_si512 (), + (__mmask16) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_andnot_epi32 (__m512i __W, __mmask16 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pandnd512_mask ((__v16si) __A, + (__v16si) __B, + (__v16si) __W, + (__mmask16) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_andnot_epi32 (__mmask16 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pandnd512_mask ((__v16si) __A, + (__v16si) __B, + (__v16si) + _mm512_setzero_si512 (), + (__mmask16) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_andnot_epi64 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pandnq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) -1); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_andnot_epi64 (__m512i __W, __mmask8 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pandnq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) __W, __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_andnot_epi64 (__mmask8 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pandnq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) + _mm512_setzero_pd (), + __U); +} +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_or_epi32(__m512i __a, __m512i __b) +{ + return __a | __b; +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_or_epi32(__m512i __src, __mmask16 __k, __m512i __a, __m512i __b) +{ + return (__m512i) __builtin_ia32_pord512_mask((__v16si) __a, + (__v16si) __b, + (__v16si) __src, + (__mmask16) __k); +} +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_or_epi32(__mmask16 __k, __m512i __a, __m512i __b) +{ + return (__m512i) __builtin_ia32_pord512_mask((__v16si) __a, + (__v16si) __b, + (__v16si) + _mm512_setzero_si512 (), + (__mmask16) __k); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_or_epi64(__m512i __a, __m512i __b) +{ + return __a | __b; +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_or_epi64(__m512i __src, __mmask8 __k, __m512i __a, __m512i __b) +{ + return (__m512i) __builtin_ia32_porq512_mask ((__v8di) __a, + (__v8di) __b, + (__v8di) __src, + (__mmask8) __k); +} +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_or_epi64(__mmask8 __k, __m512i __a, __m512i __b) +{ + return (__m512i) __builtin_ia32_porq512_mask ((__v8di) __a, + (__v8di) __b, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) __k); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_xor_epi32(__m512i __a, __m512i __b) +{ + return __a ^ __b; +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_xor_epi32(__m512i __src, __mmask16 __k, __m512i __a, __m512i __b) +{ + return (__m512i) __builtin_ia32_pxord512_mask((__v16si) __a, + (__v16si) __b, + (__v16si) __src, + (__mmask16) __k); +} +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_xor_epi32(__mmask16 __k, __m512i __a, __m512i __b) +{ + return (__m512i) __builtin_ia32_pxord512_mask((__v16si) __a, + (__v16si) __b, + (__v16si) + _mm512_setzero_si512 (), + (__mmask16) __k); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_xor_epi64(__m512i __a, __m512i __b) +{ + return __a ^ __b; +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_xor_epi64(__m512i __src, __mmask8 __k, __m512i __a, __m512i __b) +{ + return (__m512i) __builtin_ia32_pxorq512_mask ((__v8di) __a, + (__v8di) __b, + (__v8di) __src, + (__mmask8) __k); +} +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_xor_epi64(__mmask8 __k, __m512i __a, __m512i __b) +{ + return (__m512i) __builtin_ia32_pxorq512_mask ((__v8di) __a, + (__v8di) __b, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) __k); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_and_si512(__m512i __a, __m512i __b) +{ + return __a & __b; +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_or_si512(__m512i __a, __m512i __b) +{ + return __a | __b; +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_xor_si512(__m512i __a, __m512i __b) +{ + return __a ^ __b; +} +/* Arithmetic */ + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_add_pd(__m512d __a, __m512d __b) +{ + return __a + __b; +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_add_ps(__m512 __a, __m512 __b) +{ + return __a + __b; +} + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_mul_pd(__m512d __a, __m512d __b) +{ + return __a * __b; +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_mul_ps(__m512 __a, __m512 __b) +{ + return __a * __b; +} + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_sub_pd(__m512d __a, __m512d __b) +{ + return __a - __b; +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_sub_ps(__m512 __a, __m512 __b) +{ + return __a - __b; +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_add_epi64 (__m512i __A, __m512i __B) +{ + return (__m512i) ((__v8di) __A + (__v8di) __B); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_add_epi64 (__m512i __W, __mmask8 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_paddq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) __W, + (__mmask8) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_add_epi64 (__mmask8 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_paddq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_sub_epi64 (__m512i __A, __m512i __B) +{ + return (__m512i) ((__v8di) __A - (__v8di) __B); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_sub_epi64 (__m512i __W, __mmask8 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_psubq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) __W, + (__mmask8) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_sub_epi64 (__mmask8 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_psubq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_add_epi32 (__m512i __A, __m512i __B) +{ + return (__m512i) ((__v16si) __A + (__v16si) __B); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_add_epi32 (__m512i __W, __mmask16 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_paddd512_mask ((__v16si) __A, + (__v16si) __B, + (__v16si) __W, + (__mmask16) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_add_epi32 (__mmask16 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_paddd512_mask ((__v16si) __A, + (__v16si) __B, + (__v16si) + _mm512_setzero_si512 (), + (__mmask16) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_sub_epi32 (__m512i __A, __m512i __B) +{ + return (__m512i) ((__v16si) __A - (__v16si) __B); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_mask_sub_epi32 (__m512i __W, __mmask16 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_psubd512_mask ((__v16si) __A, + (__v16si) __B, + (__v16si) __W, + (__mmask16) __U); +} + +static __inline__ __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_sub_epi32 (__mmask16 __U, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_psubd512_mask ((__v16si) __A, + (__v16si) __B, + (__v16si) + _mm512_setzero_si512 (), + (__mmask16) __U); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_max_pd(__m512d __A, __m512d __B) +{ + return (__m512d) __builtin_ia32_maxpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_max_ps(__m512 __A, __m512 __B) +{ + return (__m512) __builtin_ia32_maxps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_max_ss(__m128 __W, __mmask8 __U,__m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_maxss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_max_ss(__mmask8 __U,__m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_maxss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) _mm_setzero_ps (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm_max_round_ss(__A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_maxss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) -1, __R); }) + +#define _mm_mask_max_round_ss(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_maxss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) __W, (__mmask8) __U,__R); }) + +#define _mm_maskz_max_round_ss(__U, __A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_maxss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) __U,__R); }) + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_max_sd(__m128d __W, __mmask8 __U,__m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_maxsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_max_sd(__mmask8 __U,__m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_maxsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) _mm_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm_max_round_sd(__A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_maxsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) _mm_setzero_pd(), (__mmask8) -1, __R); }) + +#define _mm_mask_max_round_sd(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_maxsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) __W, (__mmask8) __U,__R); }) + +#define _mm_maskz_max_round_sd(__U, __A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_maxsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) _mm_setzero_pd(), (__mmask8) __U,__R); }) + +static __inline __m512i +__DEFAULT_FN_ATTRS +_mm512_max_epi32(__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxsd512_mask ((__v16si) __A, + (__v16si) __B, + (__v16si) + _mm512_setzero_si512 (), + (__mmask16) -1); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_max_epu32(__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxud512_mask ((__v16si) __A, + (__v16si) __B, + (__v16si) + _mm512_setzero_si512 (), + (__mmask16) -1); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_max_epi64(__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxsq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) -1); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_max_epu64(__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmaxuq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) -1); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_min_pd(__m512d __A, __m512d __B) +{ + return (__m512d) __builtin_ia32_minpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_min_ps(__m512 __A, __m512 __B) +{ + return (__m512) __builtin_ia32_minps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_min_ss(__m128 __W, __mmask8 __U,__m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_minss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_min_ss(__mmask8 __U,__m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_minss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) _mm_setzero_ps (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm_min_round_ss(__A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_minss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) -1, __R); }) + +#define _mm_mask_min_round_ss(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_minss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) __W, (__mmask8) __U,__R); }) + +#define _mm_maskz_min_round_ss(__U, __A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_minss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) __U,__R); }) + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_min_sd(__m128d __W, __mmask8 __U,__m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_minsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_min_sd(__mmask8 __U,__m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_minsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) _mm_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm_min_round_sd(__A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_minsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) _mm_setzero_pd(), (__mmask8) -1, __R); }) + +#define _mm_mask_min_round_sd(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_minsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) __W, (__mmask8) __U,__R); }) + +#define _mm_maskz_min_round_sd(__U, __A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_minsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) _mm_setzero_pd(), (__mmask8) __U,__R); }) + +static __inline __m512i +__DEFAULT_FN_ATTRS +_mm512_min_epi32(__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pminsd512_mask ((__v16si) __A, + (__v16si) __B, + (__v16si) + _mm512_setzero_si512 (), + (__mmask16) -1); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_min_epu32(__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pminud512_mask ((__v16si) __A, + (__v16si) __B, + (__v16si) + _mm512_setzero_si512 (), + (__mmask16) -1); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_min_epi64(__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pminsq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) -1); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_min_epu64(__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pminuq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) -1); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_mul_epi32(__m512i __X, __m512i __Y) +{ + return (__m512i) __builtin_ia32_pmuldq512_mask ((__v16si) __X, + (__v16si) __Y, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) -1); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_mask_mul_epi32 (__m512i __W, __mmask8 __M, __m512i __X, __m512i __Y) +{ + return (__m512i) __builtin_ia32_pmuldq512_mask ((__v16si) __X, + (__v16si) __Y, + (__v8di) __W, __M); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_mul_epi32 (__mmask8 __M, __m512i __X, __m512i __Y) +{ + return (__m512i) __builtin_ia32_pmuldq512_mask ((__v16si) __X, + (__v16si) __Y, + (__v8di) + _mm512_setzero_si512 (), + __M); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_mul_epu32(__m512i __X, __m512i __Y) +{ + return (__m512i) __builtin_ia32_pmuludq512_mask ((__v16si) __X, + (__v16si) __Y, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) -1); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_mask_mul_epu32 (__m512i __W, __mmask8 __M, __m512i __X, __m512i __Y) +{ + return (__m512i) __builtin_ia32_pmuludq512_mask ((__v16si) __X, + (__v16si) __Y, + (__v8di) __W, __M); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_mul_epu32 (__mmask8 __M, __m512i __X, __m512i __Y) +{ + return (__m512i) __builtin_ia32_pmuludq512_mask ((__v16si) __X, + (__v16si) __Y, + (__v8di) + _mm512_setzero_si512 (), + __M); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_mullo_epi32 (__m512i __A, __m512i __B) +{ + return (__m512i) ((__v16si) __A * (__v16si) __B); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_mullo_epi32 (__mmask16 __M, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmulld512_mask ((__v16si) __A, + (__v16si) __B, + (__v16si) + _mm512_setzero_si512 (), + __M); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_mask_mullo_epi32 (__m512i __W, __mmask16 __M, __m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_pmulld512_mask ((__v16si) __A, + (__v16si) __B, + (__v16si) __W, __M); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_sqrt_pd(__m512d __a) +{ + return (__m512d)__builtin_ia32_sqrtpd512_mask((__v8df)__a, + (__v8df) _mm512_setzero_pd (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_sqrt_ps(__m512 __a) +{ + return (__m512)__builtin_ia32_sqrtps512_mask((__v16sf)__a, + (__v16sf) _mm512_setzero_ps (), + (__mmask16) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_rsqrt14_pd(__m512d __A) +{ + return (__m512d) __builtin_ia32_rsqrt14pd512_mask ((__v8df) __A, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) -1);} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_rsqrt14_ps(__m512 __A) +{ + return (__m512) __builtin_ia32_rsqrt14ps512_mask ((__v16sf) __A, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) -1); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_rsqrt14_ss(__m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_rsqrt14ss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) -1); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_rsqrt14_sd(__m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_rsqrt14sd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_setzero_pd (), + (__mmask8) -1); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_rcp14_pd(__m512d __A) +{ + return (__m512d) __builtin_ia32_rcp14pd512_mask ((__v8df) __A, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) -1); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_rcp14_ps(__m512 __A) +{ + return (__m512) __builtin_ia32_rcp14ps512_mask ((__v16sf) __A, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) -1); +} +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_rcp14_ss(__m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_rcp14ss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) -1); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_rcp14_sd(__m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_rcp14sd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_setzero_pd (), + (__mmask8) -1); +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_floor_ps(__m512 __A) +{ + return (__m512) __builtin_ia32_rndscaleps_mask ((__v16sf) __A, + _MM_FROUND_FLOOR, + (__v16sf) __A, -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_floor_pd(__m512d __A) +{ + return (__m512d) __builtin_ia32_rndscalepd_mask ((__v8df) __A, + _MM_FROUND_FLOOR, + (__v8df) __A, -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_ceil_ps(__m512 __A) +{ + return (__m512) __builtin_ia32_rndscaleps_mask ((__v16sf) __A, + _MM_FROUND_CEIL, + (__v16sf) __A, -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_ceil_pd(__m512d __A) +{ + return (__m512d) __builtin_ia32_rndscalepd_mask ((__v8df) __A, + _MM_FROUND_CEIL, + (__v8df) __A, -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_abs_epi64(__m512i __A) +{ + return (__m512i) __builtin_ia32_pabsq512_mask ((__v8di) __A, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) -1); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_abs_epi32(__m512i __A) +{ + return (__m512i) __builtin_ia32_pabsd512_mask ((__v16si) __A, + (__v16si) + _mm512_setzero_si512 (), + (__mmask16) -1); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_add_ss(__m128 __W, __mmask8 __U,__m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_addss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_add_ss(__mmask8 __U,__m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_addss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) _mm_setzero_ps (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm_add_round_ss(__A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_addss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) -1, __R); }) + +#define _mm_mask_add_round_ss(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_addss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) __W, (__mmask8) __U,__R); }) + +#define _mm_maskz_add_round_ss(__U, __A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_addss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) __U,__R); }) + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_add_sd(__m128d __W, __mmask8 __U,__m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_addsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_add_sd(__mmask8 __U,__m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_addsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) _mm_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +#define _mm_add_round_sd(__A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_addsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) _mm_setzero_pd(), (__mmask8) -1, __R); }) + +#define _mm_mask_add_round_sd(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_addsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) __W, (__mmask8) __U,__R); }) + +#define _mm_maskz_add_round_sd(__U, __A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_addsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) _mm_setzero_pd(), (__mmask8) __U,__R); }) + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_add_pd(__m512d __W, __mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_addpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_add_pd(__mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_addpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) _mm512_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask_add_ps(__m512 __W, __mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_addps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __W, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_add_ps(__mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_addps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) _mm512_setzero_ps (), + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_add_round_pd(__A, __B, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_addpd512_mask ((__v8df) __A, (__v8df) __B, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) -1, __R); }) + +#define _mm512_mask_add_round_pd(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_addpd512_mask((__v8df) __A, (__v8df) __B, \ + (__v8df) __W, (__mmask8) __U, __R); }) + +#define _mm512_maskz_add_round_pd(__U, __A, __B, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_addpd512_mask ((__v8df) __A, (__v8df) __B, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) __U, __R); }) + +#define _mm512_add_round_ps(__A, __B, __R) __extension__ ({ \ + (__m512) __builtin_ia32_addps512_mask ((__v16sf) __A, (__v16sf) __B, \ + (__v16sf) _mm512_setzero_ps(), (__mmask16) -1, __R); }) + +#define _mm512_mask_add_round_ps(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m512) __builtin_ia32_addps512_mask ((__v16sf) __A, (__v16sf) __B, \ + (__v16sf) __W, (__mmask16)__U, __R); }) + +#define _mm512_maskz_add_round_ps(__U, __A, __B, __R) __extension__ ({ \ + (__m512) __builtin_ia32_addps512_mask ((__v16sf) __A, (__v16sf) __B, \ + (__v16sf) _mm512_setzero_ps(), (__mmask16)__U, __R); }) + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_sub_ss(__m128 __W, __mmask8 __U,__m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_subss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_sub_ss(__mmask8 __U,__m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_subss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) _mm_setzero_ps (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +#define _mm_sub_round_ss(__A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_subss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) -1, __R); }) + +#define _mm_mask_sub_round_ss(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_subss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) __W, (__mmask8) __U,__R); }) + +#define _mm_maskz_sub_round_ss(__U, __A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_subss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) __U,__R); }) + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_sub_sd(__m128d __W, __mmask8 __U,__m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_subsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_sub_sd(__mmask8 __U,__m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_subsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) _mm_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm_sub_round_sd(__A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_subsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) _mm_setzero_pd(), (__mmask8) -1, __R); }) + +#define _mm_mask_sub_round_sd(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_subsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) __W, (__mmask8) __U,__R); }) + +#define _mm_maskz_sub_round_sd(__U, __A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_subsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) _mm_setzero_pd(), (__mmask8) __U,__R); }) + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_sub_pd(__m512d __W, __mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_subpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_sub_pd(__mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_subpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask_sub_ps(__m512 __W, __mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_subps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __W, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_sub_ps(__mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_subps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_sub_round_pd(__A, __B, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_subpd512_mask ((__v8df) __A, (__v8df) __B,\ + (__v8df) _mm512_setzero_pd(), (__mmask8) -1, __R); }) + +#define _mm512_mask_sub_round_pd(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_subpd512_mask ((__v8df) __A, (__v8df) __B, \ + (__v8df) __W, (__mmask8) __U, __R); }) + +#define _mm512_maskz_sub_round_pd(__U, __A, __B, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_subpd512_mask ((__v8df) __A, (__v8df) __B, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) __U, __R);}) + +#define _mm512_sub_round_ps(__A, __B, __R) __extension__ ({ \ + (__m512) __builtin_ia32_subps512_mask ((__v16sf) __A, (__v16sf) __B, \ + (__v16sf) _mm512_setzero_ps (), (__mmask16) -1, __R);}) + +#define _mm512_mask_sub_round_ps(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m512) __builtin_ia32_subps512_mask ((__v16sf) __A, (__v16sf) __B, \ + (__v16sf) __W, (__mmask16) __U, __R); }); + +#define _mm512_maskz_sub_round_ps(__U, __A, __B, __R) __extension__ ({ \ + (__m512) __builtin_ia32_subps512_mask ((__v16sf) __A, (__v16sf) __B, \ + (__v16sf) _mm512_setzero_ps (), (__mmask16) __U, __R);}); + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_mul_ss(__m128 __W, __mmask8 __U,__m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_mulss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_mul_ss(__mmask8 __U,__m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_mulss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) _mm_setzero_ps (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +#define _mm_mul_round_ss(__A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_mulss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) -1, __R); }) + +#define _mm_mask_mul_round_ss(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_mulss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) __W, (__mmask8) __U,__R); }) + +#define _mm_maskz_mul_round_ss(__U, __A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_mulss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) __U,__R); }) + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_mul_sd(__m128d __W, __mmask8 __U,__m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_mulsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_mul_sd(__mmask8 __U,__m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_mulsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) _mm_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm_mul_round_sd(__A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_mulsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) _mm_setzero_pd(), (__mmask8) -1, __R); }) + +#define _mm_mask_mul_round_sd(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_mulsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) __W, (__mmask8) __U,__R); }) + +#define _mm_maskz_mul_round_sd(__U, __A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_mulsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) _mm_setzero_pd(), (__mmask8) __U,__R); }) + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_mul_pd(__m512d __W, __mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_mulpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_mul_pd(__mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_mulpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask_mul_ps(__m512 __W, __mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_mulps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __W, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_mul_ps(__mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_mulps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_mul_round_pd(__A, __B, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_mulpd512_mask ((__v8df) __A, (__v8df) __B,\ + (__v8df) _mm512_setzero_pd(), (__mmask8) -1, __R); }) + +#define _mm512_mask_mul_round_pd(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_mulpd512_mask ((__v8df) __A, (__v8df) __B, \ + (__v8df) __W, (__mmask8) __U, __R); }) + +#define _mm512_maskz_mul_round_pd(__U, __A, __B, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_mulpd512_mask ((__v8df) __A, (__v8df) __B, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) __U, __R);}) + +#define _mm512_mul_round_ps(__A, __B, __R) __extension__ ({ \ + (__m512) __builtin_ia32_mulps512_mask ((__v16sf) __A, (__v16sf) __B, \ + (__v16sf) _mm512_setzero_ps (), (__mmask16) -1, __R);}) + +#define _mm512_mask_mul_round_ps(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m512) __builtin_ia32_mulps512_mask ((__v16sf) __A, (__v16sf) __B, \ + (__v16sf) __W, (__mmask16) __U, __R); }); + +#define _mm512_maskz_mul_round_ps(__U, __A, __B, __R) __extension__ ({ \ + (__m512) __builtin_ia32_mulps512_mask ((__v16sf) __A, (__v16sf) __B, \ + (__v16sf) _mm512_setzero_ps (), (__mmask16) __U, __R);}); + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_div_ss(__m128 __W, __mmask8 __U,__m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_divss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_div_ss(__mmask8 __U,__m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_divss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) _mm_setzero_ps (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm_div_round_ss(__A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_divss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) -1, __R); }) + +#define _mm_mask_div_round_ss(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_divss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) __W, (__mmask8) __U,__R); }) + +#define _mm_maskz_div_round_ss(__U, __A, __B, __R) __extension__ ({ \ + (__m128) __builtin_ia32_divss_mask ((__v4sf) __A, (__v4sf) __B, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) __U,__R); }) + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_div_sd(__m128d __W, __mmask8 __U,__m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_divsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_div_sd(__mmask8 __U,__m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_divsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) _mm_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm_div_round_sd(__A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_divsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) _mm_setzero_pd(), (__mmask8) -1, __R); }) + +#define _mm_mask_div_round_sd(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_divsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) __W, (__mmask8) __U,__R); }) + +#define _mm_maskz_div_round_sd(__U, __A, __B, __R) __extension__ ({ \ + (__m128d) __builtin_ia32_divsd_mask ((__v2df) __A, (__v2df) __B, \ + (__v2df) _mm_setzero_pd(), (__mmask8) __U,__R); }) + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_div_pd(__m512d __W, __mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_divpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_div_pd(__mmask8 __U, __m512d __A, __m512d __B) { + return (__m512d) __builtin_ia32_divpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask_div_ps(__m512 __W, __mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_divps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __W, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_div_ps(__mmask16 __U, __m512 __A, __m512 __B) { + return (__m512) __builtin_ia32_divps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_div_round_pd(__A, __B, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_divpd512_mask ((__v8df) __A, (__v8df) __B,\ + (__v8df) _mm512_setzero_pd(), (__mmask8) -1, __R); }) + +#define _mm512_mask_div_round_pd(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_divpd512_mask ((__v8df) __A, (__v8df) __B, \ + (__v8df) __W, (__mmask8) __U, __R); }) + +#define _mm512_maskz_div_round_pd(__U, __A, __B, __R) __extension__ ({ \ + (__m512d) __builtin_ia32_divpd512_mask ((__v8df) __A, (__v8df) __B, \ + (__v8df) _mm512_setzero_pd(), (__mmask8) __U, __R);}) + +#define _mm512_div_round_ps(__A, __B, __R) __extension__ ({ \ + (__m512) __builtin_ia32_divps512_mask ((__v16sf) __A, (__v16sf) __B, \ + (__v16sf) _mm512_setzero_ps (), (__mmask16) -1, __R);}) + +#define _mm512_mask_div_round_ps(__W, __U, __A, __B, __R) __extension__ ({ \ + (__m512) __builtin_ia32_divps512_mask ((__v16sf) __A, (__v16sf) __B, \ + (__v16sf) __W, (__mmask16) __U, __R); }); + +#define _mm512_maskz_div_round_ps(__U, __A, __B, __R) __extension__ ({ \ + (__m512) __builtin_ia32_divps512_mask ((__v16sf) __A, (__v16sf) __B, \ + (__v16sf) _mm512_setzero_ps (), (__mmask16) __U, __R);}); + +#define _mm512_roundscale_ps(A, B) __extension__ ({ \ + (__m512)__builtin_ia32_rndscaleps_mask((__v16sf)(A), (B), (__v16sf)(A), \ + -1, _MM_FROUND_CUR_DIRECTION); }) + +#define _mm512_roundscale_pd(A, B) __extension__ ({ \ + (__m512d)__builtin_ia32_rndscalepd_mask((__v8df)(A), (B), (__v8df)(A), \ + -1, _MM_FROUND_CUR_DIRECTION); }) + +#define _mm512_fmadd_round_pd(A, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddpd512_mask ((__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) -1, (R)); }) + + +#define _mm512_mask_fmadd_round_pd(A, U, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddpd512_mask ((__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +#define _mm512_mask3_fmadd_round_pd(A, B, C, U, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddpd512_mask3 ((__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +#define _mm512_maskz_fmadd_round_pd(U, A, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddpd512_maskz ((__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +#define _mm512_fmsub_round_pd(A, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddpd512_mask ((__v8df) (A), \ + (__v8df) (B), -(__v8df) (C), \ + (__mmask8) -1, (R)); }) + + +#define _mm512_mask_fmsub_round_pd(A, U, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddpd512_mask ((__v8df) (A), \ + (__v8df) (B), -(__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +#define _mm512_maskz_fmsub_round_pd(U, A, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddpd512_maskz ((__v8df) (A), \ + (__v8df) (B), -(__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +#define _mm512_fnmadd_round_pd(A, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddpd512_mask (-(__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) -1, (R)); }) + + +#define _mm512_mask3_fnmadd_round_pd(A, B, C, U, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddpd512_mask3 (-(__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +#define _mm512_maskz_fnmadd_round_pd(U, A, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddpd512_maskz (-(__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +#define _mm512_fnmsub_round_pd(A, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddpd512_mask (-(__v8df) (A), \ + (__v8df) (B), -(__v8df) (C), \ + (__mmask8) -1, (R)); }) + + +#define _mm512_maskz_fnmsub_round_pd(U, A, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddpd512_maskz (-(__v8df) (A), \ + (__v8df) (B), -(__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_fmadd_pd(__m512d __A, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_fmadd_pd(__m512d __A, __mmask8 __U, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask3_fmadd_pd(__m512d __A, __m512d __B, __m512d __C, __mmask8 __U) +{ + return (__m512d) __builtin_ia32_vfmaddpd512_mask3 ((__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_fmadd_pd(__mmask8 __U, __m512d __A, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddpd512_maskz ((__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_fmsub_pd(__m512d __A, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddpd512_mask ((__v8df) __A, + (__v8df) __B, + -(__v8df) __C, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_fmsub_pd(__m512d __A, __mmask8 __U, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddpd512_mask ((__v8df) __A, + (__v8df) __B, + -(__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_fmsub_pd(__mmask8 __U, __m512d __A, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddpd512_maskz ((__v8df) __A, + (__v8df) __B, + -(__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_fnmadd_pd(__m512d __A, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddpd512_mask (-(__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask3_fnmadd_pd(__m512d __A, __m512d __B, __m512d __C, __mmask8 __U) +{ + return (__m512d) __builtin_ia32_vfmaddpd512_mask3 (-(__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_fnmadd_pd(__mmask8 __U, __m512d __A, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddpd512_maskz (-(__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_fnmsub_pd(__m512d __A, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddpd512_mask (-(__v8df) __A, + (__v8df) __B, + -(__v8df) __C, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_fnmsub_pd(__mmask8 __U, __m512d __A, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddpd512_maskz (-(__v8df) __A, + (__v8df) __B, + -(__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_fmadd_round_ps(A, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddps512_mask ((__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) -1, (R)); }) + + +#define _mm512_mask_fmadd_round_ps(A, U, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddps512_mask ((__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +#define _mm512_mask3_fmadd_round_ps(A, B, C, U, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddps512_mask3 ((__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +#define _mm512_maskz_fmadd_round_ps(U, A, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddps512_maskz ((__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +#define _mm512_fmsub_round_ps(A, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddps512_mask ((__v16sf) (A), \ + (__v16sf) (B), -(__v16sf) (C), \ + (__mmask16) -1, (R)); }) + + +#define _mm512_mask_fmsub_round_ps(A, U, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddps512_mask ((__v16sf) (A), \ + (__v16sf) (B), -(__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +#define _mm512_maskz_fmsub_round_ps(U, A, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddps512_maskz ((__v16sf) (A), \ + (__v16sf) (B), -(__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +#define _mm512_fnmadd_round_ps(A, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddps512_mask (-(__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) -1, (R)); }) + + +#define _mm512_mask3_fnmadd_round_ps(A, B, C, U, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddps512_mask3 (-(__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +#define _mm512_maskz_fnmadd_round_ps(U, A, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddps512_maskz (-(__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +#define _mm512_fnmsub_round_ps(A, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddps512_mask (-(__v16sf) (A), \ + (__v16sf) (B), -(__v16sf) (C), \ + (__mmask16) -1, (R)); }) + + +#define _mm512_maskz_fnmsub_round_ps(U, A, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddps512_maskz (-(__v16sf) (A), \ + (__v16sf) (B), -(__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_fmadd_ps(__m512 __A, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask_fmadd_ps(__m512 __A, __mmask16 __U, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask3_fmadd_ps(__m512 __A, __m512 __B, __m512 __C, __mmask16 __U) +{ + return (__m512) __builtin_ia32_vfmaddps512_mask3 ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_fmadd_ps(__mmask16 __U, __m512 __A, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddps512_maskz ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_fmsub_ps(__m512 __A, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddps512_mask ((__v16sf) __A, + (__v16sf) __B, + -(__v16sf) __C, + (__mmask16) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask_fmsub_ps(__m512 __A, __mmask16 __U, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddps512_mask ((__v16sf) __A, + (__v16sf) __B, + -(__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_fmsub_ps(__mmask16 __U, __m512 __A, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddps512_maskz ((__v16sf) __A, + (__v16sf) __B, + -(__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_fnmadd_ps(__m512 __A, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddps512_mask (-(__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask3_fnmadd_ps(__m512 __A, __m512 __B, __m512 __C, __mmask16 __U) +{ + return (__m512) __builtin_ia32_vfmaddps512_mask3 (-(__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_fnmadd_ps(__mmask16 __U, __m512 __A, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddps512_maskz (-(__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_fnmsub_ps(__m512 __A, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddps512_mask (-(__v16sf) __A, + (__v16sf) __B, + -(__v16sf) __C, + (__mmask16) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_fnmsub_ps(__mmask16 __U, __m512 __A, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddps512_maskz (-(__v16sf) __A, + (__v16sf) __B, + -(__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_fmaddsub_round_pd(A, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddsubpd512_mask ((__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) -1, (R)); }) + + +#define _mm512_mask_fmaddsub_round_pd(A, U, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddsubpd512_mask ((__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +#define _mm512_mask3_fmaddsub_round_pd(A, B, C, U, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddsubpd512_mask3 ((__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +#define _mm512_maskz_fmaddsub_round_pd(U, A, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddsubpd512_maskz ((__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +#define _mm512_fmsubadd_round_pd(A, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddsubpd512_mask ((__v8df) (A), \ + (__v8df) (B), -(__v8df) (C), \ + (__mmask8) -1, (R)); }) + + +#define _mm512_mask_fmsubadd_round_pd(A, U, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddsubpd512_mask ((__v8df) (A), \ + (__v8df) (B), -(__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +#define _mm512_maskz_fmsubadd_round_pd(U, A, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmaddsubpd512_maskz ((__v8df) (A), \ + (__v8df) (B), -(__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_fmaddsub_pd(__m512d __A, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddsubpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_fmaddsub_pd(__m512d __A, __mmask8 __U, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddsubpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask3_fmaddsub_pd(__m512d __A, __m512d __B, __m512d __C, __mmask8 __U) +{ + return (__m512d) __builtin_ia32_vfmaddsubpd512_mask3 ((__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_fmaddsub_pd(__mmask8 __U, __m512d __A, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddsubpd512_maskz ((__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_fmsubadd_pd(__m512d __A, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddsubpd512_mask ((__v8df) __A, + (__v8df) __B, + -(__v8df) __C, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_fmsubadd_pd(__m512d __A, __mmask8 __U, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddsubpd512_mask ((__v8df) __A, + (__v8df) __B, + -(__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_fmsubadd_pd(__mmask8 __U, __m512d __A, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfmaddsubpd512_maskz ((__v8df) __A, + (__v8df) __B, + -(__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_fmaddsub_round_ps(A, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddsubps512_mask ((__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) -1, (R)); }) + + +#define _mm512_mask_fmaddsub_round_ps(A, U, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddsubps512_mask ((__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +#define _mm512_mask3_fmaddsub_round_ps(A, B, C, U, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddsubps512_mask3 ((__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +#define _mm512_maskz_fmaddsub_round_ps(U, A, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddsubps512_maskz ((__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +#define _mm512_fmsubadd_round_ps(A, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddsubps512_mask ((__v16sf) (A), \ + (__v16sf) (B), -(__v16sf) (C), \ + (__mmask16) -1, (R)); }) + + +#define _mm512_mask_fmsubadd_round_ps(A, U, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddsubps512_mask ((__v16sf) (A), \ + (__v16sf) (B), -(__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +#define _mm512_maskz_fmsubadd_round_ps(U, A, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmaddsubps512_maskz ((__v16sf) (A), \ + (__v16sf) (B), -(__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_fmaddsub_ps(__m512 __A, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddsubps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask_fmaddsub_ps(__m512 __A, __mmask16 __U, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddsubps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask3_fmaddsub_ps(__m512 __A, __m512 __B, __m512 __C, __mmask16 __U) +{ + return (__m512) __builtin_ia32_vfmaddsubps512_mask3 ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_fmaddsub_ps(__mmask16 __U, __m512 __A, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddsubps512_maskz ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_fmsubadd_ps(__m512 __A, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddsubps512_mask ((__v16sf) __A, + (__v16sf) __B, + -(__v16sf) __C, + (__mmask16) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask_fmsubadd_ps(__m512 __A, __mmask16 __U, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddsubps512_mask ((__v16sf) __A, + (__v16sf) __B, + -(__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_fmsubadd_ps(__mmask16 __U, __m512 __A, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfmaddsubps512_maskz ((__v16sf) __A, + (__v16sf) __B, + -(__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_mask3_fmsub_round_pd(A, B, C, U, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmsubpd512_mask3 ((__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask3_fmsub_pd(__m512d __A, __m512d __B, __m512d __C, __mmask8 __U) +{ + return (__m512d) __builtin_ia32_vfmsubpd512_mask3 ((__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_mask3_fmsub_round_ps(A, B, C, U, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmsubps512_mask3 ((__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask3_fmsub_ps(__m512 __A, __m512 __B, __m512 __C, __mmask16 __U) +{ + return (__m512) __builtin_ia32_vfmsubps512_mask3 ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_mask3_fmsubadd_round_pd(A, B, C, U, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfmsubaddpd512_mask3 ((__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask3_fmsubadd_pd(__m512d __A, __m512d __B, __m512d __C, __mmask8 __U) +{ + return (__m512d) __builtin_ia32_vfmsubaddpd512_mask3 ((__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_mask3_fmsubadd_round_ps(A, B, C, U, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfmsubaddps512_mask3 ((__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask3_fmsubadd_ps(__m512 __A, __m512 __B, __m512 __C, __mmask16 __U) +{ + return (__m512) __builtin_ia32_vfmsubaddps512_mask3 ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_mask_fnmadd_round_pd(A, U, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfnmaddpd512_mask ((__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_fnmadd_pd(__m512d __A, __mmask8 __U, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfnmaddpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_mask_fnmadd_round_ps(A, U, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfnmaddps512_mask ((__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask_fnmadd_ps(__m512 __A, __mmask16 __U, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfnmaddps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_mask_fnmsub_round_pd(A, U, B, C, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfnmsubpd512_mask ((__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +#define _mm512_mask3_fnmsub_round_pd(A, B, C, U, R) __extension__ ({ \ + (__m512d) __builtin_ia32_vfnmsubpd512_mask3 ((__v8df) (A), \ + (__v8df) (B), (__v8df) (C), \ + (__mmask8) (U), (R)); }) + + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask_fnmsub_pd(__m512d __A, __mmask8 __U, __m512d __B, __m512d __C) +{ + return (__m512d) __builtin_ia32_vfnmsubpd512_mask ((__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512d __DEFAULT_FN_ATTRS +_mm512_mask3_fnmsub_pd(__m512d __A, __m512d __B, __m512d __C, __mmask8 __U) +{ + return (__m512d) __builtin_ia32_vfnmsubpd512_mask3 ((__v8df) __A, + (__v8df) __B, + (__v8df) __C, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_mask_fnmsub_round_ps(A, U, B, C, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfnmsubps512_mask ((__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +#define _mm512_mask3_fnmsub_round_ps(A, B, C, U, R) __extension__ ({ \ + (__m512) __builtin_ia32_vfnmsubps512_mask3 ((__v16sf) (A), \ + (__v16sf) (B), (__v16sf) (C), \ + (__mmask16) (U), (R)); }) + + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask_fnmsub_ps(__m512 __A, __mmask16 __U, __m512 __B, __m512 __C) +{ + return (__m512) __builtin_ia32_vfnmsubps512_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline__ __m512 __DEFAULT_FN_ATTRS +_mm512_mask3_fnmsub_ps(__m512 __A, __m512 __B, __m512 __C, __mmask16 __U) +{ + return (__m512) __builtin_ia32_vfnmsubps512_mask3 ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__mmask16) __U, + _MM_FROUND_CUR_DIRECTION); +} + + + +/* Vector permutations */ + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_permutex2var_epi32(__m512i __A, __m512i __I, __m512i __B) +{ + return (__m512i) __builtin_ia32_vpermt2vard512_mask ((__v16si) __I + /* idx */ , + (__v16si) __A, + (__v16si) __B, + (__mmask16) -1); +} +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_permutex2var_epi64(__m512i __A, __m512i __I, __m512i __B) +{ + return (__m512i) __builtin_ia32_vpermt2varq512_mask ((__v8di) __I + /* idx */ , + (__v8di) __A, + (__v8di) __B, + (__mmask8) -1); +} + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_permutex2var_pd(__m512d __A, __m512i __I, __m512d __B) +{ + return (__m512d) __builtin_ia32_vpermt2varpd512_mask ((__v8di) __I + /* idx */ , + (__v8df) __A, + (__v8df) __B, + (__mmask8) -1); +} +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_permutex2var_ps(__m512 __A, __m512i __I, __m512 __B) +{ + return (__m512) __builtin_ia32_vpermt2varps512_mask ((__v16si) __I + /* idx */ , + (__v16sf) __A, + (__v16sf) __B, + (__mmask16) -1); +} + +#define _mm512_alignr_epi64(A, B, I) __extension__ ({ \ + (__m512i)__builtin_ia32_alignq512_mask((__v8di)(__m512i)(A), \ + (__v8di)(__m512i)(B), \ + (I), (__v8di)_mm512_setzero_si512(), \ + (__mmask8)-1); }) + +#define _mm512_alignr_epi32(A, B, I) __extension__ ({ \ + (__m512i)__builtin_ia32_alignd512_mask((__v16si)(__m512i)(A), \ + (__v16si)(__m512i)(B), \ + (I), (__v16si)_mm512_setzero_si512(), \ + (__mmask16)-1); }) + +/* Vector Extract */ + +#define _mm512_extractf64x4_pd(A, I) __extension__ ({ \ + __m512d __A = (A); \ + (__m256d) \ + __builtin_ia32_extractf64x4_mask((__v8df)__A, \ + (I), \ + (__v4df)_mm256_setzero_si256(), \ + (__mmask8) -1); }) + +#define _mm512_extractf32x4_ps(A, I) __extension__ ({ \ + __m512 __A = (A); \ + (__m128) \ + __builtin_ia32_extractf32x4_mask((__v16sf)__A, \ + (I), \ + (__v4sf)_mm_setzero_ps(), \ + (__mmask8) -1); }) + +/* Vector Blend */ + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_mask_blend_pd(__mmask8 __U, __m512d __A, __m512d __W) +{ + return (__m512d) __builtin_ia32_blendmpd_512_mask ((__v8df) __A, + (__v8df) __W, + (__mmask8) __U); +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_mask_blend_ps(__mmask16 __U, __m512 __A, __m512 __W) +{ + return (__m512) __builtin_ia32_blendmps_512_mask ((__v16sf) __A, + (__v16sf) __W, + (__mmask16) __U); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_mask_blend_epi64(__mmask8 __U, __m512i __A, __m512i __W) +{ + return (__m512i) __builtin_ia32_blendmq_512_mask ((__v8di) __A, + (__v8di) __W, + (__mmask8) __U); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_mask_blend_epi32(__mmask16 __U, __m512i __A, __m512i __W) +{ + return (__m512i) __builtin_ia32_blendmd_512_mask ((__v16si) __A, + (__v16si) __W, + (__mmask16) __U); +} + +/* Compare */ + +#define _mm512_cmp_round_ps_mask(A, B, P, R) __extension__ ({ \ + (__mmask16)__builtin_ia32_cmpps512_mask((__v16sf)(__m512)(A), \ + (__v16sf)(__m512)(B), \ + (P), (__mmask16)-1, (R)); }) + +#define _mm512_mask_cmp_round_ps_mask(U, A, B, P, R) __extension__ ({ \ + (__mmask16)__builtin_ia32_cmpps512_mask((__v16sf)(__m512)(A), \ + (__v16sf)(__m512)(B), \ + (P), (__mmask16)(U), (R)); }) + +#define _mm512_cmp_ps_mask(A, B, P) \ + _mm512_cmp_round_ps_mask((A), (B), (P), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_mask_cmp_ps_mask(U, A, B, P) \ + _mm512_mask_cmp_round_ps_mask((U), (A), (B), (P), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_cmp_round_pd_mask(A, B, P, R) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmppd512_mask((__v8df)(__m512d)(A), \ + (__v8df)(__m512d)(B), \ + (P), (__mmask8)-1, (R)); }) + +#define _mm512_mask_cmp_round_pd_mask(U, A, B, P, R) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmppd512_mask((__v8df)(__m512d)(A), \ + (__v8df)(__m512d)(B), \ + (P), (__mmask8)(U), (R)); }) + +#define _mm512_cmp_pd_mask(A, B, P) \ + _mm512_cmp_round_pd_mask((A), (B), (P), _MM_FROUND_CUR_DIRECTION) + +#define _mm512_mask_cmp_pd_mask(U, A, B, P) \ + _mm512_mask_cmp_round_pd_mask((U), (A), (B), (P), _MM_FROUND_CUR_DIRECTION) + +/* Conversion */ + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_cvttps_epu32(__m512 __A) +{ + return (__m512i) __builtin_ia32_cvttps2udq512_mask ((__v16sf) __A, + (__v16si) + _mm512_setzero_si512 (), + (__mmask16) -1, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_cvt_roundepi32_ps(A, R) __extension__ ({ \ + (__m512)__builtin_ia32_cvtdq2ps512_mask((__v16si)(A), \ + (__v16sf)_mm512_setzero_ps(), \ + (__mmask16)-1, (R)); }) + +#define _mm512_cvt_roundepu32_ps(A, R) __extension__ ({ \ + (__m512)__builtin_ia32_cvtudq2ps512_mask((__v16si)(A), \ + (__v16sf)_mm512_setzero_ps(), \ + (__mmask16)-1, (R)); }) + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_cvtepi32_pd(__m256i __A) +{ + return (__m512d) __builtin_ia32_cvtdq2pd512_mask ((__v8si) __A, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) -1); +} + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_cvtepu32_pd(__m256i __A) +{ + return (__m512d) __builtin_ia32_cvtudq2pd512_mask ((__v8si) __A, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) -1); +} + +#define _mm512_cvt_roundpd_ps(A, R) __extension__ ({ \ + (__m256)__builtin_ia32_cvtpd2ps512_mask((__v8df)(A), \ + (__v8sf)_mm256_setzero_ps(), \ + (__mmask8)-1, (R)); }) + +#define _mm512_cvtps_ph(A, I) __extension__ ({ \ + (__m256i)__builtin_ia32_vcvtps2ph512_mask((__v16sf)(A), (I), \ + (__v16hi)_mm256_setzero_si256(), \ + -1); }) + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_cvtph_ps(__m256i __A) +{ + return (__m512) __builtin_ia32_vcvtph2ps512_mask ((__v16hi) __A, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) -1, + _MM_FROUND_CUR_DIRECTION); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_cvttps_epi32(__m512 __a) +{ + return (__m512i) + __builtin_ia32_cvttps2dq512_mask((__v16sf) __a, + (__v16si) _mm512_setzero_si512 (), + (__mmask16) -1, _MM_FROUND_CUR_DIRECTION); +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm512_cvttpd_epi32(__m512d __a) +{ + return (__m256i)__builtin_ia32_cvttpd2dq512_mask((__v8df) __a, + (__v8si)_mm256_setzero_si256(), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} + +#define _mm512_cvtt_roundpd_epi32(A, R) __extension__ ({ \ + (__m256i)__builtin_ia32_cvttpd2dq512_mask((__v8df)(A), \ + (__v8si)_mm256_setzero_si256(), \ + (__mmask8)-1, (R)); }) + +#define _mm512_cvtt_roundps_epi32(A, R) __extension__ ({ \ + (__m512i)__builtin_ia32_cvttps2dq512_mask((__v16sf)(A), \ + (__v16si)_mm512_setzero_si512(), \ + (__mmask16)-1, (R)); }) + +#define _mm512_cvt_roundps_epi32(A, R) __extension__ ({ \ + (__m512i)__builtin_ia32_cvtps2dq512_mask((__v16sf)(A), \ + (__v16si)_mm512_setzero_si512(), \ + (__mmask16)-1, (R)); }) + +#define _mm512_cvt_roundpd_epi32(A, R) __extension__ ({ \ + (__m256i)__builtin_ia32_cvtpd2dq512_mask((__v8df)(A), \ + (__v8si)_mm256_setzero_si256(), \ + (__mmask8)-1, (R)); }) + +#define _mm512_cvt_roundps_epu32(A, R) __extension__ ({ \ + (__m512i)__builtin_ia32_cvtps2udq512_mask((__v16sf)(A), \ + (__v16si)_mm512_setzero_si512(), \ + (__mmask16)-1, (R)); }) + +#define _mm512_cvt_roundpd_epu32(A, R) __extension__ ({ \ + (__m256i)__builtin_ia32_cvtpd2udq512_mask((__v8df)(A), \ + (__v8si)_mm256_setzero_si256(), \ + (__mmask8) -1, (R)); }) + +/* Unpack and Interleave */ +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_unpackhi_pd(__m512d __a, __m512d __b) +{ + return __builtin_shufflevector(__a, __b, 1, 9, 1+2, 9+2, 1+4, 9+4, 1+6, 9+6); +} + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_unpacklo_pd(__m512d __a, __m512d __b) +{ + return __builtin_shufflevector(__a, __b, 0, 8, 0+2, 8+2, 0+4, 8+4, 0+6, 8+6); +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_unpackhi_ps(__m512 __a, __m512 __b) +{ + return __builtin_shufflevector(__a, __b, + 2, 18, 3, 19, + 2+4, 18+4, 3+4, 19+4, + 2+8, 18+8, 3+8, 19+8, + 2+12, 18+12, 3+12, 19+12); +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_unpacklo_ps(__m512 __a, __m512 __b) +{ + return __builtin_shufflevector(__a, __b, + 0, 16, 1, 17, + 0+4, 16+4, 1+4, 17+4, + 0+8, 16+8, 1+8, 17+8, + 0+12, 16+12, 1+12, 17+12); +} + +/* Bit Test */ + +static __inline __mmask16 __DEFAULT_FN_ATTRS +_mm512_test_epi32_mask(__m512i __A, __m512i __B) +{ + return (__mmask16) __builtin_ia32_ptestmd512 ((__v16si) __A, + (__v16si) __B, + (__mmask16) -1); +} + +static __inline __mmask8 __DEFAULT_FN_ATTRS +_mm512_test_epi64_mask(__m512i __A, __m512i __B) +{ + return (__mmask8) __builtin_ia32_ptestmq512 ((__v8di) __A, + (__v8di) __B, + (__mmask8) -1); +} + +/* SIMD load ops */ + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_loadu_epi32(__mmask16 __U, void const *__P) +{ + return (__m512i) __builtin_ia32_loaddqusi512_mask ((const __v16si *)__P, + (__v16si) + _mm512_setzero_si512 (), + (__mmask16) __U); +} + +static __inline __m512i __DEFAULT_FN_ATTRS +_mm512_maskz_loadu_epi64(__mmask8 __U, void const *__P) +{ + return (__m512i) __builtin_ia32_loaddqudi512_mask ((const __v8di *)__P, + (__v8di) + _mm512_setzero_si512 (), + (__mmask8) __U); +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_loadu_ps(__mmask16 __U, void const *__P) +{ + return (__m512) __builtin_ia32_loadups512_mask ((const __v16sf *)__P, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) __U); +} + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_loadu_pd(__mmask8 __U, void const *__P) +{ + return (__m512d) __builtin_ia32_loadupd512_mask ((const __v8df *)__P, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) __U); +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_maskz_load_ps(__mmask16 __U, void const *__P) +{ + return (__m512) __builtin_ia32_loadaps512_mask ((const __v16sf *)__P, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) __U); +} + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_maskz_load_pd(__mmask8 __U, void const *__P) +{ + return (__m512d) __builtin_ia32_loadapd512_mask ((const __v8df *)__P, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) __U); +} + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_loadu_pd(double const *__p) +{ + struct __loadu_pd { + __m512d __v; + } __attribute__((__packed__, __may_alias__)); + return ((struct __loadu_pd*)__p)->__v; +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_loadu_ps(float const *__p) +{ + struct __loadu_ps { + __m512 __v; + } __attribute__((__packed__, __may_alias__)); + return ((struct __loadu_ps*)__p)->__v; +} + +static __inline __m512 __DEFAULT_FN_ATTRS +_mm512_load_ps(double const *__p) +{ + return (__m512) __builtin_ia32_loadaps512_mask ((const __v16sf *)__p, + (__v16sf) + _mm512_setzero_ps (), + (__mmask16) -1); +} + +static __inline __m512d __DEFAULT_FN_ATTRS +_mm512_load_pd(float const *__p) +{ + return (__m512d) __builtin_ia32_loadapd512_mask ((const __v8df *)__p, + (__v8df) + _mm512_setzero_pd (), + (__mmask8) -1); +} + +/* SIMD store ops */ + +static __inline void __DEFAULT_FN_ATTRS +_mm512_mask_storeu_epi64(void *__P, __mmask8 __U, __m512i __A) +{ + __builtin_ia32_storedqudi512_mask ((__v8di *)__P, (__v8di) __A, + (__mmask8) __U); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm512_mask_storeu_epi32(void *__P, __mmask16 __U, __m512i __A) +{ + __builtin_ia32_storedqusi512_mask ((__v16si *)__P, (__v16si) __A, + (__mmask16) __U); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm512_mask_storeu_pd(void *__P, __mmask8 __U, __m512d __A) +{ + __builtin_ia32_storeupd512_mask ((__v8df *)__P, (__v8df) __A, (__mmask8) __U); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm512_storeu_pd(void *__P, __m512d __A) +{ + __builtin_ia32_storeupd512_mask((__v8df *)__P, (__v8df)__A, (__mmask8)-1); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm512_mask_storeu_ps(void *__P, __mmask16 __U, __m512 __A) +{ + __builtin_ia32_storeups512_mask ((__v16sf *)__P, (__v16sf) __A, + (__mmask16) __U); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm512_storeu_ps(void *__P, __m512 __A) +{ + __builtin_ia32_storeups512_mask((__v16sf *)__P, (__v16sf)__A, (__mmask16)-1); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm512_mask_store_pd(void *__P, __mmask8 __U, __m512d __A) +{ + __builtin_ia32_storeapd512_mask ((__v8df *)__P, (__v8df) __A, (__mmask8) __U); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm512_store_pd(void *__P, __m512d __A) +{ + *(__m512d*)__P = __A; +} + +static __inline void __DEFAULT_FN_ATTRS +_mm512_mask_store_ps(void *__P, __mmask16 __U, __m512 __A) +{ + __builtin_ia32_storeaps512_mask ((__v16sf *)__P, (__v16sf) __A, + (__mmask16) __U); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm512_store_ps(void *__P, __m512 __A) +{ + *(__m512*)__P = __A; +} + +/* Mask ops */ + +static __inline __mmask16 __DEFAULT_FN_ATTRS +_mm512_knot(__mmask16 __M) +{ + return __builtin_ia32_knothi(__M); +} + +/* Integer compare */ + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_cmpeq_epi32_mask(__m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_pcmpeqd512_mask((__v16si)__a, (__v16si)__b, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_mask_cmpeq_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_pcmpeqd512_mask((__v16si)__a, (__v16si)__b, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_cmpeq_epu32_mask(__m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 0, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_mask_cmpeq_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 0, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_mask_cmpeq_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_pcmpeqq512_mask((__v8di)__a, (__v8di)__b, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_cmpeq_epi64_mask(__m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_pcmpeqq512_mask((__v8di)__a, (__v8di)__b, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_cmpeq_epu64_mask(__m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 0, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_mask_cmpeq_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 0, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_cmpge_epi32_mask(__m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 5, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_mask_cmpge_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 5, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_cmpge_epu32_mask(__m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 5, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_mask_cmpge_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 5, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_cmpge_epi64_mask(__m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 5, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_mask_cmpge_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 5, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_cmpge_epu64_mask(__m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 5, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_mask_cmpge_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 5, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_cmpgt_epi32_mask(__m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_pcmpgtd512_mask((__v16si)__a, (__v16si)__b, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_mask_cmpgt_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_pcmpgtd512_mask((__v16si)__a, (__v16si)__b, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_cmpgt_epu32_mask(__m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 6, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_mask_cmpgt_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 6, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_mask_cmpgt_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_pcmpgtq512_mask((__v8di)__a, (__v8di)__b, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_cmpgt_epi64_mask(__m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_pcmpgtq512_mask((__v8di)__a, (__v8di)__b, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_cmpgt_epu64_mask(__m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 6, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_mask_cmpgt_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 6, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_cmple_epi32_mask(__m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 2, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_mask_cmple_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 2, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_cmple_epu32_mask(__m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 2, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_mask_cmple_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 2, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_cmple_epi64_mask(__m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 2, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_mask_cmple_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 2, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_cmple_epu64_mask(__m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 2, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_mask_cmple_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 2, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_cmplt_epi32_mask(__m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 1, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_mask_cmplt_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 1, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_cmplt_epu32_mask(__m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 1, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_mask_cmplt_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 1, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_cmplt_epi64_mask(__m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 1, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_mask_cmplt_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 1, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_cmplt_epu64_mask(__m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 1, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_mask_cmplt_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 1, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_cmpneq_epi32_mask(__m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 4, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_mask_cmpneq_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 4, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_cmpneq_epu32_mask(__m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 4, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm512_mask_cmpneq_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { + return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 4, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_cmpneq_epi64_mask(__m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 4, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_mask_cmpneq_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 4, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_cmpneq_epu64_mask(__m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 4, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm512_mask_cmpneq_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { + return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 4, + __u); +} + +#define _mm512_cmp_epi32_mask(a, b, p) __extension__ ({ \ + __m512i __a = (a); \ + __m512i __b = (b); \ + (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, (p), \ + (__mmask16)-1); }) + +#define _mm512_cmp_epu32_mask(a, b, p) __extension__ ({ \ + __m512i __a = (a); \ + __m512i __b = (b); \ + (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, (p), \ + (__mmask16)-1); }) + +#define _mm512_cmp_epi64_mask(a, b, p) __extension__ ({ \ + __m512i __a = (a); \ + __m512i __b = (b); \ + (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, (p), \ + (__mmask8)-1); }) + +#define _mm512_cmp_epu64_mask(a, b, p) __extension__ ({ \ + __m512i __a = (a); \ + __m512i __b = (b); \ + (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, (p), \ + (__mmask8)-1); }) + +#define _mm512_mask_cmp_epi32_mask(m, a, b, p) __extension__ ({ \ + __m512i __a = (a); \ + __m512i __b = (b); \ + (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, (p), \ + (__mmask16)(m)); }) + +#define _mm512_mask_cmp_epu32_mask(m, a, b, p) __extension__ ({ \ + __m512i __a = (a); \ + __m512i __b = (b); \ + (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, (p), \ + (__mmask16)(m)); }) + +#define _mm512_mask_cmp_epi64_mask(m, a, b, p) __extension__ ({ \ + __m512i __a = (a); \ + __m512i __b = (b); \ + (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, (p), \ + (__mmask8)(m)); }) + +#define _mm512_mask_cmp_epu64_mask(m, a, b, p) __extension__ ({ \ + __m512i __a = (a); \ + __m512i __b = (b); \ + (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, (p), \ + (__mmask8)(m)); }) + +#undef __DEFAULT_FN_ATTRS + +#endif // __AVX512FINTRIN_H diff --git a/headers/clang/avx512vlbwintrin.h b/headers/clang/avx512vlbwintrin.h new file mode 100644 index 0000000000..5b61c2baca --- /dev/null +++ b/headers/clang/avx512vlbwintrin.h @@ -0,0 +1,2336 @@ +/*===---- avx512vlbwintrin.h - AVX512VL and AVX512BW intrinsics ----------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __AVX512VLBWINTRIN_H +#define __AVX512VLBWINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512vl,avx512bw"))) + +/* Integer compare */ + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_cmpeq_epi8_mask(__m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_pcmpeqb128_mask((__v16qi)__a, (__v16qi)__b, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_mask_cmpeq_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_pcmpeqb128_mask((__v16qi)__a, (__v16qi)__b, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_cmpeq_epu8_mask(__m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 0, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_mask_cmpeq_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 0, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_cmpeq_epi8_mask(__m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_pcmpeqb256_mask((__v32qi)__a, (__v32qi)__b, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_mask_cmpeq_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_pcmpeqb256_mask((__v32qi)__a, (__v32qi)__b, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_cmpeq_epu8_mask(__m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 0, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_mask_cmpeq_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 0, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpeq_epi16_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_pcmpeqw128_mask((__v8hi)__a, (__v8hi)__b, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpeq_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_pcmpeqw128_mask((__v8hi)__a, (__v8hi)__b, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpeq_epu16_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 0, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpeq_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 0, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_cmpeq_epi16_mask(__m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_pcmpeqw256_mask((__v16hi)__a, (__v16hi)__b, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_mask_cmpeq_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_pcmpeqw256_mask((__v16hi)__a, (__v16hi)__b, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_cmpeq_epu16_mask(__m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 0, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_mask_cmpeq_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 0, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_cmpge_epi8_mask(__m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 5, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_mask_cmpge_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 5, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_cmpge_epu8_mask(__m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 5, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_mask_cmpge_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 5, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_cmpge_epi8_mask(__m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 5, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_mask_cmpge_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 5, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_cmpge_epu8_mask(__m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 5, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_mask_cmpge_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 5, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpge_epi16_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 5, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpge_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 5, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpge_epu16_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 5, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpge_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 5, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_cmpge_epi16_mask(__m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 5, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_mask_cmpge_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 5, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_cmpge_epu16_mask(__m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 5, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_mask_cmpge_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 5, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_cmpgt_epi8_mask(__m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_pcmpgtb128_mask((__v16qi)__a, (__v16qi)__b, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_mask_cmpgt_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_pcmpgtb128_mask((__v16qi)__a, (__v16qi)__b, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_cmpgt_epu8_mask(__m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 6, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_mask_cmpgt_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 6, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_cmpgt_epi8_mask(__m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_pcmpgtb256_mask((__v32qi)__a, (__v32qi)__b, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_mask_cmpgt_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_pcmpgtb256_mask((__v32qi)__a, (__v32qi)__b, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_cmpgt_epu8_mask(__m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 6, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_mask_cmpgt_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 6, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpgt_epi16_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_pcmpgtw128_mask((__v8hi)__a, (__v8hi)__b, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpgt_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_pcmpgtw128_mask((__v8hi)__a, (__v8hi)__b, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpgt_epu16_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 6, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpgt_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 6, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_cmpgt_epi16_mask(__m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_pcmpgtw256_mask((__v16hi)__a, (__v16hi)__b, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_mask_cmpgt_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_pcmpgtw256_mask((__v16hi)__a, (__v16hi)__b, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_cmpgt_epu16_mask(__m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 6, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_mask_cmpgt_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 6, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_cmple_epi8_mask(__m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 2, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_mask_cmple_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 2, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_cmple_epu8_mask(__m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 2, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_mask_cmple_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 2, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_cmple_epi8_mask(__m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 2, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_mask_cmple_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 2, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_cmple_epu8_mask(__m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 2, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_mask_cmple_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 2, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmple_epi16_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 2, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmple_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 2, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmple_epu16_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 2, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmple_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 2, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_cmple_epi16_mask(__m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 2, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_mask_cmple_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 2, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_cmple_epu16_mask(__m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 2, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_mask_cmple_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 2, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_cmplt_epi8_mask(__m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 1, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_mask_cmplt_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 1, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_cmplt_epu8_mask(__m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 1, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_mask_cmplt_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 1, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_cmplt_epi8_mask(__m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 1, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_mask_cmplt_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 1, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_cmplt_epu8_mask(__m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 1, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_mask_cmplt_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 1, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmplt_epi16_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 1, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmplt_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 1, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmplt_epu16_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 1, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmplt_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 1, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_cmplt_epi16_mask(__m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 1, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_mask_cmplt_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 1, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_cmplt_epu16_mask(__m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 1, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_mask_cmplt_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 1, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_cmpneq_epi8_mask(__m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 4, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_mask_cmpneq_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 4, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_cmpneq_epu8_mask(__m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 4, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm_mask_cmpneq_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { + return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 4, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_cmpneq_epi8_mask(__m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 4, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_mask_cmpneq_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 4, + __u); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_cmpneq_epu8_mask(__m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 4, + (__mmask32)-1); +} + +static __inline__ __mmask32 __DEFAULT_FN_ATTRS +_mm256_mask_cmpneq_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { + return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 4, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpneq_epi16_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 4, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpneq_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 4, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpneq_epu16_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 4, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpneq_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 4, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_cmpneq_epi16_mask(__m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 4, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_mask_cmpneq_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 4, + __u); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_cmpneq_epu16_mask(__m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 4, + (__mmask16)-1); +} + +static __inline__ __mmask16 __DEFAULT_FN_ATTRS +_mm256_mask_cmpneq_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { + return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 4, + __u); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_add_epi8 (__m256i __W, __mmask32 __U, __m256i __A, __m256i __B){ + return (__m256i) __builtin_ia32_paddb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) __W, + (__mmask32) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_add_epi8 (__mmask32 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_paddb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) + _mm256_setzero_si256 (), + (__mmask32) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_add_epi16 (__m256i __W, __mmask16 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_paddw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_add_epi16 (__mmask16 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_paddw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) + _mm256_setzero_si256 (), + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_sub_epi8 (__m256i __W, __mmask32 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_psubb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) __W, + (__mmask32) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_sub_epi8 (__mmask32 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_psubb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) + _mm256_setzero_si256 (), + (__mmask32) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_sub_epi16 (__m256i __W, __mmask16 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_psubw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_sub_epi16 (__mmask16 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_psubw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) + _mm256_setzero_si256 (), + (__mmask16) __U); +} +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_add_epi8 (__m128i __W, __mmask16 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_paddb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) __W, + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_add_epi8 (__mmask16 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_paddb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) + _mm_setzero_si128 (), + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_add_epi16 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_paddw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_add_epi16 (__mmask8 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_paddw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_sub_epi8 (__m128i __W, __mmask16 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_psubb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) __W, + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_sub_epi8 (__mmask16 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_psubb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) + _mm_setzero_si128 (), + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_sub_epi16 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_psubw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_sub_epi16 (__mmask8 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_psubw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_mullo_epi16 (__m256i __W, __mmask16 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pmullw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_mullo_epi16 (__mmask16 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pmullw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) + _mm256_setzero_si256 (), + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_mullo_epi16 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pmullw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_mullo_epi16 (__mmask8 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pmullw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_blend_epi8 (__mmask16 __U, __m128i __A, __m128i __W) +{ + return (__m128i) __builtin_ia32_blendmb_128_mask ((__v16qi) __A, + (__v16qi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_blend_epi8 (__mmask32 __U, __m256i __A, __m256i __W) +{ + return (__m256i) __builtin_ia32_blendmb_256_mask ((__v32qi) __A, + (__v32qi) __W, + (__mmask32) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_blend_epi16 (__mmask8 __U, __m128i __A, __m128i __W) +{ + return (__m128i) __builtin_ia32_blendmw_128_mask ((__v8hi) __A, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_blend_epi16 (__mmask16 __U, __m256i __A, __m256i __W) +{ + return (__m256i) __builtin_ia32_blendmw_256_mask ((__v16hi) __A, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_abs_epi8 (__m128i __W, __mmask16 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_pabsb128_mask ((__v16qi) __A, + (__v16qi) __W, + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_abs_epi8 (__mmask16 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_pabsb128_mask ((__v16qi) __A, + (__v16qi) _mm_setzero_si128 (), + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_abs_epi8 (__m256i __W, __mmask32 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_pabsb256_mask ((__v32qi) __A, + (__v32qi) __W, + (__mmask32) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_abs_epi8 (__mmask32 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_pabsb256_mask ((__v32qi) __A, + (__v32qi) _mm256_setzero_si256 (), + (__mmask32) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_abs_epi16 (__m128i __W, __mmask8 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_pabsw128_mask ((__v8hi) __A, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_abs_epi16 (__mmask8 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_pabsw128_mask ((__v8hi) __A, + (__v8hi) _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_abs_epi16 (__m256i __W, __mmask16 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_pabsw256_mask ((__v16hi) __A, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_abs_epi16 (__mmask16 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_pabsw256_mask ((__v16hi) __A, + (__v16hi) _mm256_setzero_si256 (), + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_packs_epi32 (__mmask8 __M, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_packssdw128_mask ((__v4si) __A, + (__v4si) __B, + (__v8hi) _mm_setzero_si128 (), __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_packs_epi32 (__m128i __W, __mmask16 __M, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_packssdw128_mask ((__v4si) __A, + (__v4si) __B, + (__v8hi) __W, __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_packs_epi32 (__mmask16 __M, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_packssdw256_mask ((__v8si) __A, + (__v8si) __B, + (__v16hi) _mm256_setzero_si256 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_packs_epi32 (__m256i __W, __mmask16 __M, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_packssdw256_mask ((__v8si) __A, + (__v8si) __B, + (__v16hi) __W, __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_packs_epi16 (__mmask16 __M, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_packsswb128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v16qi) _mm_setzero_si128 (), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_packs_epi16 (__m128i __W, __mmask16 __M, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_packsswb128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v16qi) __W, + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_packs_epi16 (__mmask32 __M, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_packsswb256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v32qi) _mm256_setzero_si256 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_packs_epi16 (__m256i __W, __mmask32 __M, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_packsswb256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v32qi) __W, + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_packus_epi32 (__mmask8 __M, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_packusdw128_mask ((__v4si) __A, + (__v4si) __B, + (__v8hi) _mm_setzero_si128 (), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_packus_epi32 (__m128i __W, __mmask16 __M, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_packusdw128_mask ((__v4si) __A, + (__v4si) __B, + (__v8hi) __W, __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_packus_epi32 (__mmask16 __M, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_packusdw256_mask ((__v8si) __A, + (__v8si) __B, + (__v16hi) _mm256_setzero_si256 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_packus_epi32 (__m256i __W, __mmask16 __M, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_packusdw256_mask ((__v8si) __A, + (__v8si) __B, + (__v16hi) __W, + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_packus_epi16 (__mmask16 __M, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_packuswb128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v16qi) _mm_setzero_si128 (), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_packus_epi16 (__m128i __W, __mmask16 __M, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_packuswb128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v16qi) __W, + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_packus_epi16 (__mmask32 __M, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_packuswb256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v32qi) _mm256_setzero_si256 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_packus_epi16 (__m256i __W, __mmask32 __M, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_packuswb256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v32qi) __W, + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_adds_epi8 (__m128i __W, __mmask16 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_paddsb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) __W, + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_adds_epi8 (__mmask16 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_paddsb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) _mm_setzero_si128 (), + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_adds_epi8 (__m256i __W, __mmask32 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_paddsb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) __W, + (__mmask32) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_adds_epi8 (__mmask32 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_paddsb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) _mm256_setzero_si256 (), + (__mmask32) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_adds_epi16 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_paddsw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_adds_epi16 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_paddsw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_adds_epi16 (__m256i __W, __mmask16 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_paddsw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_adds_epi16 (__mmask16 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_paddsw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) _mm256_setzero_si256 (), + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_adds_epu8 (__m128i __W, __mmask16 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_paddusb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) __W, + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_adds_epu8 (__mmask16 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_paddusb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) _mm_setzero_si128 (), + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_adds_epu8 (__m256i __W, __mmask32 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_paddusb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) __W, + (__mmask32) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_adds_epu8 (__mmask32 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_paddusb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) _mm256_setzero_si256 (), + (__mmask32) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_adds_epu16 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_paddusw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_adds_epu16 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_paddusw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_adds_epu16 (__m256i __W, __mmask16 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_paddusw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_adds_epu16 (__mmask16 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_paddusw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) _mm256_setzero_si256 (), + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_avg_epu8 (__m128i __W, __mmask16 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pavgb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) __W, + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_avg_epu8 (__mmask16 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pavgb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) _mm_setzero_si128 (), + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_avg_epu8 (__m256i __W, __mmask32 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pavgb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) __W, + (__mmask32) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_avg_epu8 (__mmask32 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pavgb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) _mm256_setzero_si256 (), + (__mmask32) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_avg_epu16 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pavgw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_avg_epu16 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pavgw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_avg_epu16 (__m256i __W, __mmask16 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pavgw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_avg_epu16 (__mmask16 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pavgw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) _mm256_setzero_si256 (), + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_max_epi8 (__mmask16 __M, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pmaxsb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) _mm_setzero_si128 (), + (__mmask16) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_max_epi8 (__m128i __W, __mmask16 __M, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pmaxsb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) __W, + (__mmask16) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_max_epi8 (__mmask32 __M, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pmaxsb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) _mm256_setzero_si256 (), + (__mmask32) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_max_epi8 (__m256i __W, __mmask32 __M, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pmaxsb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) __W, + (__mmask32) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_max_epi16 (__mmask8 __M, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pmaxsw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) _mm_setzero_si128 (), + (__mmask8) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_max_epi16 (__m128i __W, __mmask8 __M, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pmaxsw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_max_epi16 (__mmask16 __M, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pmaxsw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) _mm256_setzero_si256 (), + (__mmask16) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_max_epi16 (__m256i __W, __mmask16 __M, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pmaxsw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_max_epu8 (__mmask16 __M, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pmaxub128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) _mm_setzero_si128 (), + (__mmask16) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_max_epu8 (__m128i __W, __mmask16 __M, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pmaxub128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) __W, + (__mmask16) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_max_epu8 (__mmask32 __M, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pmaxub256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) _mm256_setzero_si256 (), + (__mmask32) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_max_epu8 (__m256i __W, __mmask32 __M, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pmaxub256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) __W, + (__mmask32) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_max_epu16 (__mmask8 __M, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pmaxuw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) _mm_setzero_si128 (), + (__mmask8) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_max_epu16 (__m128i __W, __mmask8 __M, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pmaxuw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_max_epu16 (__mmask16 __M, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pmaxuw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) _mm256_setzero_si256 (), + (__mmask16) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_max_epu16 (__m256i __W, __mmask16 __M, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pmaxuw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_min_epi8 (__mmask16 __M, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pminsb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) _mm_setzero_si128 (), + (__mmask16) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_min_epi8 (__m128i __W, __mmask16 __M, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pminsb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) __W, + (__mmask16) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_min_epi8 (__mmask32 __M, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pminsb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) _mm256_setzero_si256 (), + (__mmask32) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_min_epi8 (__m256i __W, __mmask32 __M, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pminsb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) __W, + (__mmask32) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_min_epi16 (__mmask8 __M, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pminsw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) _mm_setzero_si128 (), + (__mmask8) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_min_epi16 (__m128i __W, __mmask8 __M, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pminsw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_min_epi16 (__mmask16 __M, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pminsw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) _mm256_setzero_si256 (), + (__mmask16) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_min_epi16 (__m256i __W, __mmask16 __M, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pminsw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_min_epu8 (__mmask16 __M, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pminub128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) _mm_setzero_si128 (), + (__mmask16) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_min_epu8 (__m128i __W, __mmask16 __M, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pminub128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) __W, + (__mmask16) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_min_epu8 (__mmask32 __M, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pminub256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) _mm256_setzero_si256 (), + (__mmask32) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_min_epu8 (__m256i __W, __mmask32 __M, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pminub256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) __W, + (__mmask32) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_min_epu16 (__mmask8 __M, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pminuw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) _mm_setzero_si128 (), + (__mmask8) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_min_epu16 (__m128i __W, __mmask8 __M, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pminuw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_min_epu16 (__mmask16 __M, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pminuw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) _mm256_setzero_si256 (), + (__mmask16) __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_min_epu16 (__m256i __W, __mmask16 __M, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pminuw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_shuffle_epi8 (__m128i __W, __mmask16 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pshufb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) __W, + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_shuffle_epi8 (__mmask16 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pshufb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) _mm_setzero_si128 (), + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_shuffle_epi8 (__m256i __W, __mmask32 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pshufb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) __W, + (__mmask32) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_shuffle_epi8 (__mmask32 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pshufb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) _mm256_setzero_si256 (), + (__mmask32) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_subs_epi8 (__m128i __W, __mmask16 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_psubsb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) __W, + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_subs_epi8 (__mmask16 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_psubsb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) _mm_setzero_si128 (), + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_subs_epi8 (__m256i __W, __mmask32 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_psubsb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) __W, + (__mmask32) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_subs_epi8 (__mmask32 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_psubsb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) _mm256_setzero_si256 (), + (__mmask32) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_subs_epi16 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_psubsw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_subs_epi16 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_psubsw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_subs_epi16 (__m256i __W, __mmask16 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_psubsw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_subs_epi16 (__mmask16 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_psubsw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) _mm256_setzero_si256 (), + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_subs_epu8 (__m128i __W, __mmask16 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_psubusb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) __W, + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_subs_epu8 (__mmask16 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_psubusb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) _mm_setzero_si128 (), + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_subs_epu8 (__m256i __W, __mmask32 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_psubusb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) __W, + (__mmask32) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_subs_epu8 (__mmask32 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_psubusb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) _mm256_setzero_si256 (), + (__mmask32) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_subs_epu16 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_psubusw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_subs_epu16 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_psubusw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_subs_epu16 (__m256i __W, __mmask16 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_psubusw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_subs_epu16 (__mmask16 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_psubusw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) _mm256_setzero_si256 (), + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask2_permutex2var_epi16 (__m128i __A, __m128i __I, __mmask8 __U, + __m128i __B) +{ + return (__m128i) __builtin_ia32_vpermi2varhi128_mask ((__v8hi) __A, + (__v8hi) __I /* idx */ , + (__v8hi) __B, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask2_permutex2var_epi16 (__m256i __A, __m256i __I, + __mmask16 __U, __m256i __B) +{ + return (__m256i) __builtin_ia32_vpermi2varhi256_mask ((__v16hi) __A, + (__v16hi) __I /* idx */ , + (__v16hi) __B, + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_permutex2var_epi16 (__m128i __A, __m128i __I, __m128i __B) +{ + return (__m128i) __builtin_ia32_vpermt2varhi128_mask ((__v8hi) __I/* idx */, + (__v8hi) __A, + (__v8hi) __B, + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_permutex2var_epi16 (__m128i __A, __mmask8 __U, __m128i __I, + __m128i __B) +{ + return (__m128i) __builtin_ia32_vpermt2varhi128_mask ((__v8hi) __I/* idx */, + (__v8hi) __A, + (__v8hi) __B, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_permutex2var_epi16 (__mmask8 __U, __m128i __A, __m128i __I, + __m128i __B) +{ + return (__m128i) __builtin_ia32_vpermt2varhi128_maskz ((__v8hi) __I/* idx */, + (__v8hi) __A, + (__v8hi) __B, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_permutex2var_epi16 (__m256i __A, __m256i __I, __m256i __B) +{ + return (__m256i) __builtin_ia32_vpermt2varhi256_mask ((__v16hi) __I/* idx */, + (__v16hi) __A, + (__v16hi) __B, + (__mmask16) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_permutex2var_epi16 (__m256i __A, __mmask16 __U, + __m256i __I, __m256i __B) +{ + return (__m256i) __builtin_ia32_vpermt2varhi256_mask ((__v16hi) __I/* idx */, + (__v16hi) __A, + (__v16hi) __B, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_permutex2var_epi16 (__mmask16 __U, __m256i __A, + __m256i __I, __m256i __B) +{ + return (__m256i) __builtin_ia32_vpermt2varhi256_maskz ((__v16hi) __I/* idx */, + (__v16hi) __A, + (__v16hi) __B, + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_maddubs_epi16 (__m128i __W, __mmask8 __U, __m128i __X, __m128i __Y) { + return (__m128i) __builtin_ia32_pmaddubsw128_mask ((__v16qi) __X, + (__v16qi) __Y, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_maddubs_epi16 (__mmask8 __U, __m128i __X, __m128i __Y) { + return (__m128i) __builtin_ia32_pmaddubsw128_mask ((__v16qi) __X, + (__v16qi) __Y, + (__v8hi) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_maddubs_epi16 (__m256i __W, __mmask16 __U, __m256i __X, + __m256i __Y) { + return (__m256i) __builtin_ia32_pmaddubsw256_mask ((__v32qi) __X, + (__v32qi) __Y, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_maddubs_epi16 (__mmask16 __U, __m256i __X, __m256i __Y) { + return (__m256i) __builtin_ia32_pmaddubsw256_mask ((__v32qi) __X, + (__v32qi) __Y, + (__v16hi) _mm256_setzero_si256(), + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_madd_epi16 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_pmaddwd128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_madd_epi16 (__mmask8 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pmaddwd128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v4si) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_madd_epi16 (__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pmaddwd256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_madd_epi16 (__mmask8 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pmaddwd256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v8si) _mm256_setzero_si256(), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtsepi16_epi8 (__m128i __A) { + return (__m128i) __builtin_ia32_pmovswb128_mask ((__v8hi) __A, + (__v16qi) _mm_setzero_si128(), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvtsepi16_epi8 (__m128i __O, __mmask8 __M, __m128i __A) { + return (__m128i) __builtin_ia32_pmovswb128_mask ((__v8hi) __A, + (__v16qi) __O, + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvtsepi16_epi8 (__mmask8 __M, __m128i __A) { + return (__m128i) __builtin_ia32_pmovswb128_mask ((__v8hi) __A, + (__v16qi) _mm_setzero_si128(), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_cvtsepi16_epi8 (__m256i __A) { + return (__m128i) __builtin_ia32_pmovswb256_mask ((__v16hi) __A, + (__v16qi) _mm_setzero_si128(), + (__mmask16) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_mask_cvtsepi16_epi8 (__m128i __O, __mmask16 __M, __m256i __A) { + return (__m128i) __builtin_ia32_pmovswb256_mask ((__v16hi) __A, + (__v16qi) __O, + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_maskz_cvtsepi16_epi8 (__mmask16 __M, __m256i __A) { + return (__m128i) __builtin_ia32_pmovswb256_mask ((__v16hi) __A, + (__v16qi) _mm_setzero_si128(), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtusepi16_epi8 (__m128i __A) { + return (__m128i) __builtin_ia32_pmovuswb128_mask ((__v8hi) __A, + (__v16qi) _mm_setzero_si128(), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvtusepi16_epi8 (__m128i __O, __mmask8 __M, __m128i __A) { + return (__m128i) __builtin_ia32_pmovuswb128_mask ((__v8hi) __A, + (__v16qi) __O, + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvtusepi16_epi8 (__mmask8 __M, __m128i __A) { + return (__m128i) __builtin_ia32_pmovuswb128_mask ((__v8hi) __A, + (__v16qi) _mm_setzero_si128(), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_cvtusepi16_epi8 (__m256i __A) { + return (__m128i) __builtin_ia32_pmovuswb256_mask ((__v16hi) __A, + (__v16qi) _mm_setzero_si128(), + (__mmask16) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_mask_cvtusepi16_epi8 (__m128i __O, __mmask16 __M, __m256i __A) { + return (__m128i) __builtin_ia32_pmovuswb256_mask ((__v16hi) __A, + (__v16qi) __O, + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_maskz_cvtusepi16_epi8 (__mmask16 __M, __m256i __A) { + return (__m128i) __builtin_ia32_pmovuswb256_mask ((__v16hi) __A, + (__v16qi) _mm_setzero_si128(), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtepi16_epi8 (__m128i __A) { + + return (__m128i) __builtin_ia32_pmovwb128_mask ((__v8hi) __A, + (__v16qi) _mm_setzero_si128(), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvtepi16_epi8 (__m128i __O, __mmask8 __M, __m128i __A) { + return (__m128i) __builtin_ia32_pmovwb128_mask ((__v8hi) __A, + (__v16qi) __O, + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvtepi16_epi8 (__mmask8 __M, __m128i __A) { + return (__m128i) __builtin_ia32_pmovwb128_mask ((__v8hi) __A, + (__v16qi) _mm_setzero_si128(), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_cvtepi16_epi8 (__m256i __A) { + return (__m128i) __builtin_ia32_pmovwb256_mask ((__v16hi) __A, + (__v16qi) _mm_setzero_si128(), + (__mmask16) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_mask_cvtepi16_epi8 (__m128i __O, __mmask16 __M, __m256i __A) { + return (__m128i) __builtin_ia32_pmovwb256_mask ((__v16hi) __A, + (__v16qi) __O, + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_maskz_cvtepi16_epi8 (__mmask16 __M, __m256i __A) { + return (__m128i) __builtin_ia32_pmovwb256_mask ((__v16hi) __A, + (__v16qi) _mm_setzero_si128(), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_mulhrs_epi16 (__m128i __W, __mmask8 __U, __m128i __X, __m128i __Y) { + return (__m128i) __builtin_ia32_pmulhrsw128_mask ((__v8hi) __X, + (__v8hi) __Y, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_mulhrs_epi16 (__mmask8 __U, __m128i __X, __m128i __Y) { + return (__m128i) __builtin_ia32_pmulhrsw128_mask ((__v8hi) __X, + (__v8hi) __Y, + (__v8hi) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_mulhrs_epi16 (__m256i __W, __mmask16 __U, __m256i __X, __m256i __Y) { + return (__m256i) __builtin_ia32_pmulhrsw256_mask ((__v16hi) __X, + (__v16hi) __Y, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_mulhrs_epi16 (__mmask16 __U, __m256i __X, __m256i __Y) { + return (__m256i) __builtin_ia32_pmulhrsw256_mask ((__v16hi) __X, + (__v16hi) __Y, + (__v16hi) _mm256_setzero_si256(), + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_mulhi_epu16 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_pmulhuw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_mulhi_epu16 (__mmask8 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pmulhuw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_mulhi_epu16 (__m256i __W, __mmask16 __U, __m256i __A, + __m256i __B) { + return (__m256i) __builtin_ia32_pmulhuw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_mulhi_epu16 (__mmask16 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pmulhuw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) _mm256_setzero_si256(), + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_mulhi_epi16 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_pmulhw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_mulhi_epi16 (__mmask8 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pmulhw128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_mulhi_epi16 (__m256i __W, __mmask16 __U, __m256i __A, + __m256i __B) { + return (__m256i) __builtin_ia32_pmulhw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_mulhi_epi16 (__mmask16 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pmulhw256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) _mm256_setzero_si256(), + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_unpackhi_epi8 (__m128i __W, __mmask16 __U, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_punpckhbw128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) __W, + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_unpackhi_epi8 (__mmask16 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_punpckhbw128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) _mm_setzero_si128(), + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_unpackhi_epi8 (__m256i __W, __mmask32 __U, __m256i __A, + __m256i __B) { + return (__m256i) __builtin_ia32_punpckhbw256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) __W, + (__mmask32) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_unpackhi_epi8 (__mmask32 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_punpckhbw256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) _mm256_setzero_si256(), + (__mmask32) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_unpackhi_epi16 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_punpckhwd128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_unpackhi_epi16 (__mmask8 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_punpckhwd128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_unpackhi_epi16 (__m256i __W, __mmask16 __U, __m256i __A, + __m256i __B) { + return (__m256i) __builtin_ia32_punpckhwd256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_unpackhi_epi16 (__mmask16 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_punpckhwd256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) _mm256_setzero_si256(), + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_unpacklo_epi8 (__m128i __W, __mmask16 __U, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_punpcklbw128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) __W, + (__mmask16) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_unpacklo_epi8 (__mmask16 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_punpcklbw128_mask ((__v16qi) __A, + (__v16qi) __B, + (__v16qi) _mm_setzero_si128(), + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_unpacklo_epi8 (__m256i __W, __mmask32 __U, __m256i __A, + __m256i __B) { + return (__m256i) __builtin_ia32_punpcklbw256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) __W, + (__mmask32) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_unpacklo_epi8 (__mmask32 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_punpcklbw256_mask ((__v32qi) __A, + (__v32qi) __B, + (__v32qi) _mm256_setzero_si256(), + (__mmask32) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_unpacklo_epi16 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_punpcklwd128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_unpacklo_epi16 (__mmask8 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_punpcklwd128_mask ((__v8hi) __A, + (__v8hi) __B, + (__v8hi) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_unpacklo_epi16 (__m256i __W, __mmask16 __U, __m256i __A, + __m256i __B) { + return (__m256i) __builtin_ia32_punpcklwd256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) __W, + (__mmask16) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_unpacklo_epi16 (__mmask16 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_punpcklwd256_mask ((__v16hi) __A, + (__v16hi) __B, + (__v16hi) _mm256_setzero_si256(), + (__mmask16) __U); +} + +#define _mm_cmp_epi8_mask(a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)(__m128i)(a), \ + (__v16qi)(__m128i)(b), \ + (p), (__mmask16)-1); }) + +#define _mm_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)(__m128i)(a), \ + (__v16qi)(__m128i)(b), \ + (p), (__mmask16)(m)); }) + +#define _mm_cmp_epu8_mask(a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)(__m128i)(a), \ + (__v16qi)(__m128i)(b), \ + (p), (__mmask16)-1); }) + +#define _mm_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)(__m128i)(a), \ + (__v16qi)(__m128i)(b), \ + (p), (__mmask16)(m)); }) + +#define _mm256_cmp_epi8_mask(a, b, p) __extension__ ({ \ + (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)(__m256i)(a), \ + (__v32qi)(__m256i)(b), \ + (p), (__mmask32)-1); }) + +#define _mm256_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ + (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)(__m256i)(a), \ + (__v32qi)(__m256i)(b), \ + (p), (__mmask32)(m)); }) + +#define _mm256_cmp_epu8_mask(a, b, p) __extension__ ({ \ + (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)(__m256i)(a), \ + (__v32qi)(__m256i)(b), \ + (p), (__mmask32)-1); }) + +#define _mm256_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ + (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)(__m256i)(a), \ + (__v32qi)(__m256i)(b), \ + (p), (__mmask32)(m)); }) + +#define _mm_cmp_epi16_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)(__m128i)(a), \ + (__v8hi)(__m128i)(b), \ + (p), (__mmask8)-1); }) + +#define _mm_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)(__m128i)(a), \ + (__v8hi)(__m128i)(b), \ + (p), (__mmask8)(m)); }) + +#define _mm_cmp_epu16_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)(__m128i)(a), \ + (__v8hi)(__m128i)(b), \ + (p), (__mmask8)-1); }) + +#define _mm_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)(__m128i)(a), \ + (__v8hi)(__m128i)(b), \ + (p), (__mmask8)(m)); }) + +#define _mm256_cmp_epi16_mask(a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)(__m256i)(a), \ + (__v16hi)(__m256i)(b), \ + (p), (__mmask16)-1); }) + +#define _mm256_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)(__m256i)(a), \ + (__v16hi)(__m256i)(b), \ + (p), (__mmask16)(m)); }) + +#define _mm256_cmp_epu16_mask(a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)(__m256i)(a), \ + (__v16hi)(__m256i)(b), \ + (p), (__mmask16)-1); }) + +#define _mm256_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)(__m256i)(a), \ + (__v16hi)(__m256i)(b), \ + (p), (__mmask16)(m)); }) + +#undef __DEFAULT_FN_ATTRS + +#endif /* __AVX512VLBWINTRIN_H */ diff --git a/headers/clang/avx512vldqintrin.h b/headers/clang/avx512vldqintrin.h new file mode 100644 index 0000000000..8f48b0bc28 --- /dev/null +++ b/headers/clang/avx512vldqintrin.h @@ -0,0 +1,953 @@ +/*===---- avx512vldqintrin.h - AVX512VL and AVX512DQ intrinsics ---------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __AVX512VLDQINTRIN_H +#define __AVX512VLDQINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512vl,avx512dq"))) + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mullo_epi64 (__m256i __A, __m256i __B) { + return (__m256i) ((__v4di) __A * (__v4di) __B); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_mullo_epi64 (__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pmullq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_mullo_epi64 (__mmask8 __U, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pmullq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mullo_epi64 (__m128i __A, __m128i __B) { + return (__m128i) ((__v2di) __A * (__v2di) __B); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_mullo_epi64 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pmullq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_mullo_epi64 (__mmask8 __U, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pmullq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_andnot_pd (__m256d __W, __mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_andnpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_andnot_pd (__mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_andnpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_andnot_pd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_andnpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_andnot_pd (__mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_andnpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_andnot_ps (__m256 __W, __mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_andnps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_andnot_ps (__mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_andnps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_andnot_ps (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_andnps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_andnot_ps (__mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_andnps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_and_pd (__m256d __W, __mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_andpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_and_pd (__mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_andpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_and_pd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_andpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_and_pd (__mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_andpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_and_ps (__m256 __W, __mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_andps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_and_ps (__mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_andps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_and_ps (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_andps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_and_ps (__mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_andps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_xor_pd (__m256d __W, __mmask8 __U, __m256d __A, + __m256d __B) { + return (__m256d) __builtin_ia32_xorpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_xor_pd (__mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_xorpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_xor_pd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_xorpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_xor_pd (__mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_xorpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_xor_ps (__m256 __W, __mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_xorps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_xor_ps (__mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_xorps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_xor_ps (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_xorps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_xor_ps (__mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_xorps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_or_pd (__m256d __W, __mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_orpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_or_pd (__mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_orpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_or_pd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_orpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_or_pd (__mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_orpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_or_ps (__m256 __W, __mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_orps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_or_ps (__mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_orps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_or_ps (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_orps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_or_ps (__mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_orps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtpd_epi64 (__m128d __A) { + return (__m128i) __builtin_ia32_cvtpd2qq128_mask ((__v2df) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvtpd_epi64 (__m128i __W, __mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvtpd2qq128_mask ((__v2df) __A, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvtpd_epi64 (__mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvtpd2qq128_mask ((__v2df) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtpd_epi64 (__m256d __A) { + return (__m256i) __builtin_ia32_cvtpd2qq256_mask ((__v4df) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_cvtpd_epi64 (__m256i __W, __mmask8 __U, __m256d __A) { + return (__m256i) __builtin_ia32_cvtpd2qq256_mask ((__v4df) __A, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_cvtpd_epi64 (__mmask8 __U, __m256d __A) { + return (__m256i) __builtin_ia32_cvtpd2qq256_mask ((__v4df) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtpd_epu64 (__m128d __A) { + return (__m128i) __builtin_ia32_cvtpd2uqq128_mask ((__v2df) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvtpd_epu64 (__m128i __W, __mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvtpd2uqq128_mask ((__v2df) __A, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvtpd_epu64 (__mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvtpd2uqq128_mask ((__v2df) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtpd_epu64 (__m256d __A) { + return (__m256i) __builtin_ia32_cvtpd2uqq256_mask ((__v4df) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_cvtpd_epu64 (__m256i __W, __mmask8 __U, __m256d __A) { + return (__m256i) __builtin_ia32_cvtpd2uqq256_mask ((__v4df) __A, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_cvtpd_epu64 (__mmask8 __U, __m256d __A) { + return (__m256i) __builtin_ia32_cvtpd2uqq256_mask ((__v4df) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtps_epi64 (__m128 __A) { + return (__m128i) __builtin_ia32_cvtps2qq128_mask ((__v4sf) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvtps_epi64 (__m128i __W, __mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvtps2qq128_mask ((__v4sf) __A, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvtps_epi64 (__mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvtps2qq128_mask ((__v4sf) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtps_epi64 (__m128 __A) { + return (__m256i) __builtin_ia32_cvtps2qq256_mask ((__v4sf) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_cvtps_epi64 (__m256i __W, __mmask8 __U, __m128 __A) { + return (__m256i) __builtin_ia32_cvtps2qq256_mask ((__v4sf) __A, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_cvtps_epi64 (__mmask8 __U, __m128 __A) { + return (__m256i) __builtin_ia32_cvtps2qq256_mask ((__v4sf) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtps_epu64 (__m128 __A) { + return (__m128i) __builtin_ia32_cvtps2uqq128_mask ((__v4sf) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvtps_epu64 (__m128i __W, __mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvtps2uqq128_mask ((__v4sf) __A, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvtps_epu64 (__mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvtps2uqq128_mask ((__v4sf) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtps_epu64 (__m128 __A) { + return (__m256i) __builtin_ia32_cvtps2uqq256_mask ((__v4sf) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_cvtps_epu64 (__m256i __W, __mmask8 __U, __m128 __A) { + return (__m256i) __builtin_ia32_cvtps2uqq256_mask ((__v4sf) __A, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_cvtps_epu64 (__mmask8 __U, __m128 __A) { + return (__m256i) __builtin_ia32_cvtps2uqq256_mask ((__v4sf) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cvtepi64_pd (__m128i __A) { + return (__m128d) __builtin_ia32_cvtqq2pd128_mask ((__v2di) __A, + (__v2df) _mm_setzero_pd(), + (__mmask8) -1); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_cvtepi64_pd (__m128d __W, __mmask8 __U, __m128i __A) { + return (__m128d) __builtin_ia32_cvtqq2pd128_mask ((__v2di) __A, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_cvtepi64_pd (__mmask8 __U, __m128i __A) { + return (__m128d) __builtin_ia32_cvtqq2pd128_mask ((__v2di) __A, + (__v2df) _mm_setzero_pd(), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_cvtepi64_pd (__m256i __A) { + return (__m256d) __builtin_ia32_cvtqq2pd256_mask ((__v4di) __A, + (__v4df) _mm256_setzero_pd(), + (__mmask8) -1); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_cvtepi64_pd (__m256d __W, __mmask8 __U, __m256i __A) { + return (__m256d) __builtin_ia32_cvtqq2pd256_mask ((__v4di) __A, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_cvtepi64_pd (__mmask8 __U, __m256i __A) { + return (__m256d) __builtin_ia32_cvtqq2pd256_mask ((__v4di) __A, + (__v4df) _mm256_setzero_pd(), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvtepi64_ps (__m128i __A) { + return (__m128) __builtin_ia32_cvtqq2ps128_mask ((__v2di) __A, + (__v4sf) _mm_setzero_ps(), + (__mmask8) -1); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_cvtepi64_ps (__m128 __W, __mmask8 __U, __m128i __A) { + return (__m128) __builtin_ia32_cvtqq2ps128_mask ((__v2di) __A, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_cvtepi64_ps (__mmask8 __U, __m128i __A) { + return (__m128) __builtin_ia32_cvtqq2ps128_mask ((__v2di) __A, + (__v4sf) _mm_setzero_ps(), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm256_cvtepi64_ps (__m256i __A) { + return (__m128) __builtin_ia32_cvtqq2ps256_mask ((__v4di) __A, + (__v4sf) _mm_setzero_ps(), + (__mmask8) -1); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm256_mask_cvtepi64_ps (__m128 __W, __mmask8 __U, __m256i __A) { + return (__m128) __builtin_ia32_cvtqq2ps256_mask ((__v4di) __A, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm256_maskz_cvtepi64_ps (__mmask8 __U, __m256i __A) { + return (__m128) __builtin_ia32_cvtqq2ps256_mask ((__v4di) __A, + (__v4sf) _mm_setzero_ps(), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvttpd_epi64 (__m128d __A) { + return (__m128i) __builtin_ia32_cvttpd2qq128_mask ((__v2df) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvttpd_epi64 (__m128i __W, __mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvttpd2qq128_mask ((__v2df) __A, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvttpd_epi64 (__mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvttpd2qq128_mask ((__v2df) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvttpd_epi64 (__m256d __A) { + return (__m256i) __builtin_ia32_cvttpd2qq256_mask ((__v4df) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_cvttpd_epi64 (__m256i __W, __mmask8 __U, __m256d __A) { + return (__m256i) __builtin_ia32_cvttpd2qq256_mask ((__v4df) __A, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_cvttpd_epi64 (__mmask8 __U, __m256d __A) { + return (__m256i) __builtin_ia32_cvttpd2qq256_mask ((__v4df) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvttpd_epu64 (__m128d __A) { + return (__m128i) __builtin_ia32_cvttpd2uqq128_mask ((__v2df) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvttpd_epu64 (__m128i __W, __mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvttpd2uqq128_mask ((__v2df) __A, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvttpd_epu64 (__mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvttpd2uqq128_mask ((__v2df) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvttpd_epu64 (__m256d __A) { + return (__m256i) __builtin_ia32_cvttpd2uqq256_mask ((__v4df) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_cvttpd_epu64 (__m256i __W, __mmask8 __U, __m256d __A) { + return (__m256i) __builtin_ia32_cvttpd2uqq256_mask ((__v4df) __A, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_cvttpd_epu64 (__mmask8 __U, __m256d __A) { + return (__m256i) __builtin_ia32_cvttpd2uqq256_mask ((__v4df) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvttps_epi64 (__m128 __A) { + return (__m128i) __builtin_ia32_cvttps2qq128_mask ((__v4sf) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvttps_epi64 (__m128i __W, __mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvttps2qq128_mask ((__v4sf) __A, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvttps_epi64 (__mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvttps2qq128_mask ((__v4sf) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvttps_epi64 (__m128 __A) { + return (__m256i) __builtin_ia32_cvttps2qq256_mask ((__v4sf) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_cvttps_epi64 (__m256i __W, __mmask8 __U, __m128 __A) { + return (__m256i) __builtin_ia32_cvttps2qq256_mask ((__v4sf) __A, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_cvttps_epi64 (__mmask8 __U, __m128 __A) { + return (__m256i) __builtin_ia32_cvttps2qq256_mask ((__v4sf) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvttps_epu64 (__m128 __A) { + return (__m128i) __builtin_ia32_cvttps2uqq128_mask ((__v4sf) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvttps_epu64 (__m128i __W, __mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvttps2uqq128_mask ((__v4sf) __A, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvttps_epu64 (__mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvttps2uqq128_mask ((__v4sf) __A, + (__v2di) _mm_setzero_si128(), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvttps_epu64 (__m128 __A) { + return (__m256i) __builtin_ia32_cvttps2uqq256_mask ((__v4sf) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_cvttps_epu64 (__m256i __W, __mmask8 __U, __m128 __A) { + return (__m256i) __builtin_ia32_cvttps2uqq256_mask ((__v4sf) __A, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_cvttps_epu64 (__mmask8 __U, __m128 __A) { + return (__m256i) __builtin_ia32_cvttps2uqq256_mask ((__v4sf) __A, + (__v4di) _mm256_setzero_si256(), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cvtepu64_pd (__m128i __A) { + return (__m128d) __builtin_ia32_cvtuqq2pd128_mask ((__v2di) __A, + (__v2df) _mm_setzero_pd(), + (__mmask8) -1); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_cvtepu64_pd (__m128d __W, __mmask8 __U, __m128i __A) { + return (__m128d) __builtin_ia32_cvtuqq2pd128_mask ((__v2di) __A, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_cvtepu64_pd (__mmask8 __U, __m128i __A) { + return (__m128d) __builtin_ia32_cvtuqq2pd128_mask ((__v2di) __A, + (__v2df) _mm_setzero_pd(), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_cvtepu64_pd (__m256i __A) { + return (__m256d) __builtin_ia32_cvtuqq2pd256_mask ((__v4di) __A, + (__v4df) _mm256_setzero_pd(), + (__mmask8) -1); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_cvtepu64_pd (__m256d __W, __mmask8 __U, __m256i __A) { + return (__m256d) __builtin_ia32_cvtuqq2pd256_mask ((__v4di) __A, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_cvtepu64_pd (__mmask8 __U, __m256i __A) { + return (__m256d) __builtin_ia32_cvtuqq2pd256_mask ((__v4di) __A, + (__v4df) _mm256_setzero_pd(), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvtepu64_ps (__m128i __A) { + return (__m128) __builtin_ia32_cvtuqq2ps128_mask ((__v2di) __A, + (__v4sf) _mm_setzero_ps(), + (__mmask8) -1); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_cvtepu64_ps (__m128 __W, __mmask8 __U, __m128i __A) { + return (__m128) __builtin_ia32_cvtuqq2ps128_mask ((__v2di) __A, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_cvtepu64_ps (__mmask8 __U, __m128i __A) { + return (__m128) __builtin_ia32_cvtuqq2ps128_mask ((__v2di) __A, + (__v4sf) _mm_setzero_ps(), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm256_cvtepu64_ps (__m256i __A) { + return (__m128) __builtin_ia32_cvtuqq2ps256_mask ((__v4di) __A, + (__v4sf) _mm_setzero_ps(), + (__mmask8) -1); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm256_mask_cvtepu64_ps (__m128 __W, __mmask8 __U, __m256i __A) { + return (__m128) __builtin_ia32_cvtuqq2ps256_mask ((__v4di) __A, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm256_maskz_cvtepu64_ps (__mmask8 __U, __m256i __A) { + return (__m128) __builtin_ia32_cvtuqq2ps256_mask ((__v4di) __A, + (__v4sf) _mm_setzero_ps(), + (__mmask8) __U); +} + +#define _mm_range_pd(__A, __B, __C) __extension__ ({ \ + (__m128d) __builtin_ia32_rangepd128_mask ((__v2df) __A, (__v2df) __B, __C, \ + (__v2df) _mm_setzero_pd(), (__mmask8) -1); }) + +#define _mm_mask_range_pd(__W, __U, __A, __B, __C) __extension__ ({ \ + (__m128d) __builtin_ia32_rangepd128_mask ((__v2df) __A, (__v2df) __B, __C, \ + (__v2df) __W, (__mmask8) __U); }) + +#define _mm_maskz_range_pd(__U, __A, __B, __C) __extension__ ({ \ + (__m128d) __builtin_ia32_rangepd128_mask ((__v2df) __A, (__v2df) __B, __C, \ + (__v2df) _mm_setzero_pd(), (__mmask8) __U); }) + +#define _mm256_range_pd(__A, __B, __C) __extension__ ({ \ + (__m256d) __builtin_ia32_rangepd256_mask ((__v4df) __A, (__v4df) __B, __C, \ + (__v4df) _mm256_setzero_pd(), (__mmask8) -1); }) + +#define _mm256_mask_range_pd(__W, __U, __A, __B, __C) __extension__ ({ \ + (__m256d) __builtin_ia32_rangepd256_mask ((__v4df) __A, (__v4df) __B, __C, \ + (__v4df) __W, (__mmask8) __U); }) + +#define _mm256_maskz_range_pd(__U, __A, __B, __C) __extension__ ({ \ + (__m256d) __builtin_ia32_rangepd256_mask ((__v4df) __A, (__v4df) __B, __C, \ + (__v4df) _mm256_setzero_pd(), (__mmask8) __U); }) + +#define _mm_range_ps(__A, __B, __C) __extension__ ({ \ + (__m128) __builtin_ia32_rangeps128_mask ((__v4sf) __A, (__v4sf) __B, __C, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) -1); }) + +#define _mm_mask_range_ps(__W, __U, __A, __B, __C) __extension__ ({ \ + (__m128) __builtin_ia32_rangeps128_mask ((__v4sf) __A, (__v4sf) __B, __C, \ + (__v4sf) __W, (__mmask8) __U); }) + +#define _mm_maskz_range_ps(__U, __A, __B, __C) __extension__ ({ \ + (__m128) __builtin_ia32_rangeps128_mask ((__v4sf) __A, (__v4sf) __B, __C, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) __U); }) + +#define _mm256_range_ps(__A, __B, __C) __extension__ ({ \ + (__m256) __builtin_ia32_rangeps256_mask ((__v8sf) __A, (__v8sf) __B, __C, \ + (__v8sf) _mm256_setzero_ps(), (__mmask8) -1); }) + +#define _mm256_mask_range_ps(__W, __U, __A, __B, __C) __extension__ ({ \ + (__m256) __builtin_ia32_rangeps256_mask ((__v8sf) __A, (__v8sf) __B, __C, \ + (__v8sf) __W, (__mmask8) __U); }) + +#define _mm256_maskz_range_ps(__U, __A, __B, __C) __extension__ ({ \ + (__m256) __builtin_ia32_rangeps256_mask ((__v8sf) __A, (__v8sf) __B, __C, \ + (__v8sf) _mm256_setzero_ps(), (__mmask8) __U); }) + +#define _mm_reduce_pd(__A, __B) __extension__ ({ \ + (__m128d) __builtin_ia32_reducepd128_mask ((__v2df) __A, __B, \ + (__v2df) _mm_setzero_pd(), (__mmask8) -1); }) + +#define _mm_mask_reduce_pd(__W, __U, __A, __B) __extension__ ({ \ + (__m128d) __builtin_ia32_reducepd128_mask ((__v2df) __A, __B, \ + (__v2df) __W, (__mmask8) __U); }) + +#define _mm_maskz_reduce_pd(__U, __A, __B) __extension__ ({ \ + (__m128d) __builtin_ia32_reducepd128_mask ((__v2df) __A, __B, \ + (__v2df) _mm_setzero_pd(), (__mmask8) __U); }) + +#define _mm256_reduce_pd(__A, __B) __extension__ ({ \ + (__m256d) __builtin_ia32_reducepd256_mask ((__v4df) __A, __B, \ + (__v4df) _mm256_setzero_pd(), (__mmask8) -1); }) + +#define _mm256_mask_reduce_pd(__W, __U, __A, __B) __extension__ ({ \ + (__m256d) __builtin_ia32_reducepd256_mask ((__v4df) __A, __B, \ + (__v4df) __W, (__mmask8) __U); }) + +#define _mm256_maskz_reduce_pd(__U, __A, __B) __extension__ ({ \ + (__m256d) __builtin_ia32_reducepd256_mask ((__v4df) __A, __B, \ + (__v4df) _mm256_setzero_pd(), (__mmask8) __U); }) + +#define _mm_reduce_ps(__A, __B) __extension__ ({ \ + (__m128) __builtin_ia32_reduceps128_mask ((__v4sf) __A, __B, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) -1); }) + +#define _mm_mask_reduce_ps(__W, __U, __A, __B) __extension__ ({ \ + (__m128) __builtin_ia32_reduceps128_mask ((__v4sf) __A, __B, \ + (__v4sf) __W, (__mmask8) __U); }) + +#define _mm_maskz_reduce_ps(__U, __A, __B) __extension__ ({ \ + (__m128) __builtin_ia32_reduceps128_mask ((__v4sf) __A, __B, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) __U); }) + +#define _mm256_reduce_ps(__A, __B) __extension__ ({ \ + (__m256) __builtin_ia32_reduceps256_mask ((__v8sf) __A, __B, \ + (__v8sf) _mm256_setzero_ps(), (__mmask8) -1); }) + +#define _mm256_mask_reduce_ps(__W, __U, __A, __B) __extension__ ({ \ + (__m256) __builtin_ia32_reduceps256_mask ((__v8sf) __A, __B, \ + (__v8sf) __W, (__mmask8) __U); }) + +#define _mm256_maskz_reduce_ps(__U, __A, __B) __extension__ ({ \ + (__m256) __builtin_ia32_reduceps256_mask ((__v8sf) __A, __B, \ + (__v8sf) _mm256_setzero_ps(), (__mmask8) __U); }) + +#undef __DEFAULT_FN_ATTRS + +#endif diff --git a/headers/clang/avx512vlintrin.h b/headers/clang/avx512vlintrin.h new file mode 100644 index 0000000000..8f13536fbb --- /dev/null +++ b/headers/clang/avx512vlintrin.h @@ -0,0 +1,4606 @@ +/*===---- avx512vlintrin.h - AVX512VL intrinsics ---------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __AVX512VLINTRIN_H +#define __AVX512VLINTRIN_H + +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512vl"))) +#define __DEFAULT_FN_ATTRS_BOTH __attribute__((__always_inline__, __nodebug__, __target__("avx512vl, avx512bw"))) + +/* Integer compare */ + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm_cmpeq_epi32_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_pcmpeqd128_mask((__v4si)__a, (__v4si)__b, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm_mask_cmpeq_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_pcmpeqd128_mask((__v4si)__a, (__v4si)__b, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpeq_epu32_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 0, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpeq_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 0, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm256_cmpeq_epi32_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_pcmpeqd256_mask((__v8si)__a, (__v8si)__b, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm256_mask_cmpeq_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_pcmpeqd256_mask((__v8si)__a, (__v8si)__b, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmpeq_epu32_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 0, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmpeq_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 0, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm_cmpeq_epi64_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_pcmpeqq128_mask((__v2di)__a, (__v2di)__b, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm_mask_cmpeq_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_pcmpeqq128_mask((__v2di)__a, (__v2di)__b, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpeq_epu64_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 0, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpeq_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 0, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm256_cmpeq_epi64_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_pcmpeqq256_mask((__v4di)__a, (__v4di)__b, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm256_mask_cmpeq_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_pcmpeqq256_mask((__v4di)__a, (__v4di)__b, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmpeq_epu64_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 0, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmpeq_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 0, + __u); +} + + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpge_epi32_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 5, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpge_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 5, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpge_epu32_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 5, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpge_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 5, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmpge_epi32_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 5, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmpge_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 5, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmpge_epu32_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 5, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmpge_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 5, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpge_epi64_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 5, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpge_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 5, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpge_epu64_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 5, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpge_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 5, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmpge_epi64_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 5, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmpge_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 5, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmpge_epu64_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 5, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmpge_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 5, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm_cmpgt_epi32_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_pcmpgtd128_mask((__v4si)__a, (__v4si)__b, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm_mask_cmpgt_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_pcmpgtd128_mask((__v4si)__a, (__v4si)__b, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpgt_epu32_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 6, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpgt_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 6, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm256_cmpgt_epi32_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_pcmpgtd256_mask((__v8si)__a, (__v8si)__b, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm256_mask_cmpgt_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_pcmpgtd256_mask((__v8si)__a, (__v8si)__b, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmpgt_epu32_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 6, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmpgt_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 6, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm_cmpgt_epi64_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_pcmpgtq128_mask((__v2di)__a, (__v2di)__b, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm_mask_cmpgt_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_pcmpgtq128_mask((__v2di)__a, (__v2di)__b, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpgt_epu64_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 6, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpgt_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 6, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm256_cmpgt_epi64_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_pcmpgtq256_mask((__v4di)__a, (__v4di)__b, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS_BOTH +_mm256_mask_cmpgt_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_pcmpgtq256_mask((__v4di)__a, (__v4di)__b, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmpgt_epu64_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 6, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmpgt_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 6, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmple_epi32_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 2, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmple_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 2, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmple_epu32_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 2, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmple_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 2, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmple_epi32_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 2, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmple_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 2, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmple_epu32_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 2, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmple_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 2, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmple_epi64_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 2, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmple_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 2, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmple_epu64_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 2, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmple_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 2, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmple_epi64_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 2, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmple_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 2, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmple_epu64_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 2, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmple_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 2, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmplt_epi32_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 1, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmplt_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 1, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmplt_epu32_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 1, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmplt_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 1, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmplt_epi32_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 1, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmplt_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 1, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmplt_epu32_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 1, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmplt_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 1, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmplt_epi64_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 1, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmplt_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 1, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmplt_epu64_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 1, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmplt_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 1, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmplt_epi64_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 1, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmplt_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 1, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmplt_epu64_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 1, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmplt_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 1, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpneq_epi32_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 4, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpneq_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 4, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpneq_epu32_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 4, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpneq_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 4, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmpneq_epi32_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 4, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmpneq_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 4, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmpneq_epu32_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 4, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmpneq_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 4, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpneq_epi64_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 4, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpneq_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 4, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_cmpneq_epu64_mask(__m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 4, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm_mask_cmpneq_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { + return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 4, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmpneq_epi64_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 4, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmpneq_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 4, + __u); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_cmpneq_epu64_mask(__m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 4, + (__mmask8)-1); +} + +static __inline__ __mmask8 __DEFAULT_FN_ATTRS +_mm256_mask_cmpneq_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { + return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 4, + __u); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_add_epi32 (__m256i __W, __mmask8 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_paddd256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_add_epi32 (__mmask8 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_paddd256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_add_epi64 (__m256i __W, __mmask8 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_paddq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_add_epi64 (__mmask8 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_paddq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_sub_epi32 (__m256i __W, __mmask8 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_psubd256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_sub_epi32 (__mmask8 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_psubd256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_sub_epi64 (__m256i __W, __mmask8 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_psubq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_sub_epi64 (__mmask8 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_psubq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_add_epi32 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_paddd128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_add_epi32 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_paddd128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_add_epi64 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_paddq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_add_epi64 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_paddq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_sub_epi32 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_psubd128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_sub_epi32 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_psubd128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_sub_epi64 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_psubq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_sub_epi64 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_psubq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_mul_epi32 (__m256i __W, __mmask8 __M, __m256i __X, + __m256i __Y) +{ + return (__m256i) __builtin_ia32_pmuldq256_mask ((__v8si) __X, + (__v8si) __Y, + (__v4di) __W, __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_mul_epi32 (__mmask8 __M, __m256i __X, __m256i __Y) +{ + return (__m256i) __builtin_ia32_pmuldq256_mask ((__v8si) __X, + (__v8si) __Y, + (__v4di) + _mm256_setzero_si256 (), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_mul_epi32 (__m128i __W, __mmask8 __M, __m128i __X, + __m128i __Y) +{ + return (__m128i) __builtin_ia32_pmuldq128_mask ((__v4si) __X, + (__v4si) __Y, + (__v2di) __W, __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_mul_epi32 (__mmask8 __M, __m128i __X, __m128i __Y) +{ + return (__m128i) __builtin_ia32_pmuldq128_mask ((__v4si) __X, + (__v4si) __Y, + (__v2di) + _mm_setzero_si128 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_mul_epu32 (__m256i __W, __mmask8 __M, __m256i __X, + __m256i __Y) +{ + return (__m256i) __builtin_ia32_pmuludq256_mask ((__v8si) __X, + (__v8si) __Y, + (__v4di) __W, __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_mul_epu32 (__mmask8 __M, __m256i __X, __m256i __Y) +{ + return (__m256i) __builtin_ia32_pmuludq256_mask ((__v8si) __X, + (__v8si) __Y, + (__v4di) + _mm256_setzero_si256 (), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_mul_epu32 (__m128i __W, __mmask8 __M, __m128i __X, + __m128i __Y) +{ + return (__m128i) __builtin_ia32_pmuludq128_mask ((__v4si) __X, + (__v4si) __Y, + (__v2di) __W, __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_mul_epu32 (__mmask8 __M, __m128i __X, __m128i __Y) +{ + return (__m128i) __builtin_ia32_pmuludq128_mask ((__v4si) __X, + (__v4si) __Y, + (__v2di) + _mm_setzero_si128 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_mullo_epi32 (__mmask8 __M, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pmulld256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) + _mm256_setzero_si256 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_mullo_epi32 (__m256i __W, __mmask8 __M, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pmulld256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) __W, __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_mullo_epi32 (__mmask8 __M, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pmulld128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) + _mm_setzero_si128 (), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_mullo_epi32 (__m128i __W, __mmask16 __M, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pmulld128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) __W, __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_and_epi32 (__m256i __W, __mmask8 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pandd256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_and_epi32 (__mmask8 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pandd256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_and_epi32 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pandd128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_and_epi32 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pandd128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_andnot_epi32 (__m256i __W, __mmask8 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pandnd256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_andnot_epi32 (__mmask8 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pandnd256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_andnot_epi32 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pandnd128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_andnot_epi32 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pandnd128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_or_epi32 (__m256i __W, __mmask8 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pord256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_or_epi32 (__mmask8 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pord256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_or_epi32 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pord128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_or_epi32 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pord128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_xor_epi32 (__m256i __W, __mmask8 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pxord256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_xor_epi32 (__mmask8 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pxord256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_xor_epi32 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pxord128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_xor_epi32 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pxord128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_and_epi64 (__m256i __W, __mmask8 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pandq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) __W, __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_and_epi64 (__mmask8 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pandq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_pd (), + __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_and_epi64 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pandq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) __W, __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_and_epi64 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pandq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_pd (), + __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_andnot_epi64 (__m256i __W, __mmask8 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pandnq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) __W, __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_andnot_epi64 (__mmask8 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pandnq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_pd (), + __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_andnot_epi64 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pandnq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) __W, __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_andnot_epi64 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pandnq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_pd (), + __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_or_epi64 (__m256i __W, __mmask8 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_porq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_or_epi64 (__mmask8 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_porq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_or_epi64 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_porq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_or_epi64 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_porq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_xor_epi64 (__m256i __W, __mmask8 __U, __m256i __A, + __m256i __B) +{ + return (__m256i) __builtin_ia32_pxorq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_xor_epi64 (__mmask8 __U, __m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_pxorq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_xor_epi64 (__m128i __W, __mmask8 __U, __m128i __A, + __m128i __B) +{ + return (__m128i) __builtin_ia32_pxorq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_xor_epi64 (__mmask8 __U, __m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_pxorq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +#define _mm_cmp_epi32_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)(__m128i)(a), \ + (__v4si)(__m128i)(b), \ + (p), (__mmask8)-1); }) + +#define _mm_mask_cmp_epi32_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)(__m128i)(a), \ + (__v4si)(__m128i)(b), \ + (p), (__mmask8)(m)); }) + +#define _mm_cmp_epu32_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)(__m128i)(a), \ + (__v4si)(__m128i)(b), \ + (p), (__mmask8)-1); }) + +#define _mm_mask_cmp_epu32_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)(__m128i)(a), \ + (__v4si)(__m128i)(b), \ + (p), (__mmask8)(m)); }) + +#define _mm256_cmp_epi32_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)(__m256i)(a), \ + (__v8si)(__m256i)(b), \ + (p), (__mmask8)-1); }) + +#define _mm256_mask_cmp_epi32_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)(__m256i)(a), \ + (__v8si)(__m256i)(b), \ + (p), (__mmask8)(m)); }) + +#define _mm256_cmp_epu32_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)(__m256i)(a), \ + (__v8si)(__m256i)(b), \ + (p), (__mmask8)-1); }) + +#define _mm256_mask_cmp_epu32_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)(__m256i)(a), \ + (__v8si)(__m256i)(b), \ + (p), (__mmask8)(m)); }) + +#define _mm_cmp_epi64_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)(__m128i)(a), \ + (__v2di)(__m128i)(b), \ + (p), (__mmask8)-1); }) + +#define _mm_mask_cmp_epi64_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)(__m128i)(a), \ + (__v2di)(__m128i)(b), \ + (p), (__mmask8)(m)); }) + +#define _mm_cmp_epu64_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)(__m128i)(a), \ + (__v2di)(__m128i)(b), \ + (p), (__mmask8)-1); }) + +#define _mm_mask_cmp_epu64_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)(__m128i)(a), \ + (__v2di)(__m128i)(b), \ + (p), (__mmask8)(m)); }) + +#define _mm256_cmp_epi64_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)(__m256i)(a), \ + (__v4di)(__m256i)(b), \ + (p), (__mmask8)-1); }) + +#define _mm256_mask_cmp_epi64_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)(__m256i)(a), \ + (__v4di)(__m256i)(b), \ + (p), (__mmask8)(m)); }) + +#define _mm256_cmp_epu64_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)(__m256i)(a), \ + (__v4di)(__m256i)(b), \ + (p), (__mmask8)-1); }) + +#define _mm256_mask_cmp_epu64_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)(__m256i)(a), \ + (__v4di)(__m256i)(b), \ + (p), (__mmask8)(m)); }) + +#define _mm256_cmp_ps_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpps256_mask((__v8sf)(__m256)(a), \ + (__v8sf)(__m256)(b), \ + (p), (__mmask8)-1); }) + +#define _mm256_mask_cmp_ps_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpps256_mask((__v8sf)(__m256)(a), \ + (__v8sf)(__m256)(b), \ + (p), (__mmask8)(m)); }) + +#define _mm256_cmp_pd_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmppd256_mask((__v4df)(__m256)(a), \ + (__v4df)(__m256)(b), \ + (p), (__mmask8)-1); }) + +#define _mm256_mask_cmp_pd_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmppd256_mask((__v4df)(__m256)(a), \ + (__v4df)(__m256)(b), \ + (p), (__mmask8)(m)); }) + +#define _mm128_cmp_ps_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpps128_mask((__v4sf)(__m128)(a), \ + (__v4sf)(__m128)(b), \ + (p), (__mmask8)-1); }) + +#define _mm128_mask_cmp_ps_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpps128_mask((__v4sf)(__m128)(a), \ + (__v4sf)(__m128)(b), \ + (p), (__mmask8)(m)); }) + +#define _mm128_cmp_pd_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmppd128_mask((__v2df)(__m128)(a), \ + (__v2df)(__m128)(b), \ + (p), (__mmask8)-1); }) + +#define _mm128_mask_cmp_pd_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmppd128_mask((__v2df)(__m128)(a), \ + (__v2df)(__m128)(b), \ + (p), (__mmask8)(m)); }) + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_fmadd_pd(__m128d __A, __mmask8 __U, __m128d __B, __m128d __C) +{ + return (__m128d) __builtin_ia32_vfmaddpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask3_fmadd_pd(__m128d __A, __m128d __B, __m128d __C, __mmask8 __U) +{ + return (__m128d) __builtin_ia32_vfmaddpd128_mask3 ((__v2df) __A, + (__v2df) __B, + (__v2df) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_fmadd_pd(__mmask8 __U, __m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d) __builtin_ia32_vfmaddpd128_maskz ((__v2df) __A, + (__v2df) __B, + (__v2df) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_fmsub_pd(__m128d __A, __mmask8 __U, __m128d __B, __m128d __C) +{ + return (__m128d) __builtin_ia32_vfmaddpd128_mask ((__v2df) __A, + (__v2df) __B, + -(__v2df) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_fmsub_pd(__mmask8 __U, __m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d) __builtin_ia32_vfmaddpd128_maskz ((__v2df) __A, + (__v2df) __B, + -(__v2df) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask3_fnmadd_pd(__m128d __A, __m128d __B, __m128d __C, __mmask8 __U) +{ + return (__m128d) __builtin_ia32_vfmaddpd128_mask3 (-(__v2df) __A, + (__v2df) __B, + (__v2df) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_fnmadd_pd(__mmask8 __U, __m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d) __builtin_ia32_vfmaddpd128_maskz (-(__v2df) __A, + (__v2df) __B, + (__v2df) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_fnmsub_pd(__mmask8 __U, __m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d) __builtin_ia32_vfmaddpd128_maskz (-(__v2df) __A, + (__v2df) __B, + -(__v2df) __C, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_fmadd_pd(__m256d __A, __mmask8 __U, __m256d __B, __m256d __C) +{ + return (__m256d) __builtin_ia32_vfmaddpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __C, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask3_fmadd_pd(__m256d __A, __m256d __B, __m256d __C, __mmask8 __U) +{ + return (__m256d) __builtin_ia32_vfmaddpd256_mask3 ((__v4df) __A, + (__v4df) __B, + (__v4df) __C, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_fmadd_pd(__mmask8 __U, __m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d) __builtin_ia32_vfmaddpd256_maskz ((__v4df) __A, + (__v4df) __B, + (__v4df) __C, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_fmsub_pd(__m256d __A, __mmask8 __U, __m256d __B, __m256d __C) +{ + return (__m256d) __builtin_ia32_vfmaddpd256_mask ((__v4df) __A, + (__v4df) __B, + -(__v4df) __C, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_fmsub_pd(__mmask8 __U, __m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d) __builtin_ia32_vfmaddpd256_maskz ((__v4df) __A, + (__v4df) __B, + -(__v4df) __C, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask3_fnmadd_pd(__m256d __A, __m256d __B, __m256d __C, __mmask8 __U) +{ + return (__m256d) __builtin_ia32_vfmaddpd256_mask3 (-(__v4df) __A, + (__v4df) __B, + (__v4df) __C, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_fnmadd_pd(__mmask8 __U, __m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d) __builtin_ia32_vfmaddpd256_maskz (-(__v4df) __A, + (__v4df) __B, + (__v4df) __C, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_fnmsub_pd(__mmask8 __U, __m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d) __builtin_ia32_vfmaddpd256_maskz (-(__v4df) __A, + (__v4df) __B, + -(__v4df) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_fmadd_ps(__m128 __A, __mmask8 __U, __m128 __B, __m128 __C) +{ + return (__m128) __builtin_ia32_vfmaddps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask3_fmadd_ps(__m128 __A, __m128 __B, __m128 __C, __mmask8 __U) +{ + return (__m128) __builtin_ia32_vfmaddps128_mask3 ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_fmadd_ps(__mmask8 __U, __m128 __A, __m128 __B, __m128 __C) +{ + return (__m128) __builtin_ia32_vfmaddps128_maskz ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_fmsub_ps(__m128 __A, __mmask8 __U, __m128 __B, __m128 __C) +{ + return (__m128) __builtin_ia32_vfmaddps128_mask ((__v4sf) __A, + (__v4sf) __B, + -(__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_fmsub_ps(__mmask8 __U, __m128 __A, __m128 __B, __m128 __C) +{ + return (__m128) __builtin_ia32_vfmaddps128_maskz ((__v4sf) __A, + (__v4sf) __B, + -(__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask3_fnmadd_ps(__m128 __A, __m128 __B, __m128 __C, __mmask8 __U) +{ + return (__m128) __builtin_ia32_vfmaddps128_mask3 (-(__v4sf) __A, + (__v4sf) __B, + (__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_fnmadd_ps(__mmask8 __U, __m128 __A, __m128 __B, __m128 __C) +{ + return (__m128) __builtin_ia32_vfmaddps128_maskz (-(__v4sf) __A, + (__v4sf) __B, + (__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_fnmsub_ps(__mmask8 __U, __m128 __A, __m128 __B, __m128 __C) +{ + return (__m128) __builtin_ia32_vfmaddps128_maskz (-(__v4sf) __A, + (__v4sf) __B, + -(__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_fmadd_ps(__m256 __A, __mmask8 __U, __m256 __B, __m256 __C) +{ + return (__m256) __builtin_ia32_vfmaddps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask3_fmadd_ps(__m256 __A, __m256 __B, __m256 __C, __mmask8 __U) +{ + return (__m256) __builtin_ia32_vfmaddps256_mask3 ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_fmadd_ps(__mmask8 __U, __m256 __A, __m256 __B, __m256 __C) +{ + return (__m256) __builtin_ia32_vfmaddps256_maskz ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_fmsub_ps(__m256 __A, __mmask8 __U, __m256 __B, __m256 __C) +{ + return (__m256) __builtin_ia32_vfmaddps256_mask ((__v8sf) __A, + (__v8sf) __B, + -(__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_fmsub_ps(__mmask8 __U, __m256 __A, __m256 __B, __m256 __C) +{ + return (__m256) __builtin_ia32_vfmaddps256_maskz ((__v8sf) __A, + (__v8sf) __B, + -(__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask3_fnmadd_ps(__m256 __A, __m256 __B, __m256 __C, __mmask8 __U) +{ + return (__m256) __builtin_ia32_vfmaddps256_mask3 (-(__v8sf) __A, + (__v8sf) __B, + (__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_fnmadd_ps(__mmask8 __U, __m256 __A, __m256 __B, __m256 __C) +{ + return (__m256) __builtin_ia32_vfmaddps256_maskz (-(__v8sf) __A, + (__v8sf) __B, + (__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_fnmsub_ps(__mmask8 __U, __m256 __A, __m256 __B, __m256 __C) +{ + return (__m256) __builtin_ia32_vfmaddps256_maskz (-(__v8sf) __A, + (__v8sf) __B, + -(__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_fmaddsub_pd(__m128d __A, __mmask8 __U, __m128d __B, __m128d __C) +{ + return (__m128d) __builtin_ia32_vfmaddsubpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask3_fmaddsub_pd(__m128d __A, __m128d __B, __m128d __C, __mmask8 __U) +{ + return (__m128d) __builtin_ia32_vfmaddsubpd128_mask3 ((__v2df) __A, + (__v2df) __B, + (__v2df) __C, + (__mmask8) + __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_fmaddsub_pd(__mmask8 __U, __m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d) __builtin_ia32_vfmaddsubpd128_maskz ((__v2df) __A, + (__v2df) __B, + (__v2df) __C, + (__mmask8) + __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_fmsubadd_pd(__m128d __A, __mmask8 __U, __m128d __B, __m128d __C) +{ + return (__m128d) __builtin_ia32_vfmaddsubpd128_mask ((__v2df) __A, + (__v2df) __B, + -(__v2df) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_fmsubadd_pd(__mmask8 __U, __m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d) __builtin_ia32_vfmaddsubpd128_maskz ((__v2df) __A, + (__v2df) __B, + -(__v2df) __C, + (__mmask8) + __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_fmaddsub_pd(__m256d __A, __mmask8 __U, __m256d __B, __m256d __C) +{ + return (__m256d) __builtin_ia32_vfmaddsubpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __C, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask3_fmaddsub_pd(__m256d __A, __m256d __B, __m256d __C, __mmask8 __U) +{ + return (__m256d) __builtin_ia32_vfmaddsubpd256_mask3 ((__v4df) __A, + (__v4df) __B, + (__v4df) __C, + (__mmask8) + __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_fmaddsub_pd(__mmask8 __U, __m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d) __builtin_ia32_vfmaddsubpd256_maskz ((__v4df) __A, + (__v4df) __B, + (__v4df) __C, + (__mmask8) + __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_fmsubadd_pd(__m256d __A, __mmask8 __U, __m256d __B, __m256d __C) +{ + return (__m256d) __builtin_ia32_vfmaddsubpd256_mask ((__v4df) __A, + (__v4df) __B, + -(__v4df) __C, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_fmsubadd_pd(__mmask8 __U, __m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d) __builtin_ia32_vfmaddsubpd256_maskz ((__v4df) __A, + (__v4df) __B, + -(__v4df) __C, + (__mmask8) + __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_fmaddsub_ps(__m128 __A, __mmask8 __U, __m128 __B, __m128 __C) +{ + return (__m128) __builtin_ia32_vfmaddsubps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask3_fmaddsub_ps(__m128 __A, __m128 __B, __m128 __C, __mmask8 __U) +{ + return (__m128) __builtin_ia32_vfmaddsubps128_mask3 ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_fmaddsub_ps(__mmask8 __U, __m128 __A, __m128 __B, __m128 __C) +{ + return (__m128) __builtin_ia32_vfmaddsubps128_maskz ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_fmsubadd_ps(__m128 __A, __mmask8 __U, __m128 __B, __m128 __C) +{ + return (__m128) __builtin_ia32_vfmaddsubps128_mask ((__v4sf) __A, + (__v4sf) __B, + -(__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_fmsubadd_ps(__mmask8 __U, __m128 __A, __m128 __B, __m128 __C) +{ + return (__m128) __builtin_ia32_vfmaddsubps128_maskz ((__v4sf) __A, + (__v4sf) __B, + -(__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_fmaddsub_ps(__m256 __A, __mmask8 __U, __m256 __B, + __m256 __C) +{ + return (__m256) __builtin_ia32_vfmaddsubps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask3_fmaddsub_ps(__m256 __A, __m256 __B, __m256 __C, __mmask8 __U) +{ + return (__m256) __builtin_ia32_vfmaddsubps256_mask3 ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_fmaddsub_ps(__mmask8 __U, __m256 __A, __m256 __B, __m256 __C) +{ + return (__m256) __builtin_ia32_vfmaddsubps256_maskz ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_fmsubadd_ps(__m256 __A, __mmask8 __U, __m256 __B, __m256 __C) +{ + return (__m256) __builtin_ia32_vfmaddsubps256_mask ((__v8sf) __A, + (__v8sf) __B, + -(__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_fmsubadd_ps(__mmask8 __U, __m256 __A, __m256 __B, __m256 __C) +{ + return (__m256) __builtin_ia32_vfmaddsubps256_maskz ((__v8sf) __A, + (__v8sf) __B, + -(__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask3_fmsub_pd(__m128d __A, __m128d __B, __m128d __C, __mmask8 __U) +{ + return (__m128d) __builtin_ia32_vfmsubpd128_mask3 ((__v2df) __A, + (__v2df) __B, + (__v2df) __C, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask3_fmsub_pd(__m256d __A, __m256d __B, __m256d __C, __mmask8 __U) +{ + return (__m256d) __builtin_ia32_vfmsubpd256_mask3 ((__v4df) __A, + (__v4df) __B, + (__v4df) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask3_fmsub_ps(__m128 __A, __m128 __B, __m128 __C, __mmask8 __U) +{ + return (__m128) __builtin_ia32_vfmsubps128_mask3 ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask3_fmsub_ps(__m256 __A, __m256 __B, __m256 __C, __mmask8 __U) +{ + return (__m256) __builtin_ia32_vfmsubps256_mask3 ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask3_fmsubadd_pd(__m128d __A, __m128d __B, __m128d __C, __mmask8 __U) +{ + return (__m128d) __builtin_ia32_vfmsubaddpd128_mask3 ((__v2df) __A, + (__v2df) __B, + (__v2df) __C, + (__mmask8) + __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask3_fmsubadd_pd(__m256d __A, __m256d __B, __m256d __C, __mmask8 __U) +{ + return (__m256d) __builtin_ia32_vfmsubaddpd256_mask3 ((__v4df) __A, + (__v4df) __B, + (__v4df) __C, + (__mmask8) + __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask3_fmsubadd_ps(__m128 __A, __m128 __B, __m128 __C, __mmask8 __U) +{ + return (__m128) __builtin_ia32_vfmsubaddps128_mask3 ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask3_fmsubadd_ps(__m256 __A, __m256 __B, __m256 __C, __mmask8 __U) +{ + return (__m256) __builtin_ia32_vfmsubaddps256_mask3 ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_fnmadd_pd(__m128d __A, __mmask8 __U, __m128d __B, __m128d __C) +{ + return (__m128d) __builtin_ia32_vfnmaddpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __C, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_fnmadd_pd(__m256d __A, __mmask8 __U, __m256d __B, __m256d __C) +{ + return (__m256d) __builtin_ia32_vfnmaddpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_fnmadd_ps(__m128 __A, __mmask8 __U, __m128 __B, __m128 __C) +{ + return (__m128) __builtin_ia32_vfnmaddps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_fnmadd_ps(__m256 __A, __mmask8 __U, __m256 __B, __m256 __C) +{ + return (__m256) __builtin_ia32_vfnmaddps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_fnmsub_pd(__m128d __A, __mmask8 __U, __m128d __B, __m128d __C) +{ + return (__m128d) __builtin_ia32_vfnmsubpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask3_fnmsub_pd(__m128d __A, __m128d __B, __m128d __C, __mmask8 __U) +{ + return (__m128d) __builtin_ia32_vfnmsubpd128_mask3 ((__v2df) __A, + (__v2df) __B, + (__v2df) __C, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_fnmsub_pd(__m256d __A, __mmask8 __U, __m256d __B, __m256d __C) +{ + return (__m256d) __builtin_ia32_vfnmsubpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __C, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask3_fnmsub_pd(__m256d __A, __m256d __B, __m256d __C, __mmask8 __U) +{ + return (__m256d) __builtin_ia32_vfnmsubpd256_mask3 ((__v4df) __A, + (__v4df) __B, + (__v4df) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_fnmsub_ps(__m128 __A, __mmask8 __U, __m128 __B, __m128 __C) +{ + return (__m128) __builtin_ia32_vfnmsubps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask3_fnmsub_ps(__m128 __A, __m128 __B, __m128 __C, __mmask8 __U) +{ + return (__m128) __builtin_ia32_vfnmsubps128_mask3 ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_fnmsub_ps(__m256 __A, __mmask8 __U, __m256 __B, __m256 __C) +{ + return (__m256) __builtin_ia32_vfnmsubps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask3_fnmsub_ps(__m256 __A, __m256 __B, __m256 __C, __mmask8 __U) +{ + return (__m256) __builtin_ia32_vfnmsubps256_mask3 ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __C, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_add_pd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_addpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_add_pd (__mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_addpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_add_pd (__m256d __W, __mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_addpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_add_pd (__mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_addpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_add_ps (__m128 __W, __mmask16 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_addps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_add_ps (__mmask16 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_addps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_add_ps (__m256 __W, __mmask16 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_addps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_add_ps (__mmask16 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_addps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_blend_epi32 (__mmask8 __U, __m128i __A, __m128i __W) { + return (__m128i) __builtin_ia32_blendmd_128_mask ((__v4si) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_blend_epi32 (__mmask8 __U, __m256i __A, __m256i __W) { + return (__m256i) __builtin_ia32_blendmd_256_mask ((__v8si) __A, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_blend_pd (__mmask8 __U, __m128d __A, __m128d __W) { + return (__m128d) __builtin_ia32_blendmpd_128_mask ((__v2df) __A, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_blend_pd (__mmask8 __U, __m256d __A, __m256d __W) { + return (__m256d) __builtin_ia32_blendmpd_256_mask ((__v4df) __A, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_blend_ps (__mmask8 __U, __m128 __A, __m128 __W) { + return (__m128) __builtin_ia32_blendmps_128_mask ((__v4sf) __A, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_blend_ps (__mmask8 __U, __m256 __A, __m256 __W) { + return (__m256) __builtin_ia32_blendmps_256_mask ((__v8sf) __A, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_blend_epi64 (__mmask8 __U, __m128i __A, __m128i __W) { + return (__m128i) __builtin_ia32_blendmq_128_mask ((__v2di) __A, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_blend_epi64 (__mmask8 __U, __m256i __A, __m256i __W) { + return (__m256i) __builtin_ia32_blendmq_256_mask ((__v4di) __A, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_compress_pd (__m128d __W, __mmask8 __U, __m128d __A) { + return (__m128d) __builtin_ia32_compressdf128_mask ((__v2df) __A, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_compress_pd (__mmask8 __U, __m128d __A) { + return (__m128d) __builtin_ia32_compressdf128_mask ((__v2df) __A, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_compress_pd (__m256d __W, __mmask8 __U, __m256d __A) { + return (__m256d) __builtin_ia32_compressdf256_mask ((__v4df) __A, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_compress_pd (__mmask8 __U, __m256d __A) { + return (__m256d) __builtin_ia32_compressdf256_mask ((__v4df) __A, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_compress_epi64 (__m128i __W, __mmask8 __U, __m128i __A) { + return (__m128i) __builtin_ia32_compressdi128_mask ((__v2di) __A, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_compress_epi64 (__mmask8 __U, __m128i __A) { + return (__m128i) __builtin_ia32_compressdi128_mask ((__v2di) __A, + (__v2di) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_compress_epi64 (__m256i __W, __mmask8 __U, __m256i __A) { + return (__m256i) __builtin_ia32_compressdi256_mask ((__v4di) __A, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_compress_epi64 (__mmask8 __U, __m256i __A) { + return (__m256i) __builtin_ia32_compressdi256_mask ((__v4di) __A, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_compress_ps (__m128 __W, __mmask8 __U, __m128 __A) { + return (__m128) __builtin_ia32_compresssf128_mask ((__v4sf) __A, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_compress_ps (__mmask8 __U, __m128 __A) { + return (__m128) __builtin_ia32_compresssf128_mask ((__v4sf) __A, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_compress_ps (__m256 __W, __mmask8 __U, __m256 __A) { + return (__m256) __builtin_ia32_compresssf256_mask ((__v8sf) __A, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_compress_ps (__mmask8 __U, __m256 __A) { + return (__m256) __builtin_ia32_compresssf256_mask ((__v8sf) __A, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_compress_epi32 (__m128i __W, __mmask8 __U, __m128i __A) { + return (__m128i) __builtin_ia32_compresssi128_mask ((__v4si) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_compress_epi32 (__mmask8 __U, __m128i __A) { + return (__m128i) __builtin_ia32_compresssi128_mask ((__v4si) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_compress_epi32 (__m256i __W, __mmask8 __U, __m256i __A) { + return (__m256i) __builtin_ia32_compresssi256_mask ((__v8si) __A, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_compress_epi32 (__mmask8 __U, __m256i __A) { + return (__m256i) __builtin_ia32_compresssi256_mask ((__v8si) __A, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_mask_compressstoreu_pd (void *__P, __mmask8 __U, __m128d __A) { + __builtin_ia32_compressstoredf128_mask ((__v2df *) __P, + (__v2df) __A, + (__mmask8) __U); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm256_mask_compressstoreu_pd (void *__P, __mmask8 __U, __m256d __A) { + __builtin_ia32_compressstoredf256_mask ((__v4df *) __P, + (__v4df) __A, + (__mmask8) __U); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_mask_compressstoreu_epi64 (void *__P, __mmask8 __U, __m128i __A) { + __builtin_ia32_compressstoredi128_mask ((__v2di *) __P, + (__v2di) __A, + (__mmask8) __U); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm256_mask_compressstoreu_epi64 (void *__P, __mmask8 __U, __m256i __A) { + __builtin_ia32_compressstoredi256_mask ((__v4di *) __P, + (__v4di) __A, + (__mmask8) __U); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_mask_compressstoreu_ps (void *__P, __mmask8 __U, __m128 __A) { + __builtin_ia32_compressstoresf128_mask ((__v4sf *) __P, + (__v4sf) __A, + (__mmask8) __U); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm256_mask_compressstoreu_ps (void *__P, __mmask8 __U, __m256 __A) { + __builtin_ia32_compressstoresf256_mask ((__v8sf *) __P, + (__v8sf) __A, + (__mmask8) __U); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_mask_compressstoreu_epi32 (void *__P, __mmask8 __U, __m128i __A) { + __builtin_ia32_compressstoresi128_mask ((__v4si *) __P, + (__v4si) __A, + (__mmask8) __U); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm256_mask_compressstoreu_epi32 (void *__P, __mmask8 __U, __m256i __A) { + __builtin_ia32_compressstoresi256_mask ((__v8si *) __P, + (__v8si) __A, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_cvtepi32_pd (__m128d __W, __mmask8 __U, __m128i __A) { + return (__m128d) __builtin_ia32_cvtdq2pd128_mask ((__v4si) __A, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_cvtepi32_pd (__mmask8 __U, __m128i __A) { + return (__m128d) __builtin_ia32_cvtdq2pd128_mask ((__v4si) __A, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_cvtepi32_pd (__m256d __W, __mmask8 __U, __m128i __A) { + return (__m256d) __builtin_ia32_cvtdq2pd256_mask ((__v4si) __A, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_cvtepi32_pd (__mmask8 __U, __m128i __A) { + return (__m256d) __builtin_ia32_cvtdq2pd256_mask ((__v4si) __A, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_cvtepi32_ps (__m128 __W, __mmask8 __U, __m128i __A) { + return (__m128) __builtin_ia32_cvtdq2ps128_mask ((__v4si) __A, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_cvtepi32_ps (__mmask16 __U, __m128i __A) { + return (__m128) __builtin_ia32_cvtdq2ps128_mask ((__v4si) __A, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_cvtepi32_ps (__m256 __W, __mmask8 __U, __m256i __A) { + return (__m256) __builtin_ia32_cvtdq2ps256_mask ((__v8si) __A, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_cvtepi32_ps (__mmask16 __U, __m256i __A) { + return (__m256) __builtin_ia32_cvtdq2ps256_mask ((__v8si) __A, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvtpd_epi32 (__m128i __W, __mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvtpd2dq128_mask ((__v2df) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvtpd_epi32 (__mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvtpd2dq128_mask ((__v2df) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_mask_cvtpd_epi32 (__m128i __W, __mmask8 __U, __m256d __A) { + return (__m128i) __builtin_ia32_cvtpd2dq256_mask ((__v4df) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_maskz_cvtpd_epi32 (__mmask8 __U, __m256d __A) { + return (__m128i) __builtin_ia32_cvtpd2dq256_mask ((__v4df) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_cvtpd_ps (__m128 __W, __mmask8 __U, __m128d __A) { + return (__m128) __builtin_ia32_cvtpd2ps_mask ((__v2df) __A, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_cvtpd_ps (__mmask8 __U, __m128d __A) { + return (__m128) __builtin_ia32_cvtpd2ps_mask ((__v2df) __A, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm256_mask_cvtpd_ps (__m128 __W, __mmask8 __U, __m256d __A) { + return (__m128) __builtin_ia32_cvtpd2ps256_mask ((__v4df) __A, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm256_maskz_cvtpd_ps (__mmask8 __U, __m256d __A) { + return (__m128) __builtin_ia32_cvtpd2ps256_mask ((__v4df) __A, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtpd_epu32 (__m128d __A) { + return (__m128i) __builtin_ia32_cvtpd2udq128_mask ((__v2df) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvtpd_epu32 (__m128i __W, __mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvtpd2udq128_mask ((__v2df) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvtpd_epu32 (__mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvtpd2udq128_mask ((__v2df) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_cvtpd_epu32 (__m256d __A) { + return (__m128i) __builtin_ia32_cvtpd2udq256_mask ((__v4df) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_mask_cvtpd_epu32 (__m128i __W, __mmask8 __U, __m256d __A) { + return (__m128i) __builtin_ia32_cvtpd2udq256_mask ((__v4df) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_maskz_cvtpd_epu32 (__mmask8 __U, __m256d __A) { + return (__m128i) __builtin_ia32_cvtpd2udq256_mask ((__v4df) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvtps_epi32 (__m128i __W, __mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvtps2dq128_mask ((__v4sf) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvtps_epi32 (__mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvtps2dq128_mask ((__v4sf) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_cvtps_epi32 (__m256i __W, __mmask8 __U, __m256 __A) { + return (__m256i) __builtin_ia32_cvtps2dq256_mask ((__v8sf) __A, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_cvtps_epi32 (__mmask8 __U, __m256 __A) { + return (__m256i) __builtin_ia32_cvtps2dq256_mask ((__v8sf) __A, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_cvtps_pd (__m128d __W, __mmask8 __U, __m128 __A) { + return (__m128d) __builtin_ia32_cvtps2pd128_mask ((__v4sf) __A, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_cvtps_pd (__mmask8 __U, __m128 __A) { + return (__m128d) __builtin_ia32_cvtps2pd128_mask ((__v4sf) __A, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_cvtps_pd (__m256d __W, __mmask8 __U, __m128 __A) { + return (__m256d) __builtin_ia32_cvtps2pd256_mask ((__v4sf) __A, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_cvtps_pd (__mmask8 __U, __m128 __A) { + return (__m256d) __builtin_ia32_cvtps2pd256_mask ((__v4sf) __A, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtps_epu32 (__m128 __A) { + return (__m128i) __builtin_ia32_cvtps2udq128_mask ((__v4sf) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvtps_epu32 (__m128i __W, __mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvtps2udq128_mask ((__v4sf) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvtps_epu32 (__mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvtps2udq128_mask ((__v4sf) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvtps_epu32 (__m256 __A) { + return (__m256i) __builtin_ia32_cvtps2udq256_mask ((__v8sf) __A, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_cvtps_epu32 (__m256i __W, __mmask8 __U, __m256 __A) { + return (__m256i) __builtin_ia32_cvtps2udq256_mask ((__v8sf) __A, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_cvtps_epu32 (__mmask8 __U, __m256 __A) { + return (__m256i) __builtin_ia32_cvtps2udq256_mask ((__v8sf) __A, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvttpd_epi32 (__m128i __W, __mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvttpd2dq128_mask ((__v2df) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvttpd_epi32 (__mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvttpd2dq128_mask ((__v2df) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_mask_cvttpd_epi32 (__m128i __W, __mmask8 __U, __m256d __A) { + return (__m128i) __builtin_ia32_cvttpd2dq256_mask ((__v4df) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_maskz_cvttpd_epi32 (__mmask8 __U, __m256d __A) { + return (__m128i) __builtin_ia32_cvttpd2dq256_mask ((__v4df) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvttpd_epu32 (__m128d __A) { + return (__m128i) __builtin_ia32_cvttpd2udq128_mask ((__v2df) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvttpd_epu32 (__m128i __W, __mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvttpd2udq128_mask ((__v2df) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvttpd_epu32 (__mmask8 __U, __m128d __A) { + return (__m128i) __builtin_ia32_cvttpd2udq128_mask ((__v2df) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_cvttpd_epu32 (__m256d __A) { + return (__m128i) __builtin_ia32_cvttpd2udq256_mask ((__v4df) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_mask_cvttpd_epu32 (__m128i __W, __mmask8 __U, __m256d __A) { + return (__m128i) __builtin_ia32_cvttpd2udq256_mask ((__v4df) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm256_maskz_cvttpd_epu32 (__mmask8 __U, __m256d __A) { + return (__m128i) __builtin_ia32_cvttpd2udq256_mask ((__v4df) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvttps_epi32 (__m128i __W, __mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvttps2dq128_mask ((__v4sf) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvttps_epi32 (__mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvttps2dq128_mask ((__v4sf) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_cvttps_epi32 (__m256i __W, __mmask8 __U, __m256 __A) { + return (__m256i) __builtin_ia32_cvttps2dq256_mask ((__v8sf) __A, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_cvttps_epi32 (__mmask8 __U, __m256 __A) { + return (__m256i) __builtin_ia32_cvttps2dq256_mask ((__v8sf) __A, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvttps_epu32 (__m128 __A) { + return (__m128i) __builtin_ia32_cvttps2udq128_mask ((__v4sf) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_cvttps_epu32 (__m128i __W, __mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvttps2udq128_mask ((__v4sf) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_cvttps_epu32 (__mmask8 __U, __m128 __A) { + return (__m128i) __builtin_ia32_cvttps2udq128_mask ((__v4sf) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cvttps_epu32 (__m256 __A) { + return (__m256i) __builtin_ia32_cvttps2udq256_mask ((__v8sf) __A, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_cvttps_epu32 (__m256i __W, __mmask8 __U, __m256 __A) { + return (__m256i) __builtin_ia32_cvttps2udq256_mask ((__v8sf) __A, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_cvttps_epu32 (__mmask8 __U, __m256 __A) { + return (__m256i) __builtin_ia32_cvttps2udq256_mask ((__v8sf) __A, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cvtepu32_pd (__m128i __A) { + return (__m128d) __builtin_ia32_cvtudq2pd128_mask ((__v4si) __A, + (__v2df) + _mm_setzero_pd (), + (__mmask8) -1); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_cvtepu32_pd (__m128d __W, __mmask8 __U, __m128i __A) { + return (__m128d) __builtin_ia32_cvtudq2pd128_mask ((__v4si) __A, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_cvtepu32_pd (__mmask8 __U, __m128i __A) { + return (__m128d) __builtin_ia32_cvtudq2pd128_mask ((__v4si) __A, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_cvtepu32_pd (__m128i __A) { + return (__m256d) __builtin_ia32_cvtudq2pd256_mask ((__v4si) __A, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) -1); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_cvtepu32_pd (__m256d __W, __mmask8 __U, __m128i __A) { + return (__m256d) __builtin_ia32_cvtudq2pd256_mask ((__v4si) __A, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_cvtepu32_pd (__mmask8 __U, __m128i __A) { + return (__m256d) __builtin_ia32_cvtudq2pd256_mask ((__v4si) __A, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvtepu32_ps (__m128i __A) { + return (__m128) __builtin_ia32_cvtudq2ps128_mask ((__v4si) __A, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) -1); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_cvtepu32_ps (__m128 __W, __mmask8 __U, __m128i __A) { + return (__m128) __builtin_ia32_cvtudq2ps128_mask ((__v4si) __A, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_cvtepu32_ps (__mmask8 __U, __m128i __A) { + return (__m128) __builtin_ia32_cvtudq2ps128_mask ((__v4si) __A, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_cvtepu32_ps (__m256i __A) { + return (__m256) __builtin_ia32_cvtudq2ps256_mask ((__v8si) __A, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) -1); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_cvtepu32_ps (__m256 __W, __mmask8 __U, __m256i __A) { + return (__m256) __builtin_ia32_cvtudq2ps256_mask ((__v8si) __A, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_cvtepu32_ps (__mmask8 __U, __m256i __A) { + return (__m256) __builtin_ia32_cvtudq2ps256_mask ((__v8si) __A, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_div_pd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_divpd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_div_pd (__mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_divpd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_div_pd (__m256d __W, __mmask8 __U, __m256d __A, + __m256d __B) { + return (__m256d) __builtin_ia32_divpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_div_pd (__mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_divpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_div_ps (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_divps_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_div_ps (__mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_divps_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_div_ps (__m256 __W, __mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_divps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_div_ps (__mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_divps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_expand_pd (__m128d __W, __mmask8 __U, __m128d __A) { + return (__m128d) __builtin_ia32_expanddf128_mask ((__v2df) __A, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_expand_pd (__mmask8 __U, __m128d __A) { + return (__m128d) __builtin_ia32_expanddf128_mask ((__v2df) __A, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_expand_pd (__m256d __W, __mmask8 __U, __m256d __A) { + return (__m256d) __builtin_ia32_expanddf256_mask ((__v4df) __A, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_expand_pd (__mmask8 __U, __m256d __A) { + return (__m256d) __builtin_ia32_expanddf256_mask ((__v4df) __A, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_expand_epi64 (__m128i __W, __mmask8 __U, __m128i __A) { + return (__m128i) __builtin_ia32_expanddi128_mask ((__v2di) __A, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_expand_epi64 (__mmask8 __U, __m128i __A) { + return (__m128i) __builtin_ia32_expanddi128_mask ((__v2di) __A, + (__v2di) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_expand_epi64 (__m256i __W, __mmask8 __U, __m256i __A) { + return (__m256i) __builtin_ia32_expanddi256_mask ((__v4di) __A, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_expand_epi64 (__mmask8 __U, __m256i __A) { + return (__m256i) __builtin_ia32_expanddi256_mask ((__v4di) __A, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_expandloadu_pd (__m128d __W, __mmask8 __U, void const *__P) { + return (__m128d) __builtin_ia32_expandloaddf128_mask ((__v2df *) __P, + (__v2df) __W, + (__mmask8) + __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_expandloadu_pd (__mmask8 __U, void const *__P) { + return (__m128d) __builtin_ia32_expandloaddf128_mask ((__v2df *) __P, + (__v2df) + _mm_setzero_pd (), + (__mmask8) + __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_expandloadu_pd (__m256d __W, __mmask8 __U, void const *__P) { + return (__m256d) __builtin_ia32_expandloaddf256_mask ((__v4df *) __P, + (__v4df) __W, + (__mmask8) + __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_expandloadu_pd (__mmask8 __U, void const *__P) { + return (__m256d) __builtin_ia32_expandloaddf256_mask ((__v4df *) __P, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) + __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_expandloadu_epi64 (__m128i __W, __mmask8 __U, void const *__P) { + return (__m128i) __builtin_ia32_expandloaddi128_mask ((__v2di *) __P, + (__v2di) __W, + (__mmask8) + __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_expandloadu_epi64 (__mmask8 __U, void const *__P) { + return (__m128i) __builtin_ia32_expandloaddi128_mask ((__v2di *) __P, + (__v2di) + _mm_setzero_si128 (), + (__mmask8) + __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_expandloadu_epi64 (__m256i __W, __mmask8 __U, + void const *__P) { + return (__m256i) __builtin_ia32_expandloaddi256_mask ((__v4di *) __P, + (__v4di) __W, + (__mmask8) + __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_expandloadu_epi64 (__mmask8 __U, void const *__P) { + return (__m256i) __builtin_ia32_expandloaddi256_mask ((__v4di *) __P, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) + __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_expandloadu_ps (__m128 __W, __mmask8 __U, void const *__P) { + return (__m128) __builtin_ia32_expandloadsf128_mask ((__v4sf *) __P, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_expandloadu_ps (__mmask8 __U, void const *__P) { + return (__m128) __builtin_ia32_expandloadsf128_mask ((__v4sf *) __P, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) + __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_expandloadu_ps (__m256 __W, __mmask8 __U, void const *__P) { + return (__m256) __builtin_ia32_expandloadsf256_mask ((__v8sf *) __P, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_expandloadu_ps (__mmask8 __U, void const *__P) { + return (__m256) __builtin_ia32_expandloadsf256_mask ((__v8sf *) __P, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) + __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_expandloadu_epi32 (__m128i __W, __mmask8 __U, void const *__P) { + return (__m128i) __builtin_ia32_expandloadsi128_mask ((__v4si *) __P, + (__v4si) __W, + (__mmask8) + __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_expandloadu_epi32 (__mmask8 __U, void const *__P) { + return (__m128i) __builtin_ia32_expandloadsi128_mask ((__v4si *) __P, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_expandloadu_epi32 (__m256i __W, __mmask8 __U, + void const *__P) { + return (__m256i) __builtin_ia32_expandloadsi256_mask ((__v8si *) __P, + (__v8si) __W, + (__mmask8) + __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_expandloadu_epi32 (__mmask8 __U, void const *__P) { + return (__m256i) __builtin_ia32_expandloadsi256_mask ((__v8si *) __P, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) + __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_expand_ps (__m128 __W, __mmask8 __U, __m128 __A) { + return (__m128) __builtin_ia32_expandsf128_mask ((__v4sf) __A, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_expand_ps (__mmask8 __U, __m128 __A) { + return (__m128) __builtin_ia32_expandsf128_mask ((__v4sf) __A, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_expand_ps (__m256 __W, __mmask8 __U, __m256 __A) { + return (__m256) __builtin_ia32_expandsf256_mask ((__v8sf) __A, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_expand_ps (__mmask8 __U, __m256 __A) { + return (__m256) __builtin_ia32_expandsf256_mask ((__v8sf) __A, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_expand_epi32 (__m128i __W, __mmask8 __U, __m128i __A) { + return (__m128i) __builtin_ia32_expandsi128_mask ((__v4si) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_expand_epi32 (__mmask8 __U, __m128i __A) { + return (__m128i) __builtin_ia32_expandsi128_mask ((__v4si) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_expand_epi32 (__m256i __W, __mmask8 __U, __m256i __A) { + return (__m256i) __builtin_ia32_expandsi256_mask ((__v8si) __A, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_expand_epi32 (__mmask8 __U, __m256i __A) { + return (__m256i) __builtin_ia32_expandsi256_mask ((__v8si) __A, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_getexp_pd (__m128d __A) { + return (__m128d) __builtin_ia32_getexppd128_mask ((__v2df) __A, + (__v2df) + _mm_setzero_pd (), + (__mmask8) -1); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_getexp_pd (__m128d __W, __mmask8 __U, __m128d __A) { + return (__m128d) __builtin_ia32_getexppd128_mask ((__v2df) __A, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_getexp_pd (__mmask8 __U, __m128d __A) { + return (__m128d) __builtin_ia32_getexppd128_mask ((__v2df) __A, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_getexp_pd (__m256d __A) { + return (__m256d) __builtin_ia32_getexppd256_mask ((__v4df) __A, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) -1); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_getexp_pd (__m256d __W, __mmask8 __U, __m256d __A) { + return (__m256d) __builtin_ia32_getexppd256_mask ((__v4df) __A, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_getexp_pd (__mmask8 __U, __m256d __A) { + return (__m256d) __builtin_ia32_getexppd256_mask ((__v4df) __A, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_getexp_ps (__m128 __A) { + return (__m128) __builtin_ia32_getexpps128_mask ((__v4sf) __A, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) -1); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_getexp_ps (__m128 __W, __mmask8 __U, __m128 __A) { + return (__m128) __builtin_ia32_getexpps128_mask ((__v4sf) __A, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_getexp_ps (__mmask8 __U, __m128 __A) { + return (__m128) __builtin_ia32_getexpps128_mask ((__v4sf) __A, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_getexp_ps (__m256 __A) { + return (__m256) __builtin_ia32_getexpps256_mask ((__v8sf) __A, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) -1); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_getexp_ps (__m256 __W, __mmask8 __U, __m256 __A) { + return (__m256) __builtin_ia32_getexpps256_mask ((__v8sf) __A, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_getexp_ps (__mmask8 __U, __m256 __A) { + return (__m256) __builtin_ia32_getexpps256_mask ((__v8sf) __A, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_max_pd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_maxpd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_max_pd (__mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_maxpd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_max_pd (__m256d __W, __mmask8 __U, __m256d __A, + __m256d __B) { + return (__m256d) __builtin_ia32_maxpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_max_pd (__mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_maxpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_max_ps (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_maxps_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_max_ps (__mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_maxps_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_max_ps (__m256 __W, __mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_maxps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_max_ps (__mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_maxps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_min_pd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_minpd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_min_pd (__mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_minpd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_min_pd (__m256d __W, __mmask8 __U, __m256d __A, + __m256d __B) { + return (__m256d) __builtin_ia32_minpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_min_pd (__mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_minpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_min_ps (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_minps_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_min_ps (__mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_minps_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_min_ps (__m256 __W, __mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_minps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_min_ps (__mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_minps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_mul_pd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_mulpd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_mul_pd (__mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_mulpd_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_mul_pd (__m256d __W, __mmask8 __U, __m256d __A, + __m256d __B) { + return (__m256d) __builtin_ia32_mulpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_mul_pd (__mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_mulpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_mul_ps (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_mulps_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_mul_ps (__mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_mulps_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_mul_ps (__m256 __W, __mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_mulps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_mul_ps (__mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_mulps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_abs_epi32 (__m128i __W, __mmask8 __U, __m128i __A) { + return (__m128i) __builtin_ia32_pabsd128_mask ((__v4si) __A, + (__v4si) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_abs_epi32 (__mmask8 __U, __m128i __A) { + return (__m128i) __builtin_ia32_pabsd128_mask ((__v4si) __A, + (__v4si) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_abs_epi32 (__m256i __W, __mmask8 __U, __m256i __A) { + return (__m256i) __builtin_ia32_pabsd256_mask ((__v8si) __A, + (__v8si) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_abs_epi32 (__mmask8 __U, __m256i __A) { + return (__m256i) __builtin_ia32_pabsd256_mask ((__v8si) __A, + (__v8si) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_abs_epi64 (__m128i __A) { + return (__m128i) __builtin_ia32_pabsq128_mask ((__v2di) __A, + (__v2di) + _mm_setzero_si128 (), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_abs_epi64 (__m128i __W, __mmask8 __U, __m128i __A) { + return (__m128i) __builtin_ia32_pabsq128_mask ((__v2di) __A, + (__v2di) __W, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_abs_epi64 (__mmask8 __U, __m128i __A) { + return (__m128i) __builtin_ia32_pabsq128_mask ((__v2di) __A, + (__v2di) + _mm_setzero_si128 (), + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_abs_epi64 (__m256i __A) { + return (__m256i) __builtin_ia32_pabsq256_mask ((__v4di) __A, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_abs_epi64 (__m256i __W, __mmask8 __U, __m256i __A) { + return (__m256i) __builtin_ia32_pabsq256_mask ((__v4di) __A, + (__v4di) __W, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_abs_epi64 (__mmask8 __U, __m256i __A) { + return (__m256i) __builtin_ia32_pabsq256_mask ((__v4di) __A, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_max_epi32 (__mmask8 __M, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pmaxsd128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) + _mm_setzero_si128 (), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_max_epi32 (__m128i __W, __mmask8 __M, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_pmaxsd128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) __W, __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_max_epi32 (__mmask8 __M, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pmaxsd256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) + _mm256_setzero_si256 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_max_epi32 (__m256i __W, __mmask8 __M, __m256i __A, + __m256i __B) { + return (__m256i) __builtin_ia32_pmaxsd256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) __W, __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_max_epi64 (__mmask8 __M, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pmaxsq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_si128 (), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_max_epi64 (__m128i __W, __mmask8 __M, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_pmaxsq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) __W, __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_max_epi64 (__m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pmaxsq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_si128 (), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_max_epi64 (__mmask8 __M, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pmaxsq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_si256 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_max_epi64 (__m256i __W, __mmask8 __M, __m256i __A, + __m256i __B) { + return (__m256i) __builtin_ia32_pmaxsq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) __W, __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_max_epi64 (__m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pmaxsq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_max_epu32 (__mmask8 __M, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pmaxud128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) + _mm_setzero_si128 (), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_max_epu32 (__m128i __W, __mmask8 __M, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_pmaxud128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) __W, __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_max_epu32 (__mmask8 __M, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pmaxud256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) + _mm256_setzero_si256 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_max_epu32 (__m256i __W, __mmask8 __M, __m256i __A, + __m256i __B) { + return (__m256i) __builtin_ia32_pmaxud256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) __W, __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_max_epu64 (__mmask8 __M, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pmaxuq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_si128 (), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_max_epu64 (__m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pmaxuq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_si128 (), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_max_epu64 (__m128i __W, __mmask8 __M, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_pmaxuq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) __W, __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_max_epu64 (__mmask8 __M, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pmaxuq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_si256 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_max_epu64 (__m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pmaxuq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_max_epu64 (__m256i __W, __mmask8 __M, __m256i __A, + __m256i __B) { + return (__m256i) __builtin_ia32_pmaxuq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) __W, __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_min_epi32 (__mmask8 __M, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pminsd128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) + _mm_setzero_si128 (), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_min_epi32 (__m128i __W, __mmask8 __M, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_pminsd128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) __W, __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_min_epi32 (__mmask8 __M, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pminsd256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) + _mm256_setzero_si256 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_min_epi32 (__m256i __W, __mmask8 __M, __m256i __A, + __m256i __B) { + return (__m256i) __builtin_ia32_pminsd256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) __W, __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_min_epi64 (__m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pminsq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_si128 (), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_min_epi64 (__m128i __W, __mmask8 __M, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_pminsq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) __W, __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_min_epi64 (__mmask8 __M, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pminsq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_si128 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_min_epi64 (__m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pminsq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_min_epi64 (__m256i __W, __mmask8 __M, __m256i __A, + __m256i __B) { + return (__m256i) __builtin_ia32_pminsq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) __W, __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_min_epi64 (__mmask8 __M, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pminsq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_si256 (), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_min_epu32 (__mmask8 __M, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pminud128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) + _mm_setzero_si128 (), + __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_min_epu32 (__m128i __W, __mmask8 __M, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_pminud128_mask ((__v4si) __A, + (__v4si) __B, + (__v4si) __W, __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_min_epu32 (__mmask8 __M, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pminud256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) + _mm256_setzero_si256 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_min_epu32 (__m256i __W, __mmask8 __M, __m256i __A, + __m256i __B) { + return (__m256i) __builtin_ia32_pminud256_mask ((__v8si) __A, + (__v8si) __B, + (__v8si) __W, __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_min_epu64 (__m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pminuq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_si128 (), + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_min_epu64 (__m128i __W, __mmask8 __M, __m128i __A, + __m128i __B) { + return (__m128i) __builtin_ia32_pminuq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) __W, __M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_min_epu64 (__mmask8 __M, __m128i __A, __m128i __B) { + return (__m128i) __builtin_ia32_pminuq128_mask ((__v2di) __A, + (__v2di) __B, + (__v2di) + _mm_setzero_si128 (), + __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_min_epu64 (__m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pminuq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_si256 (), + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_min_epu64 (__m256i __W, __mmask8 __M, __m256i __A, + __m256i __B) { + return (__m256i) __builtin_ia32_pminuq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) __W, __M); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_min_epu64 (__mmask8 __M, __m256i __A, __m256i __B) { + return (__m256i) __builtin_ia32_pminuq256_mask ((__v4di) __A, + (__v4di) __B, + (__v4di) + _mm256_setzero_si256 (), + __M); +} + +#define _mm_roundscale_pd(__A, __imm) __extension__ ({ \ + (__m128d) __builtin_ia32_rndscalepd_128_mask ((__v2df) __A, \ + __imm, (__v2df) _mm_setzero_pd (), (__mmask8) -1); }) + + +#define _mm_mask_roundscale_pd(__W, __U, __A, __imm) __extension__ ({ \ + (__m128d) __builtin_ia32_rndscalepd_128_mask ((__v2df) __A, __imm, \ + (__v2df) __W, (__mmask8) __U); }) + + +#define _mm_maskz_roundscale_pd(__U, __A, __imm) __extension__ ({ \ + (__m128d) __builtin_ia32_rndscalepd_128_mask ((__v2df) __A, __imm, \ + (__v2df) _mm_setzero_pd (), (__mmask8) __U); }) + + +#define _mm256_roundscale_pd(__A, __imm) __extension__ ({ \ + (__m256d) __builtin_ia32_rndscalepd_256_mask ((__v4df) __A, __imm, \ + (__v4df) _mm256_setzero_pd (), (__mmask8) -1); }) + + +#define _mm256_mask_roundscale_pd(__W, __U, __A, __imm) __extension__ ({ \ + (__m256d) __builtin_ia32_rndscalepd_256_mask ((__v4df) __A, __imm, \ + (__v4df) __W, (__mmask8) __U); }) + + +#define _mm256_maskz_roundscale_pd(__U, __A, __imm) __extension__ ({ \ + (__m256d) __builtin_ia32_rndscalepd_256_mask ((__v4df) __A, __imm, \ + (__v4df) _mm256_setzero_pd(), (__mmask8) __U); }) + +#define _mm_roundscale_ps(__A, __imm) __extension__ ({ \ + (__m128) __builtin_ia32_rndscaleps_128_mask ((__v4sf) __A, __imm, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) -1); }) + + +#define _mm_mask_roundscale_ps(__W, __U, __A, __imm) __extension__ ({ \ + (__m128) __builtin_ia32_rndscaleps_128_mask ((__v4sf) __A, __imm, \ + (__v4sf) __W, (__mmask8) __U); }) + + +#define _mm_maskz_roundscale_ps(__U, __A, __imm) __extension__ ({ \ + (__m128) __builtin_ia32_rndscaleps_128_mask ((__v4sf) __A, __imm, \ + (__v4sf) _mm_setzero_ps(), (__mmask8) __U); }) + +#define _mm256_roundscale_ps(__A, __imm) __extension__ ({ \ + (__m256) __builtin_ia32_rndscaleps_256_mask ((__v8sf) __A,__imm, \ + (__v8sf) _mm256_setzero_ps(), (__mmask8) -1); }) + +#define _mm256_mask_roundscale_ps(__W, __U, __A,__imm) __extension__ ({ \ + (__m256) __builtin_ia32_rndscaleps_256_mask ((__v8sf) __A, __imm, \ + (__v8sf) __W, (__mmask8) __U); }) + + +#define _mm256_maskz_roundscale_ps(__U, __A, __imm) __extension__ ({ \ + (__m256) __builtin_ia32_rndscaleps_256_mask ((__v8sf) __A, __imm, \ + (__v8sf) _mm256_setzero_ps(), (__mmask8) __U); }) + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_scalef_pd (__m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_scalefpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_setzero_pd (), + (__mmask8) -1); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_scalef_pd (__m128d __W, __mmask8 __U, __m128d __A, + __m128d __B) { + return (__m128d) __builtin_ia32_scalefpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_scalef_pd (__mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_scalefpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_scalef_pd (__m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_scalefpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) -1); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_scalef_pd (__m256d __W, __mmask8 __U, __m256d __A, + __m256d __B) { + return (__m256d) __builtin_ia32_scalefpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_scalef_pd (__mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_scalefpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_scalef_ps (__m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_scalefps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) -1); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_scalef_ps (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_scalefps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_scalef_ps (__mmask8 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_scalefps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_scalef_ps (__m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_scalefps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) -1); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_scalef_ps (__m256 __W, __mmask8 __U, __m256 __A, + __m256 __B) { + return (__m256) __builtin_ia32_scalefps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_scalefps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +#define _mm_i64scatter_pd(__addr,__index, __v1, __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv2df(__addr, (__mmask8) 0xFF, (__v2di) __index, \ + (__v2df) __v1, __scale); }) + +#define _mm_mask_i64scatter_pd(__addr, __mask, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv2df (__addr, __mask, (__v2di) __index, \ + (__v2df) __v1, __scale); }) + + +#define _mm_i64scatter_epi64(__addr, __index, __v1, __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv2di (__addr, (__mmask8) 0xFF, \ + (__v2di) __index, (__v2di) __v1, __scale); }) + +#define _mm_mask_i64scatter_epi64(__addr, __mask, __index, __v1,\ + __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv2di (__addr, __mask, (__v2di) __index,\ + (__v2di) __v1, __scale); }) + +#define _mm256_i64scatter_pd(__addr, __index, __v1, __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv4df (__addr, (__mmask8) 0xFF,\ + (__v4di) __index, (__v4df) __v1, __scale); }) + +#define _mm256_mask_i64scatter_pd(__addr, __mask, __index, __v1,\ + __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv4df (__addr, __mask, (__v4di) __index,\ + (__v4df) __v1, __scale); }) + +#define _mm256_i64scatter_epi64(__addr, __index, __v1, __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv4di (__addr, (__mmask8) 0xFF, (__v4di) __index,\ + (__v4di) __v1, __scale); }) + +#define _mm256_mask_i64scatter_epi64(__addr, __mask, __index, __v1,\ + __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv4di (__addr, __mask, (__v4di) __index,\ + (__v4di) __v1, __scale); }) + +#define _mm_i64scatter_ps(__addr, __index, __v1, __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv4sf (__addr, (__mmask8) 0xFF,\ + (__v2di) __index, (__v4sf) __v1, __scale); }) + +#define _mm_mask_i64scatter_ps(__addr, __mask, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv4sf (__addr, __mask, (__v2di) __index,\ + (__v4sf) __v1, __scale); }) + +#define _mm_i64scatter_epi32(__addr, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv4si (__addr, (__mmask8) 0xFF,\ + (__v2di) __index, (__v4si) __v1, __scale); }) + +#define _mm_mask_i64scatter_epi32(__addr, __mask, __index, __v1,\ + __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv4si (__addr, __mask, (__v2di) __index,\ + (__v4si) __v1, __scale); }) + +#define _mm256_i64scatter_ps(__addr, __index, __v1, __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv8sf (__addr, (__mmask8) 0xFF, (__v4di) __index, \ + (__v4sf) __v1, __scale); }) + +#define _mm256_mask_i64scatter_ps(__addr, __mask, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv8sf (__addr, __mask, (__v4di) __index, \ + (__v4sf) __v1, __scale); }) + +#define _mm256_i64scatter_epi32(__addr, __index, __v1, __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv8si (__addr, (__mmask8) 0xFF, \ + (__v4di) __index, (__v4si) __v1, __scale); }) + +#define _mm256_mask_i64scatter_epi32(__addr, __mask, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scatterdiv8si(__addr, __mask, (__v4di) __index, \ + (__v4si) __v1, __scale); }) + +#define _mm_i32scatter_pd(__addr, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scattersiv2df (__addr, (__mmask8) 0xFF, \ + (__v4si) __index, (__v2df) __v1, __scale); }) + +#define _mm_mask_i32scatter_pd(__addr, __mask, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scattersiv2df (__addr, __mask, (__v4si) __index,\ + (__v2df) __v1, __scale); }) + +#define _mm_i32scatter_epi64(__addr, __index, __v1, __scale) __extension__ ({ \ + __builtin_ia32_scattersiv2di (__addr, (__mmask8) 0xFF, \ + (__v4si) __index, (__v2di) __v1, __scale); }) + +#define _mm_mask_i32scatter_epi64(__addr, __mask, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scattersiv2di (__addr, __mask, (__v4si) __index, \ + (__v2di) __v1, __scale); }) + +#define _mm256_i32scatter_pd(__addr, __index, __v1, __scale) __extension__ ({ \ + __builtin_ia32_scattersiv4df (__addr, (__mmask8) 0xFF, \ + (__v4si) __index, (__v4df) __v1, __scale); }) + +#define _mm256_mask_i32scatter_pd(__addr, __mask, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scattersiv4df (__addr, __mask, (__v4si) __index, \ + (__v4df) __v1, __scale); }) + +#define _mm256_i32scatter_epi64(__addr, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scattersiv4di (__addr, (__mmask8) 0xFF, \ + (__v4si) __index, (__v4di) __v1, __scale); }) + +#define _mm256_mask_i32scatter_epi64(__addr, __mask, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scattersiv4di (__addr, __mask, (__v4si) __index, \ + (__v4di) __v1, __scale); }) + +#define _mm_i32scatter_ps(__addr, __index, __v1, __scale) __extension__ ({ \ + __builtin_ia32_scattersiv4sf (__addr, (__mmask8) 0xFF, \ + (__v4si) __index, (__v4sf) __v1, __scale); }) + +#define _mm_mask_i32scatter_ps(__addr, __mask, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scattersiv4sf (__addr, __mask, (__v4si) __index, \ + (__v4sf) __v1, __scale); }) + +#define _mm_i32scatter_epi32(__addr, __index, __v1, __scale) __extension__ ({ \ + __builtin_ia32_scattersiv4si (__addr, (__mmask8) 0xFF, \ + (__v4si) __index, (__v4si) __v1, __scale); }) + +#define _mm_mask_i32scatter_epi32(__addr, __mask, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scattersiv4si (__addr, __mask, (__v4si) __index,\ + (__v4si) __v1, __scale); }) + +#define _mm256_i32scatter_ps(__addr, __index, __v1, __scale) __extension__ ({ \ + __builtin_ia32_scattersiv8sf (__addr, (__mmask8) 0xFF, \ + (__v8si) __index, (__v8sf) __v1, __scale); }) + +#define _mm256_mask_i32scatter_ps(__addr, __mask, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scattersiv8sf (__addr, __mask, (__v8si) __index,\ + (__v8sf) __v1, __scale); }) + +#define _mm256_i32scatter_epi32(__addr, __index, __v1, __scale) __extension__ ({ \ + __builtin_ia32_scattersiv8si (__addr, (__mmask8) 0xFF, \ + (__v8si) __index, (__v8si) __v1, __scale); }) + +#define _mm256_mask_i32scatter_epi32(__addr, __mask, __index, __v1, \ + __scale) __extension__ ({ \ + __builtin_ia32_scattersiv8si (__addr, __mask, (__v8si) __index, \ + (__v8si) __v1, __scale); }) + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_sqrt_pd (__m128d __W, __mmask8 __U, __m128d __A) { + return (__m128d) __builtin_ia32_sqrtpd128_mask ((__v2df) __A, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_sqrt_pd (__mmask8 __U, __m128d __A) { + return (__m128d) __builtin_ia32_sqrtpd128_mask ((__v2df) __A, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_sqrt_pd (__m256d __W, __mmask8 __U, __m256d __A) { + return (__m256d) __builtin_ia32_sqrtpd256_mask ((__v4df) __A, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_sqrt_pd (__mmask8 __U, __m256d __A) { + return (__m256d) __builtin_ia32_sqrtpd256_mask ((__v4df) __A, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_sqrt_ps (__m128 __W, __mmask8 __U, __m128 __A) { + return (__m128) __builtin_ia32_sqrtps128_mask ((__v4sf) __A, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_sqrt_ps (__mmask8 __U, __m128 __A) { + return (__m128) __builtin_ia32_sqrtps128_mask ((__v4sf) __A, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_sqrt_ps (__m256 __W, __mmask8 __U, __m256 __A) { + return (__m256) __builtin_ia32_sqrtps256_mask ((__v8sf) __A, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_sqrt_ps (__mmask8 __U, __m256 __A) { + return (__m256) __builtin_ia32_sqrtps256_mask ((__v8sf) __A, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_sub_pd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_subpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_sub_pd (__mmask8 __U, __m128d __A, __m128d __B) { + return (__m128d) __builtin_ia32_subpd128_mask ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_sub_pd (__m256d __W, __mmask8 __U, __m256d __A, + __m256d __B) { + return (__m256d) __builtin_ia32_subpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) __W, + (__mmask8) __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_sub_pd (__mmask8 __U, __m256d __A, __m256d __B) { + return (__m256d) __builtin_ia32_subpd256_mask ((__v4df) __A, + (__v4df) __B, + (__v4df) + _mm256_setzero_pd (), + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_sub_ps (__m128 __W, __mmask16 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_subps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_sub_ps (__mmask16 __U, __m128 __A, __m128 __B) { + return (__m128) __builtin_ia32_subps128_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_sub_ps (__m256 __W, __mmask16 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_subps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) __W, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_sub_ps (__mmask16 __U, __m256 __A, __m256 __B) { + return (__m256) __builtin_ia32_subps256_mask ((__v8sf) __A, + (__v8sf) __B, + (__v8sf) + _mm256_setzero_ps (), + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask2_permutex2var_epi32 (__m128i __A, __m128i __I, __mmask8 __U, + __m128i __B) { + return (__m128i) __builtin_ia32_vpermi2vard128_mask ((__v4si) __A, + (__v4si) __I + /* idx */ , + (__v4si) __B, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask2_permutex2var_epi32 (__m256i __A, __m256i __I, + __mmask8 __U, __m256i __B) { + return (__m256i) __builtin_ia32_vpermi2vard256_mask ((__v8si) __A, + (__v8si) __I + /* idx */ , + (__v8si) __B, + (__mmask8) __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask2_permutex2var_pd (__m128d __A, __m128i __I, __mmask8 __U, + __m128d __B) { + return (__m128d) __builtin_ia32_vpermi2varpd128_mask ((__v2df) __A, + (__v2di) __I + /* idx */ , + (__v2df) __B, + (__mmask8) + __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask2_permutex2var_pd (__m256d __A, __m256i __I, __mmask8 __U, + __m256d __B) { + return (__m256d) __builtin_ia32_vpermi2varpd256_mask ((__v4df) __A, + (__v4di) __I + /* idx */ , + (__v4df) __B, + (__mmask8) + __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask2_permutex2var_ps (__m128 __A, __m128i __I, __mmask8 __U, + __m128 __B) { + return (__m128) __builtin_ia32_vpermi2varps128_mask ((__v4sf) __A, + (__v4si) __I + /* idx */ , + (__v4sf) __B, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask2_permutex2var_ps (__m256 __A, __m256i __I, __mmask8 __U, + __m256 __B) { + return (__m256) __builtin_ia32_vpermi2varps256_mask ((__v8sf) __A, + (__v8si) __I + /* idx */ , + (__v8sf) __B, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask2_permutex2var_epi64 (__m128i __A, __m128i __I, __mmask8 __U, + __m128i __B) { + return (__m128i) __builtin_ia32_vpermi2varq128_mask ((__v2di) __A, + (__v2di) __I + /* idx */ , + (__v2di) __B, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask2_permutex2var_epi64 (__m256i __A, __m256i __I, + __mmask8 __U, __m256i __B) { + return (__m256i) __builtin_ia32_vpermi2varq256_mask ((__v4di) __A, + (__v4di) __I + /* idx */ , + (__v4di) __B, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_permutex2var_epi32 (__m128i __A, __m128i __I, __m128i __B) { + return (__m128i) __builtin_ia32_vpermt2vard128_mask ((__v4si) __I + /* idx */ , + (__v4si) __A, + (__v4si) __B, + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_permutex2var_epi32 (__m128i __A, __mmask8 __U, __m128i __I, + __m128i __B) { + return (__m128i) __builtin_ia32_vpermt2vard128_mask ((__v4si) __I + /* idx */ , + (__v4si) __A, + (__v4si) __B, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_permutex2var_epi32 (__mmask8 __U, __m128i __A, __m128i __I, + __m128i __B) { + return (__m128i) __builtin_ia32_vpermt2vard128_maskz ((__v4si) __I + /* idx */ , + (__v4si) __A, + (__v4si) __B, + (__mmask8) + __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_permutex2var_epi32 (__m256i __A, __m256i __I, __m256i __B) { + return (__m256i) __builtin_ia32_vpermt2vard256_mask ((__v8si) __I + /* idx */ , + (__v8si) __A, + (__v8si) __B, + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_permutex2var_epi32 (__m256i __A, __mmask8 __U, __m256i __I, + __m256i __B) { + return (__m256i) __builtin_ia32_vpermt2vard256_mask ((__v8si) __I + /* idx */ , + (__v8si) __A, + (__v8si) __B, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_permutex2var_epi32 (__mmask8 __U, __m256i __A, + __m256i __I, __m256i __B) { + return (__m256i) __builtin_ia32_vpermt2vard256_maskz ((__v8si) __I + /* idx */ , + (__v8si) __A, + (__v8si) __B, + (__mmask8) + __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_permutex2var_pd (__m128d __A, __m128i __I, __m128d __B) { + return (__m128d) __builtin_ia32_vpermt2varpd128_mask ((__v2di) __I + /* idx */ , + (__v2df) __A, + (__v2df) __B, + (__mmask8) - + 1); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mask_permutex2var_pd (__m128d __A, __mmask8 __U, __m128i __I, + __m128d __B) { + return (__m128d) __builtin_ia32_vpermt2varpd128_mask ((__v2di) __I + /* idx */ , + (__v2df) __A, + (__v2df) __B, + (__mmask8) + __U); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maskz_permutex2var_pd (__mmask8 __U, __m128d __A, __m128i __I, + __m128d __B) { + return (__m128d) __builtin_ia32_vpermt2varpd128_maskz ((__v2di) __I + /* idx */ , + (__v2df) __A, + (__v2df) __B, + (__mmask8) + __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_permutex2var_pd (__m256d __A, __m256i __I, __m256d __B) { + return (__m256d) __builtin_ia32_vpermt2varpd256_mask ((__v4di) __I + /* idx */ , + (__v4df) __A, + (__v4df) __B, + (__mmask8) - + 1); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_mask_permutex2var_pd (__m256d __A, __mmask8 __U, __m256i __I, + __m256d __B) { + return (__m256d) __builtin_ia32_vpermt2varpd256_mask ((__v4di) __I + /* idx */ , + (__v4df) __A, + (__v4df) __B, + (__mmask8) + __U); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maskz_permutex2var_pd (__mmask8 __U, __m256d __A, __m256i __I, + __m256d __B) { + return (__m256d) __builtin_ia32_vpermt2varpd256_maskz ((__v4di) __I + /* idx */ , + (__v4df) __A, + (__v4df) __B, + (__mmask8) + __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_permutex2var_ps (__m128 __A, __m128i __I, __m128 __B) { + return (__m128) __builtin_ia32_vpermt2varps128_mask ((__v4si) __I + /* idx */ , + (__v4sf) __A, + (__v4sf) __B, + (__mmask8) -1); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mask_permutex2var_ps (__m128 __A, __mmask8 __U, __m128i __I, + __m128 __B) { + return (__m128) __builtin_ia32_vpermt2varps128_mask ((__v4si) __I + /* idx */ , + (__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maskz_permutex2var_ps (__mmask8 __U, __m128 __A, __m128i __I, + __m128 __B) { + return (__m128) __builtin_ia32_vpermt2varps128_maskz ((__v4si) __I + /* idx */ , + (__v4sf) __A, + (__v4sf) __B, + (__mmask8) + __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_permutex2var_ps (__m256 __A, __m256i __I, __m256 __B) { + return (__m256) __builtin_ia32_vpermt2varps256_mask ((__v8si) __I + /* idx */ , + (__v8sf) __A, + (__v8sf) __B, + (__mmask8) -1); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_mask_permutex2var_ps (__m256 __A, __mmask8 __U, __m256i __I, + __m256 __B) { + return (__m256) __builtin_ia32_vpermt2varps256_mask ((__v8si) __I + /* idx */ , + (__v8sf) __A, + (__v8sf) __B, + (__mmask8) __U); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maskz_permutex2var_ps (__mmask8 __U, __m256 __A, __m256i __I, + __m256 __B) { + return (__m256) __builtin_ia32_vpermt2varps256_maskz ((__v8si) __I + /* idx */ , + (__v8sf) __A, + (__v8sf) __B, + (__mmask8) + __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_permutex2var_epi64 (__m128i __A, __m128i __I, __m128i __B) { + return (__m128i) __builtin_ia32_vpermt2varq128_mask ((__v2di) __I + /* idx */ , + (__v2di) __A, + (__v2di) __B, + (__mmask8) -1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mask_permutex2var_epi64 (__m128i __A, __mmask8 __U, __m128i __I, + __m128i __B) { + return (__m128i) __builtin_ia32_vpermt2varq128_mask ((__v2di) __I + /* idx */ , + (__v2di) __A, + (__v2di) __B, + (__mmask8) __U); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maskz_permutex2var_epi64 (__mmask8 __U, __m128i __A, __m128i __I, + __m128i __B) { + return (__m128i) __builtin_ia32_vpermt2varq128_maskz ((__v2di) __I + /* idx */ , + (__v2di) __A, + (__v2di) __B, + (__mmask8) + __U); +} + + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_permutex2var_epi64 (__m256i __A, __m256i __I, __m256i __B) { + return (__m256i) __builtin_ia32_vpermt2varq256_mask ((__v4di) __I + /* idx */ , + (__v4di) __A, + (__v4di) __B, + (__mmask8) -1); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_mask_permutex2var_epi64 (__m256i __A, __mmask8 __U, __m256i __I, + __m256i __B) { + return (__m256i) __builtin_ia32_vpermt2varq256_mask ((__v4di) __I + /* idx */ , + (__v4di) __A, + (__v4di) __B, + (__mmask8) __U); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_maskz_permutex2var_epi64 (__mmask8 __U, __m256i __A, + __m256i __I, __m256i __B) { + return (__m256i) __builtin_ia32_vpermt2varq256_maskz ((__v4di) __I + /* idx */ , + (__v4di) __A, + (__v4di) __B, + (__mmask8) + __U); +} + +#undef __DEFAULT_FN_ATTRS +#undef __DEFAULT_FN_ATTRS_BOTH + +#endif /* __AVX512VLINTRIN_H */ diff --git a/headers/clang/avxintrin.h b/headers/clang/avxintrin.h new file mode 100644 index 0000000000..0041365edf --- /dev/null +++ b/headers/clang/avxintrin.h @@ -0,0 +1,1330 @@ +/*===---- avxintrin.h - AVX intrinsics -------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __AVXINTRIN_H +#define __AVXINTRIN_H + +typedef double __v4df __attribute__ ((__vector_size__ (32))); +typedef float __v8sf __attribute__ ((__vector_size__ (32))); +typedef long long __v4di __attribute__ ((__vector_size__ (32))); +typedef int __v8si __attribute__ ((__vector_size__ (32))); +typedef short __v16hi __attribute__ ((__vector_size__ (32))); +typedef char __v32qi __attribute__ ((__vector_size__ (32))); + +/* We need an explicitly signed variant for char. Note that this shouldn't + * appear in the interface though. */ +typedef signed char __v32qs __attribute__((__vector_size__(32))); + +typedef float __m256 __attribute__ ((__vector_size__ (32))); +typedef double __m256d __attribute__((__vector_size__(32))); +typedef long long __m256i __attribute__((__vector_size__(32))); + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx"))) + +/* Arithmetic */ +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_add_pd(__m256d __a, __m256d __b) +{ + return __a+__b; +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_add_ps(__m256 __a, __m256 __b) +{ + return __a+__b; +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_sub_pd(__m256d __a, __m256d __b) +{ + return __a-__b; +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_sub_ps(__m256 __a, __m256 __b) +{ + return __a-__b; +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_addsub_pd(__m256d __a, __m256d __b) +{ + return (__m256d)__builtin_ia32_addsubpd256((__v4df)__a, (__v4df)__b); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_addsub_ps(__m256 __a, __m256 __b) +{ + return (__m256)__builtin_ia32_addsubps256((__v8sf)__a, (__v8sf)__b); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_div_pd(__m256d __a, __m256d __b) +{ + return __a / __b; +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_div_ps(__m256 __a, __m256 __b) +{ + return __a / __b; +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_max_pd(__m256d __a, __m256d __b) +{ + return (__m256d)__builtin_ia32_maxpd256((__v4df)__a, (__v4df)__b); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_max_ps(__m256 __a, __m256 __b) +{ + return (__m256)__builtin_ia32_maxps256((__v8sf)__a, (__v8sf)__b); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_min_pd(__m256d __a, __m256d __b) +{ + return (__m256d)__builtin_ia32_minpd256((__v4df)__a, (__v4df)__b); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_min_ps(__m256 __a, __m256 __b) +{ + return (__m256)__builtin_ia32_minps256((__v8sf)__a, (__v8sf)__b); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_mul_pd(__m256d __a, __m256d __b) +{ + return __a * __b; +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_mul_ps(__m256 __a, __m256 __b) +{ + return __a * __b; +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_sqrt_pd(__m256d __a) +{ + return (__m256d)__builtin_ia32_sqrtpd256((__v4df)__a); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_sqrt_ps(__m256 __a) +{ + return (__m256)__builtin_ia32_sqrtps256((__v8sf)__a); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_rsqrt_ps(__m256 __a) +{ + return (__m256)__builtin_ia32_rsqrtps256((__v8sf)__a); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_rcp_ps(__m256 __a) +{ + return (__m256)__builtin_ia32_rcpps256((__v8sf)__a); +} + +#define _mm256_round_pd(V, M) __extension__ ({ \ + __m256d __V = (V); \ + (__m256d)__builtin_ia32_roundpd256((__v4df)__V, (M)); }) + +#define _mm256_round_ps(V, M) __extension__ ({ \ + __m256 __V = (V); \ + (__m256)__builtin_ia32_roundps256((__v8sf)__V, (M)); }) + +#define _mm256_ceil_pd(V) _mm256_round_pd((V), _MM_FROUND_CEIL) +#define _mm256_floor_pd(V) _mm256_round_pd((V), _MM_FROUND_FLOOR) +#define _mm256_ceil_ps(V) _mm256_round_ps((V), _MM_FROUND_CEIL) +#define _mm256_floor_ps(V) _mm256_round_ps((V), _MM_FROUND_FLOOR) + +/* Logical */ +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_and_pd(__m256d __a, __m256d __b) +{ + return (__m256d)((__v4di)__a & (__v4di)__b); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_and_ps(__m256 __a, __m256 __b) +{ + return (__m256)((__v8si)__a & (__v8si)__b); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_andnot_pd(__m256d __a, __m256d __b) +{ + return (__m256d)(~(__v4di)__a & (__v4di)__b); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_andnot_ps(__m256 __a, __m256 __b) +{ + return (__m256)(~(__v8si)__a & (__v8si)__b); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_or_pd(__m256d __a, __m256d __b) +{ + return (__m256d)((__v4di)__a | (__v4di)__b); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_or_ps(__m256 __a, __m256 __b) +{ + return (__m256)((__v8si)__a | (__v8si)__b); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_xor_pd(__m256d __a, __m256d __b) +{ + return (__m256d)((__v4di)__a ^ (__v4di)__b); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_xor_ps(__m256 __a, __m256 __b) +{ + return (__m256)((__v8si)__a ^ (__v8si)__b); +} + +/* Horizontal arithmetic */ +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_hadd_pd(__m256d __a, __m256d __b) +{ + return (__m256d)__builtin_ia32_haddpd256((__v4df)__a, (__v4df)__b); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_hadd_ps(__m256 __a, __m256 __b) +{ + return (__m256)__builtin_ia32_haddps256((__v8sf)__a, (__v8sf)__b); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_hsub_pd(__m256d __a, __m256d __b) +{ + return (__m256d)__builtin_ia32_hsubpd256((__v4df)__a, (__v4df)__b); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_hsub_ps(__m256 __a, __m256 __b) +{ + return (__m256)__builtin_ia32_hsubps256((__v8sf)__a, (__v8sf)__b); +} + +/* Vector permutations */ +static __inline __m128d __DEFAULT_FN_ATTRS +_mm_permutevar_pd(__m128d __a, __m128i __c) +{ + return (__m128d)__builtin_ia32_vpermilvarpd((__v2df)__a, (__v2di)__c); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_permutevar_pd(__m256d __a, __m256i __c) +{ + return (__m256d)__builtin_ia32_vpermilvarpd256((__v4df)__a, (__v4di)__c); +} + +static __inline __m128 __DEFAULT_FN_ATTRS +_mm_permutevar_ps(__m128 __a, __m128i __c) +{ + return (__m128)__builtin_ia32_vpermilvarps((__v4sf)__a, (__v4si)__c); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_permutevar_ps(__m256 __a, __m256i __c) +{ + return (__m256)__builtin_ia32_vpermilvarps256((__v8sf)__a, (__v8si)__c); +} + +#define _mm_permute_pd(A, C) __extension__ ({ \ + __m128d __A = (A); \ + (__m128d)__builtin_shufflevector((__v2df)__A, (__v2df) _mm_setzero_pd(), \ + (C) & 0x1, ((C) & 0x2) >> 1); }) + +#define _mm256_permute_pd(A, C) __extension__ ({ \ + __m256d __A = (A); \ + (__m256d)__builtin_shufflevector((__v4df)__A, (__v4df) _mm256_setzero_pd(), \ + (C) & 0x1, ((C) & 0x2) >> 1, \ + 2 + (((C) & 0x4) >> 2), \ + 2 + (((C) & 0x8) >> 3)); }) + +#define _mm_permute_ps(A, C) __extension__ ({ \ + __m128 __A = (A); \ + (__m128)__builtin_shufflevector((__v4sf)__A, (__v4sf) _mm_setzero_ps(), \ + (C) & 0x3, ((C) & 0xc) >> 2, \ + ((C) & 0x30) >> 4, ((C) & 0xc0) >> 6); }) + +#define _mm256_permute_ps(A, C) __extension__ ({ \ + __m256 __A = (A); \ + (__m256)__builtin_shufflevector((__v8sf)__A, (__v8sf) _mm256_setzero_ps(), \ + (C) & 0x3, ((C) & 0xc) >> 2, \ + ((C) & 0x30) >> 4, ((C) & 0xc0) >> 6, \ + 4 + (((C) & 0x03) >> 0), \ + 4 + (((C) & 0x0c) >> 2), \ + 4 + (((C) & 0x30) >> 4), \ + 4 + (((C) & 0xc0) >> 6)); }) + +#define _mm256_permute2f128_pd(V1, V2, M) __extension__ ({ \ + __m256d __V1 = (V1); \ + __m256d __V2 = (V2); \ + (__m256d)__builtin_ia32_vperm2f128_pd256((__v4df)__V1, (__v4df)__V2, (M)); }) + +#define _mm256_permute2f128_ps(V1, V2, M) __extension__ ({ \ + __m256 __V1 = (V1); \ + __m256 __V2 = (V2); \ + (__m256)__builtin_ia32_vperm2f128_ps256((__v8sf)__V1, (__v8sf)__V2, (M)); }) + +#define _mm256_permute2f128_si256(V1, V2, M) __extension__ ({ \ + __m256i __V1 = (V1); \ + __m256i __V2 = (V2); \ + (__m256i)__builtin_ia32_vperm2f128_si256((__v8si)__V1, (__v8si)__V2, (M)); }) + +/* Vector Blend */ +#define _mm256_blend_pd(V1, V2, M) __extension__ ({ \ + __m256d __V1 = (V1); \ + __m256d __V2 = (V2); \ + (__m256d)__builtin_shufflevector((__v4df)__V1, (__v4df)__V2, \ + (((M) & 0x01) ? 4 : 0), \ + (((M) & 0x02) ? 5 : 1), \ + (((M) & 0x04) ? 6 : 2), \ + (((M) & 0x08) ? 7 : 3)); }) + +#define _mm256_blend_ps(V1, V2, M) __extension__ ({ \ + __m256 __V1 = (V1); \ + __m256 __V2 = (V2); \ + (__m256)__builtin_shufflevector((__v8sf)__V1, (__v8sf)__V2, \ + (((M) & 0x01) ? 8 : 0), \ + (((M) & 0x02) ? 9 : 1), \ + (((M) & 0x04) ? 10 : 2), \ + (((M) & 0x08) ? 11 : 3), \ + (((M) & 0x10) ? 12 : 4), \ + (((M) & 0x20) ? 13 : 5), \ + (((M) & 0x40) ? 14 : 6), \ + (((M) & 0x80) ? 15 : 7)); }) + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_blendv_pd(__m256d __a, __m256d __b, __m256d __c) +{ + return (__m256d)__builtin_ia32_blendvpd256( + (__v4df)__a, (__v4df)__b, (__v4df)__c); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c) +{ + return (__m256)__builtin_ia32_blendvps256( + (__v8sf)__a, (__v8sf)__b, (__v8sf)__c); +} + +/* Vector Dot Product */ +#define _mm256_dp_ps(V1, V2, M) __extension__ ({ \ + __m256 __V1 = (V1); \ + __m256 __V2 = (V2); \ + (__m256)__builtin_ia32_dpps256((__v8sf)__V1, (__v8sf)__V2, (M)); }) + +/* Vector shuffle */ +#define _mm256_shuffle_ps(a, b, mask) __extension__ ({ \ + __m256 __a = (a); \ + __m256 __b = (b); \ + (__m256)__builtin_shufflevector((__v8sf)__a, (__v8sf)__b, \ + (mask) & 0x3, ((mask) & 0xc) >> 2, \ + (((mask) & 0x30) >> 4) + 8, (((mask) & 0xc0) >> 6) + 8, \ + ((mask) & 0x3) + 4, (((mask) & 0xc) >> 2) + 4, \ + (((mask) & 0x30) >> 4) + 12, (((mask) & 0xc0) >> 6) + 12); }) + +#define _mm256_shuffle_pd(a, b, mask) __extension__ ({ \ + __m256d __a = (a); \ + __m256d __b = (b); \ + (__m256d)__builtin_shufflevector((__v4df)__a, (__v4df)__b, \ + (mask) & 0x1, \ + (((mask) & 0x2) >> 1) + 4, \ + (((mask) & 0x4) >> 2) + 2, \ + (((mask) & 0x8) >> 3) + 6); }) + +/* Compare */ +#define _CMP_EQ_OQ 0x00 /* Equal (ordered, non-signaling) */ +#define _CMP_LT_OS 0x01 /* Less-than (ordered, signaling) */ +#define _CMP_LE_OS 0x02 /* Less-than-or-equal (ordered, signaling) */ +#define _CMP_UNORD_Q 0x03 /* Unordered (non-signaling) */ +#define _CMP_NEQ_UQ 0x04 /* Not-equal (unordered, non-signaling) */ +#define _CMP_NLT_US 0x05 /* Not-less-than (unordered, signaling) */ +#define _CMP_NLE_US 0x06 /* Not-less-than-or-equal (unordered, signaling) */ +#define _CMP_ORD_Q 0x07 /* Ordered (nonsignaling) */ +#define _CMP_EQ_UQ 0x08 /* Equal (unordered, non-signaling) */ +#define _CMP_NGE_US 0x09 /* Not-greater-than-or-equal (unord, signaling) */ +#define _CMP_NGT_US 0x0a /* Not-greater-than (unordered, signaling) */ +#define _CMP_FALSE_OQ 0x0b /* False (ordered, non-signaling) */ +#define _CMP_NEQ_OQ 0x0c /* Not-equal (ordered, non-signaling) */ +#define _CMP_GE_OS 0x0d /* Greater-than-or-equal (ordered, signaling) */ +#define _CMP_GT_OS 0x0e /* Greater-than (ordered, signaling) */ +#define _CMP_TRUE_UQ 0x0f /* True (unordered, non-signaling) */ +#define _CMP_EQ_OS 0x10 /* Equal (ordered, signaling) */ +#define _CMP_LT_OQ 0x11 /* Less-than (ordered, non-signaling) */ +#define _CMP_LE_OQ 0x12 /* Less-than-or-equal (ordered, non-signaling) */ +#define _CMP_UNORD_S 0x13 /* Unordered (signaling) */ +#define _CMP_NEQ_US 0x14 /* Not-equal (unordered, signaling) */ +#define _CMP_NLT_UQ 0x15 /* Not-less-than (unordered, non-signaling) */ +#define _CMP_NLE_UQ 0x16 /* Not-less-than-or-equal (unord, non-signaling) */ +#define _CMP_ORD_S 0x17 /* Ordered (signaling) */ +#define _CMP_EQ_US 0x18 /* Equal (unordered, signaling) */ +#define _CMP_NGE_UQ 0x19 /* Not-greater-than-or-equal (unord, non-sign) */ +#define _CMP_NGT_UQ 0x1a /* Not-greater-than (unordered, non-signaling) */ +#define _CMP_FALSE_OS 0x1b /* False (ordered, signaling) */ +#define _CMP_NEQ_OS 0x1c /* Not-equal (ordered, signaling) */ +#define _CMP_GE_OQ 0x1d /* Greater-than-or-equal (ordered, non-signaling) */ +#define _CMP_GT_OQ 0x1e /* Greater-than (ordered, non-signaling) */ +#define _CMP_TRUE_US 0x1f /* True (unordered, signaling) */ + +#define _mm_cmp_pd(a, b, c) __extension__ ({ \ + __m128d __a = (a); \ + __m128d __b = (b); \ + (__m128d)__builtin_ia32_cmppd((__v2df)__a, (__v2df)__b, (c)); }) + +#define _mm_cmp_ps(a, b, c) __extension__ ({ \ + __m128 __a = (a); \ + __m128 __b = (b); \ + (__m128)__builtin_ia32_cmpps((__v4sf)__a, (__v4sf)__b, (c)); }) + +#define _mm256_cmp_pd(a, b, c) __extension__ ({ \ + __m256d __a = (a); \ + __m256d __b = (b); \ + (__m256d)__builtin_ia32_cmppd256((__v4df)__a, (__v4df)__b, (c)); }) + +#define _mm256_cmp_ps(a, b, c) __extension__ ({ \ + __m256 __a = (a); \ + __m256 __b = (b); \ + (__m256)__builtin_ia32_cmpps256((__v8sf)__a, (__v8sf)__b, (c)); }) + +#define _mm_cmp_sd(a, b, c) __extension__ ({ \ + __m128d __a = (a); \ + __m128d __b = (b); \ + (__m128d)__builtin_ia32_cmpsd((__v2df)__a, (__v2df)__b, (c)); }) + +#define _mm_cmp_ss(a, b, c) __extension__ ({ \ + __m128 __a = (a); \ + __m128 __b = (b); \ + (__m128)__builtin_ia32_cmpss((__v4sf)__a, (__v4sf)__b, (c)); }) + +static __inline int __DEFAULT_FN_ATTRS +_mm256_extract_epi32(__m256i __a, const int __imm) +{ + __v8si __b = (__v8si)__a; + return __b[__imm & 7]; +} + +static __inline int __DEFAULT_FN_ATTRS +_mm256_extract_epi16(__m256i __a, const int __imm) +{ + __v16hi __b = (__v16hi)__a; + return __b[__imm & 15]; +} + +static __inline int __DEFAULT_FN_ATTRS +_mm256_extract_epi8(__m256i __a, const int __imm) +{ + __v32qi __b = (__v32qi)__a; + return __b[__imm & 31]; +} + +#ifdef __x86_64__ +static __inline long long __DEFAULT_FN_ATTRS +_mm256_extract_epi64(__m256i __a, const int __imm) +{ + __v4di __b = (__v4di)__a; + return __b[__imm & 3]; +} +#endif + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_insert_epi32(__m256i __a, int __b, int const __imm) +{ + __v8si __c = (__v8si)__a; + __c[__imm & 7] = __b; + return (__m256i)__c; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_insert_epi16(__m256i __a, int __b, int const __imm) +{ + __v16hi __c = (__v16hi)__a; + __c[__imm & 15] = __b; + return (__m256i)__c; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_insert_epi8(__m256i __a, int __b, int const __imm) +{ + __v32qi __c = (__v32qi)__a; + __c[__imm & 31] = __b; + return (__m256i)__c; +} + +#ifdef __x86_64__ +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_insert_epi64(__m256i __a, long long __b, int const __imm) +{ + __v4di __c = (__v4di)__a; + __c[__imm & 3] = __b; + return (__m256i)__c; +} +#endif + +/* Conversion */ +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_cvtepi32_pd(__m128i __a) +{ + return (__m256d)__builtin_ia32_cvtdq2pd256((__v4si) __a); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_cvtepi32_ps(__m256i __a) +{ + return (__m256)__builtin_ia32_cvtdq2ps256((__v8si) __a); +} + +static __inline __m128 __DEFAULT_FN_ATTRS +_mm256_cvtpd_ps(__m256d __a) +{ + return (__m128)__builtin_ia32_cvtpd2ps256((__v4df) __a); +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_cvtps_epi32(__m256 __a) +{ + return (__m256i)__builtin_ia32_cvtps2dq256((__v8sf) __a); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_cvtps_pd(__m128 __a) +{ + return (__m256d)__builtin_ia32_cvtps2pd256((__v4sf) __a); +} + +static __inline __m128i __DEFAULT_FN_ATTRS +_mm256_cvttpd_epi32(__m256d __a) +{ + return (__m128i)__builtin_ia32_cvttpd2dq256((__v4df) __a); +} + +static __inline __m128i __DEFAULT_FN_ATTRS +_mm256_cvtpd_epi32(__m256d __a) +{ + return (__m128i)__builtin_ia32_cvtpd2dq256((__v4df) __a); +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_cvttps_epi32(__m256 __a) +{ + return (__m256i)__builtin_ia32_cvttps2dq256((__v8sf) __a); +} + +/* Vector replicate */ +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_movehdup_ps(__m256 __a) +{ + return __builtin_shufflevector(__a, __a, 1, 1, 3, 3, 5, 5, 7, 7); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_moveldup_ps(__m256 __a) +{ + return __builtin_shufflevector(__a, __a, 0, 0, 2, 2, 4, 4, 6, 6); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_movedup_pd(__m256d __a) +{ + return __builtin_shufflevector(__a, __a, 0, 0, 2, 2); +} + +/* Unpack and Interleave */ +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_unpackhi_pd(__m256d __a, __m256d __b) +{ + return __builtin_shufflevector(__a, __b, 1, 5, 1+2, 5+2); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_unpacklo_pd(__m256d __a, __m256d __b) +{ + return __builtin_shufflevector(__a, __b, 0, 4, 0+2, 4+2); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_unpackhi_ps(__m256 __a, __m256 __b) +{ + return __builtin_shufflevector(__a, __b, 2, 10, 2+1, 10+1, 6, 14, 6+1, 14+1); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_unpacklo_ps(__m256 __a, __m256 __b) +{ + return __builtin_shufflevector(__a, __b, 0, 8, 0+1, 8+1, 4, 12, 4+1, 12+1); +} + +/* Bit Test */ +static __inline int __DEFAULT_FN_ATTRS +_mm_testz_pd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_vtestzpd((__v2df)__a, (__v2df)__b); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm_testc_pd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_vtestcpd((__v2df)__a, (__v2df)__b); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm_testnzc_pd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_vtestnzcpd((__v2df)__a, (__v2df)__b); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm_testz_ps(__m128 __a, __m128 __b) +{ + return __builtin_ia32_vtestzps((__v4sf)__a, (__v4sf)__b); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm_testc_ps(__m128 __a, __m128 __b) +{ + return __builtin_ia32_vtestcps((__v4sf)__a, (__v4sf)__b); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm_testnzc_ps(__m128 __a, __m128 __b) +{ + return __builtin_ia32_vtestnzcps((__v4sf)__a, (__v4sf)__b); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm256_testz_pd(__m256d __a, __m256d __b) +{ + return __builtin_ia32_vtestzpd256((__v4df)__a, (__v4df)__b); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm256_testc_pd(__m256d __a, __m256d __b) +{ + return __builtin_ia32_vtestcpd256((__v4df)__a, (__v4df)__b); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm256_testnzc_pd(__m256d __a, __m256d __b) +{ + return __builtin_ia32_vtestnzcpd256((__v4df)__a, (__v4df)__b); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm256_testz_ps(__m256 __a, __m256 __b) +{ + return __builtin_ia32_vtestzps256((__v8sf)__a, (__v8sf)__b); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm256_testc_ps(__m256 __a, __m256 __b) +{ + return __builtin_ia32_vtestcps256((__v8sf)__a, (__v8sf)__b); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm256_testnzc_ps(__m256 __a, __m256 __b) +{ + return __builtin_ia32_vtestnzcps256((__v8sf)__a, (__v8sf)__b); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm256_testz_si256(__m256i __a, __m256i __b) +{ + return __builtin_ia32_ptestz256((__v4di)__a, (__v4di)__b); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm256_testc_si256(__m256i __a, __m256i __b) +{ + return __builtin_ia32_ptestc256((__v4di)__a, (__v4di)__b); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm256_testnzc_si256(__m256i __a, __m256i __b) +{ + return __builtin_ia32_ptestnzc256((__v4di)__a, (__v4di)__b); +} + +/* Vector extract sign mask */ +static __inline int __DEFAULT_FN_ATTRS +_mm256_movemask_pd(__m256d __a) +{ + return __builtin_ia32_movmskpd256((__v4df)__a); +} + +static __inline int __DEFAULT_FN_ATTRS +_mm256_movemask_ps(__m256 __a) +{ + return __builtin_ia32_movmskps256((__v8sf)__a); +} + +/* Vector __zero */ +static __inline void __DEFAULT_FN_ATTRS +_mm256_zeroall(void) +{ + __builtin_ia32_vzeroall(); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm256_zeroupper(void) +{ + __builtin_ia32_vzeroupper(); +} + +/* Vector load with broadcast */ +static __inline __m128 __DEFAULT_FN_ATTRS +_mm_broadcast_ss(float const *__a) +{ + float __f = *__a; + return (__m128)(__v4sf){ __f, __f, __f, __f }; +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_broadcast_sd(double const *__a) +{ + double __d = *__a; + return (__m256d)(__v4df){ __d, __d, __d, __d }; +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_broadcast_ss(float const *__a) +{ + float __f = *__a; + return (__m256)(__v8sf){ __f, __f, __f, __f, __f, __f, __f, __f }; +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_broadcast_pd(__m128d const *__a) +{ + return (__m256d)__builtin_ia32_vbroadcastf128_pd256(__a); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_broadcast_ps(__m128 const *__a) +{ + return (__m256)__builtin_ia32_vbroadcastf128_ps256(__a); +} + +/* SIMD load ops */ +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_load_pd(double const *__p) +{ + return *(__m256d *)__p; +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_load_ps(float const *__p) +{ + return *(__m256 *)__p; +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_loadu_pd(double const *__p) +{ + struct __loadu_pd { + __m256d __v; + } __attribute__((__packed__, __may_alias__)); + return ((struct __loadu_pd*)__p)->__v; +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_loadu_ps(float const *__p) +{ + struct __loadu_ps { + __m256 __v; + } __attribute__((__packed__, __may_alias__)); + return ((struct __loadu_ps*)__p)->__v; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_load_si256(__m256i const *__p) +{ + return *__p; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_loadu_si256(__m256i const *__p) +{ + struct __loadu_si256 { + __m256i __v; + } __attribute__((__packed__, __may_alias__)); + return ((struct __loadu_si256*)__p)->__v; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_lddqu_si256(__m256i const *__p) +{ + return (__m256i)__builtin_ia32_lddqu256((char const *)__p); +} + +/* SIMD store ops */ +static __inline void __DEFAULT_FN_ATTRS +_mm256_store_pd(double *__p, __m256d __a) +{ + *(__m256d *)__p = __a; +} + +static __inline void __DEFAULT_FN_ATTRS +_mm256_store_ps(float *__p, __m256 __a) +{ + *(__m256 *)__p = __a; +} + +static __inline void __DEFAULT_FN_ATTRS +_mm256_storeu_pd(double *__p, __m256d __a) +{ + __builtin_ia32_storeupd256(__p, (__v4df)__a); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm256_storeu_ps(float *__p, __m256 __a) +{ + __builtin_ia32_storeups256(__p, (__v8sf)__a); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm256_store_si256(__m256i *__p, __m256i __a) +{ + *__p = __a; +} + +static __inline void __DEFAULT_FN_ATTRS +_mm256_storeu_si256(__m256i *__p, __m256i __a) +{ + __builtin_ia32_storedqu256((char *)__p, (__v32qi)__a); +} + +/* Conditional load ops */ +static __inline __m128d __DEFAULT_FN_ATTRS +_mm_maskload_pd(double const *__p, __m128i __m) +{ + return (__m128d)__builtin_ia32_maskloadpd((const __v2df *)__p, (__v2di)__m); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_maskload_pd(double const *__p, __m256i __m) +{ + return (__m256d)__builtin_ia32_maskloadpd256((const __v4df *)__p, + (__v4di)__m); +} + +static __inline __m128 __DEFAULT_FN_ATTRS +_mm_maskload_ps(float const *__p, __m128i __m) +{ + return (__m128)__builtin_ia32_maskloadps((const __v4sf *)__p, (__v4si)__m); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_maskload_ps(float const *__p, __m256i __m) +{ + return (__m256)__builtin_ia32_maskloadps256((const __v8sf *)__p, (__v8si)__m); +} + +/* Conditional store ops */ +static __inline void __DEFAULT_FN_ATTRS +_mm256_maskstore_ps(float *__p, __m256i __m, __m256 __a) +{ + __builtin_ia32_maskstoreps256((__v8sf *)__p, (__v8si)__m, (__v8sf)__a); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm_maskstore_pd(double *__p, __m128i __m, __m128d __a) +{ + __builtin_ia32_maskstorepd((__v2df *)__p, (__v2di)__m, (__v2df)__a); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm256_maskstore_pd(double *__p, __m256i __m, __m256d __a) +{ + __builtin_ia32_maskstorepd256((__v4df *)__p, (__v4di)__m, (__v4df)__a); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm_maskstore_ps(float *__p, __m128i __m, __m128 __a) +{ + __builtin_ia32_maskstoreps((__v4sf *)__p, (__v4si)__m, (__v4sf)__a); +} + +/* Cacheability support ops */ +static __inline void __DEFAULT_FN_ATTRS +_mm256_stream_si256(__m256i *__a, __m256i __b) +{ + __builtin_ia32_movntdq256((__v4di *)__a, (__v4di)__b); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm256_stream_pd(double *__a, __m256d __b) +{ + __builtin_ia32_movntpd256(__a, (__v4df)__b); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm256_stream_ps(float *__p, __m256 __a) +{ + __builtin_ia32_movntps256(__p, (__v8sf)__a); +} + +/* Create vectors */ +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_undefined_pd() +{ + return (__m256d)__builtin_ia32_undef256(); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_undefined_ps() +{ + return (__m256)__builtin_ia32_undef256(); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_undefined_si256() +{ + return (__m256i)__builtin_ia32_undef256(); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_set_pd(double __a, double __b, double __c, double __d) +{ + return (__m256d){ __d, __c, __b, __a }; +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_set_ps(float __a, float __b, float __c, float __d, + float __e, float __f, float __g, float __h) +{ + return (__m256){ __h, __g, __f, __e, __d, __c, __b, __a }; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_set_epi32(int __i0, int __i1, int __i2, int __i3, + int __i4, int __i5, int __i6, int __i7) +{ + return (__m256i)(__v8si){ __i7, __i6, __i5, __i4, __i3, __i2, __i1, __i0 }; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_set_epi16(short __w15, short __w14, short __w13, short __w12, + short __w11, short __w10, short __w09, short __w08, + short __w07, short __w06, short __w05, short __w04, + short __w03, short __w02, short __w01, short __w00) +{ + return (__m256i)(__v16hi){ __w00, __w01, __w02, __w03, __w04, __w05, __w06, + __w07, __w08, __w09, __w10, __w11, __w12, __w13, __w14, __w15 }; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_set_epi8(char __b31, char __b30, char __b29, char __b28, + char __b27, char __b26, char __b25, char __b24, + char __b23, char __b22, char __b21, char __b20, + char __b19, char __b18, char __b17, char __b16, + char __b15, char __b14, char __b13, char __b12, + char __b11, char __b10, char __b09, char __b08, + char __b07, char __b06, char __b05, char __b04, + char __b03, char __b02, char __b01, char __b00) +{ + return (__m256i)(__v32qi){ + __b00, __b01, __b02, __b03, __b04, __b05, __b06, __b07, + __b08, __b09, __b10, __b11, __b12, __b13, __b14, __b15, + __b16, __b17, __b18, __b19, __b20, __b21, __b22, __b23, + __b24, __b25, __b26, __b27, __b28, __b29, __b30, __b31 + }; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_set_epi64x(long long __a, long long __b, long long __c, long long __d) +{ + return (__m256i)(__v4di){ __d, __c, __b, __a }; +} + +/* Create vectors with elements in reverse order */ +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_setr_pd(double __a, double __b, double __c, double __d) +{ + return (__m256d){ __a, __b, __c, __d }; +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_setr_ps(float __a, float __b, float __c, float __d, + float __e, float __f, float __g, float __h) +{ + return (__m256){ __a, __b, __c, __d, __e, __f, __g, __h }; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_setr_epi32(int __i0, int __i1, int __i2, int __i3, + int __i4, int __i5, int __i6, int __i7) +{ + return (__m256i)(__v8si){ __i0, __i1, __i2, __i3, __i4, __i5, __i6, __i7 }; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_setr_epi16(short __w15, short __w14, short __w13, short __w12, + short __w11, short __w10, short __w09, short __w08, + short __w07, short __w06, short __w05, short __w04, + short __w03, short __w02, short __w01, short __w00) +{ + return (__m256i)(__v16hi){ __w15, __w14, __w13, __w12, __w11, __w10, __w09, + __w08, __w07, __w06, __w05, __w04, __w03, __w02, __w01, __w00 }; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_setr_epi8(char __b31, char __b30, char __b29, char __b28, + char __b27, char __b26, char __b25, char __b24, + char __b23, char __b22, char __b21, char __b20, + char __b19, char __b18, char __b17, char __b16, + char __b15, char __b14, char __b13, char __b12, + char __b11, char __b10, char __b09, char __b08, + char __b07, char __b06, char __b05, char __b04, + char __b03, char __b02, char __b01, char __b00) +{ + return (__m256i)(__v32qi){ + __b31, __b30, __b29, __b28, __b27, __b26, __b25, __b24, + __b23, __b22, __b21, __b20, __b19, __b18, __b17, __b16, + __b15, __b14, __b13, __b12, __b11, __b10, __b09, __b08, + __b07, __b06, __b05, __b04, __b03, __b02, __b01, __b00 }; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_setr_epi64x(long long __a, long long __b, long long __c, long long __d) +{ + return (__m256i)(__v4di){ __a, __b, __c, __d }; +} + +/* Create vectors with repeated elements */ +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_set1_pd(double __w) +{ + return (__m256d){ __w, __w, __w, __w }; +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_set1_ps(float __w) +{ + return (__m256){ __w, __w, __w, __w, __w, __w, __w, __w }; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_set1_epi32(int __i) +{ + return (__m256i)(__v8si){ __i, __i, __i, __i, __i, __i, __i, __i }; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_set1_epi16(short __w) +{ + return (__m256i)(__v16hi){ __w, __w, __w, __w, __w, __w, __w, __w, __w, __w, + __w, __w, __w, __w, __w, __w }; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_set1_epi8(char __b) +{ + return (__m256i)(__v32qi){ __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, + __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, + __b, __b, __b, __b, __b, __b, __b }; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_set1_epi64x(long long __q) +{ + return (__m256i)(__v4di){ __q, __q, __q, __q }; +} + +/* Create __zeroed vectors */ +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_setzero_pd(void) +{ + return (__m256d){ 0, 0, 0, 0 }; +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_setzero_ps(void) +{ + return (__m256){ 0, 0, 0, 0, 0, 0, 0, 0 }; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_setzero_si256(void) +{ + return (__m256i){ 0LL, 0LL, 0LL, 0LL }; +} + +/* Cast between vector types */ +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_castpd_ps(__m256d __a) +{ + return (__m256)__a; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_castpd_si256(__m256d __a) +{ + return (__m256i)__a; +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_castps_pd(__m256 __a) +{ + return (__m256d)__a; +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_castps_si256(__m256 __a) +{ + return (__m256i)__a; +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_castsi256_ps(__m256i __a) +{ + return (__m256)__a; +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_castsi256_pd(__m256i __a) +{ + return (__m256d)__a; +} + +static __inline __m128d __DEFAULT_FN_ATTRS +_mm256_castpd256_pd128(__m256d __a) +{ + return __builtin_shufflevector(__a, __a, 0, 1); +} + +static __inline __m128 __DEFAULT_FN_ATTRS +_mm256_castps256_ps128(__m256 __a) +{ + return __builtin_shufflevector(__a, __a, 0, 1, 2, 3); +} + +static __inline __m128i __DEFAULT_FN_ATTRS +_mm256_castsi256_si128(__m256i __a) +{ + return __builtin_shufflevector(__a, __a, 0, 1); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_castpd128_pd256(__m128d __a) +{ + return __builtin_shufflevector(__a, __a, 0, 1, -1, -1); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_castps128_ps256(__m128 __a) +{ + return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, -1, -1, -1, -1); +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_castsi128_si256(__m128i __a) +{ + return __builtin_shufflevector(__a, __a, 0, 1, -1, -1); +} + +/* + Vector insert. + We use macros rather than inlines because we only want to accept + invocations where the immediate M is a constant expression. +*/ +#define _mm256_insertf128_ps(V1, V2, M) __extension__ ({ \ + (__m256)__builtin_shufflevector( \ + (__v8sf)(V1), \ + (__v8sf)_mm256_castps128_ps256((__m128)(V2)), \ + (((M) & 1) ? 0 : 8), \ + (((M) & 1) ? 1 : 9), \ + (((M) & 1) ? 2 : 10), \ + (((M) & 1) ? 3 : 11), \ + (((M) & 1) ? 8 : 4), \ + (((M) & 1) ? 9 : 5), \ + (((M) & 1) ? 10 : 6), \ + (((M) & 1) ? 11 : 7) );}) + +#define _mm256_insertf128_pd(V1, V2, M) __extension__ ({ \ + (__m256d)__builtin_shufflevector( \ + (__v4df)(V1), \ + (__v4df)_mm256_castpd128_pd256((__m128d)(V2)), \ + (((M) & 1) ? 0 : 4), \ + (((M) & 1) ? 1 : 5), \ + (((M) & 1) ? 4 : 2), \ + (((M) & 1) ? 5 : 3) );}) + +#define _mm256_insertf128_si256(V1, V2, M) __extension__ ({ \ + (__m256i)__builtin_shufflevector( \ + (__v4di)(V1), \ + (__v4di)_mm256_castsi128_si256((__m128i)(V2)), \ + (((M) & 1) ? 0 : 4), \ + (((M) & 1) ? 1 : 5), \ + (((M) & 1) ? 4 : 2), \ + (((M) & 1) ? 5 : 3) );}) + +/* + Vector extract. + We use macros rather than inlines because we only want to accept + invocations where the immediate M is a constant expression. +*/ +#define _mm256_extractf128_ps(V, M) __extension__ ({ \ + (__m128)__builtin_shufflevector( \ + (__v8sf)(V), \ + (__v8sf)(_mm256_setzero_ps()), \ + (((M) & 1) ? 4 : 0), \ + (((M) & 1) ? 5 : 1), \ + (((M) & 1) ? 6 : 2), \ + (((M) & 1) ? 7 : 3) );}) + +#define _mm256_extractf128_pd(V, M) __extension__ ({ \ + (__m128d)__builtin_shufflevector( \ + (__v4df)(V), \ + (__v4df)(_mm256_setzero_pd()), \ + (((M) & 1) ? 2 : 0), \ + (((M) & 1) ? 3 : 1) );}) + +#define _mm256_extractf128_si256(V, M) __extension__ ({ \ + (__m128i)__builtin_shufflevector( \ + (__v4di)(V), \ + (__v4di)(_mm256_setzero_si256()), \ + (((M) & 1) ? 2 : 0), \ + (((M) & 1) ? 3 : 1) );}) + +/* SIMD load ops (unaligned) */ +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_loadu2_m128(float const *__addr_hi, float const *__addr_lo) +{ + struct __loadu_ps { + __m128 __v; + } __attribute__((__packed__, __may_alias__)); + + __m256 __v256 = _mm256_castps128_ps256(((struct __loadu_ps*)__addr_lo)->__v); + return _mm256_insertf128_ps(__v256, ((struct __loadu_ps*)__addr_hi)->__v, 1); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_loadu2_m128d(double const *__addr_hi, double const *__addr_lo) +{ + struct __loadu_pd { + __m128d __v; + } __attribute__((__packed__, __may_alias__)); + + __m256d __v256 = _mm256_castpd128_pd256(((struct __loadu_pd*)__addr_lo)->__v); + return _mm256_insertf128_pd(__v256, ((struct __loadu_pd*)__addr_hi)->__v, 1); +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_loadu2_m128i(__m128i const *__addr_hi, __m128i const *__addr_lo) +{ + struct __loadu_si128 { + __m128i __v; + } __attribute__((__packed__, __may_alias__)); + __m256i __v256 = _mm256_castsi128_si256( + ((struct __loadu_si128*)__addr_lo)->__v); + return _mm256_insertf128_si256(__v256, + ((struct __loadu_si128*)__addr_hi)->__v, 1); +} + +/* SIMD store ops (unaligned) */ +static __inline void __DEFAULT_FN_ATTRS +_mm256_storeu2_m128(float *__addr_hi, float *__addr_lo, __m256 __a) +{ + __m128 __v128; + + __v128 = _mm256_castps256_ps128(__a); + __builtin_ia32_storeups(__addr_lo, __v128); + __v128 = _mm256_extractf128_ps(__a, 1); + __builtin_ia32_storeups(__addr_hi, __v128); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm256_storeu2_m128d(double *__addr_hi, double *__addr_lo, __m256d __a) +{ + __m128d __v128; + + __v128 = _mm256_castpd256_pd128(__a); + __builtin_ia32_storeupd(__addr_lo, __v128); + __v128 = _mm256_extractf128_pd(__a, 1); + __builtin_ia32_storeupd(__addr_hi, __v128); +} + +static __inline void __DEFAULT_FN_ATTRS +_mm256_storeu2_m128i(__m128i *__addr_hi, __m128i *__addr_lo, __m256i __a) +{ + __m128i __v128; + + __v128 = _mm256_castsi256_si128(__a); + __builtin_ia32_storedqu((char *)__addr_lo, (__v16qi)__v128); + __v128 = _mm256_extractf128_si256(__a, 1); + __builtin_ia32_storedqu((char *)__addr_hi, (__v16qi)__v128); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_set_m128 (__m128 __hi, __m128 __lo) { + return (__m256) __builtin_shufflevector(__lo, __hi, 0, 1, 2, 3, 4, 5, 6, 7); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_set_m128d (__m128d __hi, __m128d __lo) { + return (__m256d)_mm256_set_m128((__m128)__hi, (__m128)__lo); +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_set_m128i (__m128i __hi, __m128i __lo) { + return (__m256i)_mm256_set_m128((__m128)__hi, (__m128)__lo); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_setr_m128 (__m128 __lo, __m128 __hi) { + return _mm256_set_m128(__hi, __lo); +} + +static __inline __m256d __DEFAULT_FN_ATTRS +_mm256_setr_m128d (__m128d __lo, __m128d __hi) { + return (__m256d)_mm256_set_m128((__m128)__hi, (__m128)__lo); +} + +static __inline __m256i __DEFAULT_FN_ATTRS +_mm256_setr_m128i (__m128i __lo, __m128i __hi) { + return (__m256i)_mm256_set_m128((__m128)__hi, (__m128)__lo); +} + +#undef __DEFAULT_FN_ATTRS + +#endif /* __AVXINTRIN_H */ diff --git a/headers/clang/bmi2intrin.h b/headers/clang/bmi2intrin.h new file mode 100644 index 0000000000..fdae82cf2b --- /dev/null +++ b/headers/clang/bmi2intrin.h @@ -0,0 +1,95 @@ +/*===---- bmi2intrin.h - BMI2 intrinsics -----------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __BMI2INTRIN_H +#define __BMI2INTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("bmi2"))) + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +_bzhi_u32(unsigned int __X, unsigned int __Y) +{ + return __builtin_ia32_bzhi_si(__X, __Y); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +_pdep_u32(unsigned int __X, unsigned int __Y) +{ + return __builtin_ia32_pdep_si(__X, __Y); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +_pext_u32(unsigned int __X, unsigned int __Y) +{ + return __builtin_ia32_pext_si(__X, __Y); +} + +#ifdef __x86_64__ + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +_bzhi_u64(unsigned long long __X, unsigned long long __Y) +{ + return __builtin_ia32_bzhi_di(__X, __Y); +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +_pdep_u64(unsigned long long __X, unsigned long long __Y) +{ + return __builtin_ia32_pdep_di(__X, __Y); +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +_pext_u64(unsigned long long __X, unsigned long long __Y) +{ + return __builtin_ia32_pext_di(__X, __Y); +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +_mulx_u64 (unsigned long long __X, unsigned long long __Y, + unsigned long long *__P) +{ + unsigned __int128 __res = (unsigned __int128) __X * __Y; + *__P = (unsigned long long) (__res >> 64); + return (unsigned long long) __res; +} + +#else /* !__x86_64__ */ + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +_mulx_u32 (unsigned int __X, unsigned int __Y, unsigned int *__P) +{ + unsigned long long __res = (unsigned long long) __X * __Y; + *__P = (unsigned int) (__res >> 32); + return (unsigned int) __res; +} + +#endif /* !__x86_64__ */ + +#undef __DEFAULT_FN_ATTRS + +#endif /* __BMI2INTRIN_H */ diff --git a/headers/clang/bmiintrin.h b/headers/clang/bmiintrin.h new file mode 100644 index 0000000000..dc2f83f3e2 --- /dev/null +++ b/headers/clang/bmiintrin.h @@ -0,0 +1,149 @@ +/*===---- bmiintrin.h - BMI intrinsics -------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __BMIINTRIN_H +#define __BMIINTRIN_H + +#define _tzcnt_u16(a) (__tzcnt_u16((a))) +#define _andn_u32(a, b) (__andn_u32((a), (b))) +/* _bextr_u32 != __bextr_u32 */ +#define _blsi_u32(a) (__blsi_u32((a))) +#define _blsmsk_u32(a) (__blsmsk_u32((a))) +#define _blsr_u32(a) (__blsr_u32((a))) +#define _tzcnt_u32(a) (__tzcnt_u32((a))) + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("bmi"))) + +static __inline__ unsigned short __DEFAULT_FN_ATTRS +__tzcnt_u16(unsigned short __X) +{ + return __X ? __builtin_ctzs(__X) : 16; +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__andn_u32(unsigned int __X, unsigned int __Y) +{ + return ~__X & __Y; +} + +/* AMD-specified, double-leading-underscore version of BEXTR */ +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__bextr_u32(unsigned int __X, unsigned int __Y) +{ + return __builtin_ia32_bextr_u32(__X, __Y); +} + +/* Intel-specified, single-leading-underscore version of BEXTR */ +static __inline__ unsigned int __DEFAULT_FN_ATTRS +_bextr_u32(unsigned int __X, unsigned int __Y, unsigned int __Z) +{ + return __builtin_ia32_bextr_u32 (__X, ((__Y & 0xff) | ((__Z & 0xff) << 8))); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__blsi_u32(unsigned int __X) +{ + return __X & -__X; +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__blsmsk_u32(unsigned int __X) +{ + return __X ^ (__X - 1); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__blsr_u32(unsigned int __X) +{ + return __X & (__X - 1); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__tzcnt_u32(unsigned int __X) +{ + return __X ? __builtin_ctz(__X) : 32; +} + +#ifdef __x86_64__ + +#define _andn_u64(a, b) (__andn_u64((a), (b))) +/* _bextr_u64 != __bextr_u64 */ +#define _blsi_u64(a) (__blsi_u64((a))) +#define _blsmsk_u64(a) (__blsmsk_u64((a))) +#define _blsr_u64(a) (__blsr_u64((a))) +#define _tzcnt_u64(a) (__tzcnt_u64((a))) + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__andn_u64 (unsigned long long __X, unsigned long long __Y) +{ + return ~__X & __Y; +} + +/* AMD-specified, double-leading-underscore version of BEXTR */ +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__bextr_u64(unsigned long long __X, unsigned long long __Y) +{ + return __builtin_ia32_bextr_u64(__X, __Y); +} + +/* Intel-specified, single-leading-underscore version of BEXTR */ +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +_bextr_u64(unsigned long long __X, unsigned int __Y, unsigned int __Z) +{ + return __builtin_ia32_bextr_u64 (__X, ((__Y & 0xff) | ((__Z & 0xff) << 8))); +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__blsi_u64(unsigned long long __X) +{ + return __X & -__X; +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__blsmsk_u64(unsigned long long __X) +{ + return __X ^ (__X - 1); +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__blsr_u64(unsigned long long __X) +{ + return __X & (__X - 1); +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__tzcnt_u64(unsigned long long __X) +{ + return __X ? __builtin_ctzll(__X) : 64; +} + +#endif /* __x86_64__ */ + +#undef __DEFAULT_FN_ATTRS + +#endif /* __BMIINTRIN_H */ diff --git a/headers/clang/cpuid.h b/headers/clang/cpuid.h new file mode 100644 index 0000000000..5da02e0e51 --- /dev/null +++ b/headers/clang/cpuid.h @@ -0,0 +1,209 @@ +/*===---- cpuid.h - X86 cpu model detection --------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#if !(__x86_64__ || __i386__) +#error this header is for x86 only +#endif + +/* Responses identification request with %eax 0 */ +/* AMD: "AuthenticAMD" */ +#define signature_AMD_ebx 0x68747541 +#define signature_AMD_edx 0x69746e65 +#define signature_AMD_ecx 0x444d4163 +/* CENTAUR: "CentaurHauls" */ +#define signature_CENTAUR_ebx 0x746e6543 +#define signature_CENTAUR_edx 0x48727561 +#define signature_CENTAUR_ecx 0x736c7561 +/* CYRIX: "CyrixInstead" */ +#define signature_CYRIX_ebx 0x69727943 +#define signature_CYRIX_edx 0x736e4978 +#define signature_CYRIX_ecx 0x64616574 +/* INTEL: "GenuineIntel" */ +#define signature_INTEL_ebx 0x756e6547 +#define signature_INTEL_edx 0x49656e69 +#define signature_INTEL_ecx 0x6c65746e +/* TM1: "TransmetaCPU" */ +#define signature_TM1_ebx 0x6e617254 +#define signature_TM1_edx 0x74656d73 +#define signature_TM1_ecx 0x55504361 +/* TM2: "GenuineTMx86" */ +#define signature_TM2_ebx 0x756e6547 +#define signature_TM2_edx 0x54656e69 +#define signature_TM2_ecx 0x3638784d +/* NSC: "Geode by NSC" */ +#define signature_NSC_ebx 0x646f6547 +#define signature_NSC_edx 0x43534e20 +#define signature_NSC_ecx 0x79622065 +/* NEXGEN: "NexGenDriven" */ +#define signature_NEXGEN_ebx 0x4778654e +#define signature_NEXGEN_edx 0x72446e65 +#define signature_NEXGEN_ecx 0x6e657669 +/* RISE: "RiseRiseRise" */ +#define signature_RISE_ebx 0x65736952 +#define signature_RISE_edx 0x65736952 +#define signature_RISE_ecx 0x65736952 +/* SIS: "SiS SiS SiS " */ +#define signature_SIS_ebx 0x20536953 +#define signature_SIS_edx 0x20536953 +#define signature_SIS_ecx 0x20536953 +/* UMC: "UMC UMC UMC " */ +#define signature_UMC_ebx 0x20434d55 +#define signature_UMC_edx 0x20434d55 +#define signature_UMC_ecx 0x20434d55 +/* VIA: "VIA VIA VIA " */ +#define signature_VIA_ebx 0x20414956 +#define signature_VIA_edx 0x20414956 +#define signature_VIA_ecx 0x20414956 +/* VORTEX: "Vortex86 SoC" */ +#define signature_VORTEX_ebx 0x74726f56 +#define signature_VORTEX_edx 0x36387865 +#define signature_VORTEX_ecx 0x436f5320 + +/* Features in %ecx for level 1 */ +#define bit_SSE3 0x00000001 +#define bit_PCLMULQDQ 0x00000002 +#define bit_DTES64 0x00000004 +#define bit_MONITOR 0x00000008 +#define bit_DSCPL 0x00000010 +#define bit_VMX 0x00000020 +#define bit_SMX 0x00000040 +#define bit_EIST 0x00000080 +#define bit_TM2 0x00000100 +#define bit_SSSE3 0x00000200 +#define bit_CNXTID 0x00000400 +#define bit_FMA 0x00001000 +#define bit_CMPXCHG16B 0x00002000 +#define bit_xTPR 0x00004000 +#define bit_PDCM 0x00008000 +#define bit_PCID 0x00020000 +#define bit_DCA 0x00040000 +#define bit_SSE41 0x00080000 +#define bit_SSE42 0x00100000 +#define bit_x2APIC 0x00200000 +#define bit_MOVBE 0x00400000 +#define bit_POPCNT 0x00800000 +#define bit_TSCDeadline 0x01000000 +#define bit_AESNI 0x02000000 +#define bit_XSAVE 0x04000000 +#define bit_OSXSAVE 0x08000000 +#define bit_AVX 0x10000000 +#define bit_RDRND 0x40000000 + +/* Features in %edx for level 1 */ +#define bit_FPU 0x00000001 +#define bit_VME 0x00000002 +#define bit_DE 0x00000004 +#define bit_PSE 0x00000008 +#define bit_TSC 0x00000010 +#define bit_MSR 0x00000020 +#define bit_PAE 0x00000040 +#define bit_MCE 0x00000080 +#define bit_CX8 0x00000100 +#define bit_APIC 0x00000200 +#define bit_SEP 0x00000800 +#define bit_MTRR 0x00001000 +#define bit_PGE 0x00002000 +#define bit_MCA 0x00004000 +#define bit_CMOV 0x00008000 +#define bit_PAT 0x00010000 +#define bit_PSE36 0x00020000 +#define bit_PSN 0x00040000 +#define bit_CLFSH 0x00080000 +#define bit_DS 0x00200000 +#define bit_ACPI 0x00400000 +#define bit_MMX 0x00800000 +#define bit_FXSR 0x01000000 +#define bit_FXSAVE bit_FXSR /* for gcc compat */ +#define bit_SSE 0x02000000 +#define bit_SSE2 0x04000000 +#define bit_SS 0x08000000 +#define bit_HTT 0x10000000 +#define bit_TM 0x20000000 +#define bit_PBE 0x80000000 + +/* Features in %ebx for level 7 sub-leaf 0 */ +#define bit_FSGSBASE 0x00000001 +#define bit_SMEP 0x00000080 +#define bit_ENH_MOVSB 0x00000200 + +#if __i386__ +#define __cpuid(__level, __eax, __ebx, __ecx, __edx) \ + __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \ + : "0"(__level)) + +#define __cpuid_count(__level, __count, __eax, __ebx, __ecx, __edx) \ + __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \ + : "0"(__level), "2"(__count)) +#else +/* x86-64 uses %rbx as the base register, so preserve it. */ +#define __cpuid(__level, __eax, __ebx, __ecx, __edx) \ + __asm(" xchgq %%rbx,%q1\n" \ + " cpuid\n" \ + " xchgq %%rbx,%q1" \ + : "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \ + : "0"(__level)) + +#define __cpuid_count(__level, __count, __eax, __ebx, __ecx, __edx) \ + __asm(" xchgq %%rbx,%q1\n" \ + " cpuid\n" \ + " xchgq %%rbx,%q1" \ + : "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \ + : "0"(__level), "2"(__count)) +#endif + +static __inline int __get_cpuid (unsigned int __level, unsigned int *__eax, + unsigned int *__ebx, unsigned int *__ecx, + unsigned int *__edx) { + __cpuid(__level, *__eax, *__ebx, *__ecx, *__edx); + return 1; +} + +static __inline int __get_cpuid_max (unsigned int __level, unsigned int *__sig) +{ + unsigned int __eax, __ebx, __ecx, __edx; +#if __i386__ + int __cpuid_supported; + + __asm(" pushfl\n" + " popl %%eax\n" + " movl %%eax,%%ecx\n" + " xorl $0x00200000,%%eax\n" + " pushl %%eax\n" + " popfl\n" + " pushfl\n" + " popl %%eax\n" + " movl $0,%0\n" + " cmpl %%eax,%%ecx\n" + " je 1f\n" + " movl $1,%0\n" + "1:" + : "=r" (__cpuid_supported) : : "eax", "ecx"); + if (!__cpuid_supported) + return 0; +#endif + + __cpuid(__level, __eax, __ebx, __ecx, __edx); + if (__sig) + *__sig = __ebx; + return __eax; +} diff --git a/headers/clang/cuda_builtin_vars.h b/headers/clang/cuda_builtin_vars.h new file mode 100644 index 0000000000..901356b3d5 --- /dev/null +++ b/headers/clang/cuda_builtin_vars.h @@ -0,0 +1,110 @@ +/*===---- cuda_builtin_vars.h - CUDA built-in variables ---------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __CUDA_BUILTIN_VARS_H +#define __CUDA_BUILTIN_VARS_H + +// The file implements built-in CUDA variables using __declspec(property). +// https://msdn.microsoft.com/en-us/library/yhfk0thd.aspx +// All read accesses of built-in variable fields get converted into calls to a +// getter function which in turn would call appropriate builtin to fetch the +// value. +// +// Example: +// int x = threadIdx.x; +// IR output: +// %0 = call i32 @llvm.ptx.read.tid.x() #3 +// PTX output: +// mov.u32 %r2, %tid.x; + +#define __CUDA_DEVICE_BUILTIN(FIELD, INTRINSIC) \ + __declspec(property(get = __fetch_builtin_##FIELD)) unsigned int FIELD; \ + static inline __attribute__((always_inline)) \ + __attribute__((device)) unsigned int __fetch_builtin_##FIELD(void) { \ + return INTRINSIC; \ + } + +#if __cplusplus >= 201103L +#define __DELETE =delete +#else +#define __DELETE +#endif + +// Make sure nobody can create instances of the special varible types. nvcc +// also disallows taking address of special variables, so we disable address-of +// operator as well. +#define __CUDA_DISALLOW_BUILTINVAR_ACCESS(TypeName) \ + __attribute__((device)) TypeName() __DELETE; \ + __attribute__((device)) TypeName(const TypeName &) __DELETE; \ + __attribute__((device)) void operator=(const TypeName &) const __DELETE; \ + __attribute__((device)) TypeName *operator&() const __DELETE + +struct __cuda_builtin_threadIdx_t { + __CUDA_DEVICE_BUILTIN(x,__builtin_ptx_read_tid_x()); + __CUDA_DEVICE_BUILTIN(y,__builtin_ptx_read_tid_y()); + __CUDA_DEVICE_BUILTIN(z,__builtin_ptx_read_tid_z()); +private: + __CUDA_DISALLOW_BUILTINVAR_ACCESS(__cuda_builtin_threadIdx_t); +}; + +struct __cuda_builtin_blockIdx_t { + __CUDA_DEVICE_BUILTIN(x,__builtin_ptx_read_ctaid_x()); + __CUDA_DEVICE_BUILTIN(y,__builtin_ptx_read_ctaid_y()); + __CUDA_DEVICE_BUILTIN(z,__builtin_ptx_read_ctaid_z()); +private: + __CUDA_DISALLOW_BUILTINVAR_ACCESS(__cuda_builtin_blockIdx_t); +}; + +struct __cuda_builtin_blockDim_t { + __CUDA_DEVICE_BUILTIN(x,__builtin_ptx_read_ntid_x()); + __CUDA_DEVICE_BUILTIN(y,__builtin_ptx_read_ntid_y()); + __CUDA_DEVICE_BUILTIN(z,__builtin_ptx_read_ntid_z()); +private: + __CUDA_DISALLOW_BUILTINVAR_ACCESS(__cuda_builtin_blockDim_t); +}; + +struct __cuda_builtin_gridDim_t { + __CUDA_DEVICE_BUILTIN(x,__builtin_ptx_read_nctaid_x()); + __CUDA_DEVICE_BUILTIN(y,__builtin_ptx_read_nctaid_y()); + __CUDA_DEVICE_BUILTIN(z,__builtin_ptx_read_nctaid_z()); +private: + __CUDA_DISALLOW_BUILTINVAR_ACCESS(__cuda_builtin_gridDim_t); +}; + +#define __CUDA_BUILTIN_VAR \ + extern const __attribute__((device)) __attribute__((weak)) +__CUDA_BUILTIN_VAR __cuda_builtin_threadIdx_t threadIdx; +__CUDA_BUILTIN_VAR __cuda_builtin_blockIdx_t blockIdx; +__CUDA_BUILTIN_VAR __cuda_builtin_blockDim_t blockDim; +__CUDA_BUILTIN_VAR __cuda_builtin_gridDim_t gridDim; + +// warpSize should translate to read of %WARP_SZ but there's currently no +// builtin to do so. According to PTX v4.2 docs 'to date, all target +// architectures have a WARP_SZ value of 32'. +__attribute__((device)) const int warpSize = 32; + +#undef __CUDA_DEVICE_BUILTIN +#undef __CUDA_BUILTIN_VAR +#undef __CUDA_DISALLOW_BUILTINVAR_ACCESS + +#endif /* __CUDA_BUILTIN_VARS_H */ diff --git a/headers/clang/emmintrin.h b/headers/clang/emmintrin.h new file mode 100644 index 0000000000..47eaf091e1 --- /dev/null +++ b/headers/clang/emmintrin.h @@ -0,0 +1,1491 @@ +/*===---- emmintrin.h - SSE2 intrinsics ------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __EMMINTRIN_H +#define __EMMINTRIN_H + +#include + +typedef double __m128d __attribute__((__vector_size__(16))); +typedef long long __m128i __attribute__((__vector_size__(16))); + +/* Type defines. */ +typedef double __v2df __attribute__ ((__vector_size__ (16))); +typedef long long __v2di __attribute__ ((__vector_size__ (16))); +typedef short __v8hi __attribute__((__vector_size__(16))); +typedef char __v16qi __attribute__((__vector_size__(16))); + +/* We need an explicitly signed variant for char. Note that this shouldn't + * appear in the interface though. */ +typedef signed char __v16qs __attribute__((__vector_size__(16))); + +#include + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("sse2"))) + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_add_sd(__m128d __a, __m128d __b) +{ + __a[0] += __b[0]; + return __a; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_add_pd(__m128d __a, __m128d __b) +{ + return __a + __b; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_sub_sd(__m128d __a, __m128d __b) +{ + __a[0] -= __b[0]; + return __a; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_sub_pd(__m128d __a, __m128d __b) +{ + return __a - __b; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mul_sd(__m128d __a, __m128d __b) +{ + __a[0] *= __b[0]; + return __a; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_mul_pd(__m128d __a, __m128d __b) +{ + return __a * __b; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_div_sd(__m128d __a, __m128d __b) +{ + __a[0] /= __b[0]; + return __a; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_div_pd(__m128d __a, __m128d __b) +{ + return __a / __b; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_sqrt_sd(__m128d __a, __m128d __b) +{ + __m128d __c = __builtin_ia32_sqrtsd(__b); + return (__m128d) { __c[0], __a[1] }; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_sqrt_pd(__m128d __a) +{ + return __builtin_ia32_sqrtpd(__a); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_min_sd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_minsd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_min_pd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_minpd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_max_sd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_maxsd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_max_pd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_maxpd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_and_pd(__m128d __a, __m128d __b) +{ + return (__m128d)((__v4si)__a & (__v4si)__b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_andnot_pd(__m128d __a, __m128d __b) +{ + return (__m128d)(~(__v4si)__a & (__v4si)__b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_or_pd(__m128d __a, __m128d __b) +{ + return (__m128d)((__v4si)__a | (__v4si)__b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_xor_pd(__m128d __a, __m128d __b) +{ + return (__m128d)((__v4si)__a ^ (__v4si)__b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpeq_pd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpeqpd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmplt_pd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpltpd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmple_pd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmplepd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpgt_pd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpltpd(__b, __a); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpge_pd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmplepd(__b, __a); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpord_pd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpordpd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpunord_pd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpunordpd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpneq_pd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpneqpd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpnlt_pd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpnltpd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpnle_pd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpnlepd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpngt_pd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpnltpd(__b, __a); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpnge_pd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpnlepd(__b, __a); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpeq_sd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpeqsd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmplt_sd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpltsd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmple_sd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmplesd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpgt_sd(__m128d __a, __m128d __b) +{ + __m128d __c = __builtin_ia32_cmpltsd(__b, __a); + return (__m128d) { __c[0], __a[1] }; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpge_sd(__m128d __a, __m128d __b) +{ + __m128d __c = __builtin_ia32_cmplesd(__b, __a); + return (__m128d) { __c[0], __a[1] }; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpord_sd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpordsd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpunord_sd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpunordsd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpneq_sd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpneqsd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpnlt_sd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpnltsd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpnle_sd(__m128d __a, __m128d __b) +{ + return (__m128d)__builtin_ia32_cmpnlesd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpngt_sd(__m128d __a, __m128d __b) +{ + __m128d __c = __builtin_ia32_cmpnltsd(__b, __a); + return (__m128d) { __c[0], __a[1] }; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cmpnge_sd(__m128d __a, __m128d __b) +{ + __m128d __c = __builtin_ia32_cmpnlesd(__b, __a); + return (__m128d) { __c[0], __a[1] }; +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_comieq_sd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_comisdeq(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_comilt_sd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_comisdlt(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_comile_sd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_comisdle(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_comigt_sd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_comisdgt(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_comige_sd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_comisdge(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_comineq_sd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_comisdneq(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_ucomieq_sd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_ucomisdeq(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_ucomilt_sd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_ucomisdlt(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_ucomile_sd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_ucomisdle(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_ucomigt_sd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_ucomisdgt(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_ucomige_sd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_ucomisdge(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_ucomineq_sd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_ucomisdneq(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvtpd_ps(__m128d __a) +{ + return __builtin_ia32_cvtpd2ps(__a); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cvtps_pd(__m128 __a) +{ + return __builtin_ia32_cvtps2pd(__a); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cvtepi32_pd(__m128i __a) +{ + return __builtin_ia32_cvtdq2pd((__v4si)__a); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtpd_epi32(__m128d __a) +{ + return __builtin_ia32_cvtpd2dq(__a); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_cvtsd_si32(__m128d __a) +{ + return __builtin_ia32_cvtsd2si(__a); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvtsd_ss(__m128 __a, __m128d __b) +{ + __a[0] = __b[0]; + return __a; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cvtsi32_sd(__m128d __a, int __b) +{ + __a[0] = __b; + return __a; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cvtss_sd(__m128d __a, __m128 __b) +{ + __a[0] = __b[0]; + return __a; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvttpd_epi32(__m128d __a) +{ + return (__m128i)__builtin_ia32_cvttpd2dq(__a); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_cvttsd_si32(__m128d __a) +{ + return __a[0]; +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cvtpd_pi32(__m128d __a) +{ + return (__m64)__builtin_ia32_cvtpd2pi(__a); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cvttpd_pi32(__m128d __a) +{ + return (__m64)__builtin_ia32_cvttpd2pi(__a); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cvtpi32_pd(__m64 __a) +{ + return __builtin_ia32_cvtpi2pd((__v2si)__a); +} + +static __inline__ double __DEFAULT_FN_ATTRS +_mm_cvtsd_f64(__m128d __a) +{ + return __a[0]; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_load_pd(double const *__dp) +{ + return *(__m128d*)__dp; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_load1_pd(double const *__dp) +{ + struct __mm_load1_pd_struct { + double __u; + } __attribute__((__packed__, __may_alias__)); + double __u = ((struct __mm_load1_pd_struct*)__dp)->__u; + return (__m128d){ __u, __u }; +} + +#define _mm_load_pd1(dp) _mm_load1_pd(dp) + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_loadr_pd(double const *__dp) +{ + __m128d __u = *(__m128d*)__dp; + return __builtin_shufflevector(__u, __u, 1, 0); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_loadu_pd(double const *__dp) +{ + struct __loadu_pd { + __m128d __v; + } __attribute__((__packed__, __may_alias__)); + return ((struct __loadu_pd*)__dp)->__v; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_load_sd(double const *__dp) +{ + struct __mm_load_sd_struct { + double __u; + } __attribute__((__packed__, __may_alias__)); + double __u = ((struct __mm_load_sd_struct*)__dp)->__u; + return (__m128d){ __u, 0 }; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_loadh_pd(__m128d __a, double const *__dp) +{ + struct __mm_loadh_pd_struct { + double __u; + } __attribute__((__packed__, __may_alias__)); + double __u = ((struct __mm_loadh_pd_struct*)__dp)->__u; + return (__m128d){ __a[0], __u }; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_loadl_pd(__m128d __a, double const *__dp) +{ + struct __mm_loadl_pd_struct { + double __u; + } __attribute__((__packed__, __may_alias__)); + double __u = ((struct __mm_loadl_pd_struct*)__dp)->__u; + return (__m128d){ __u, __a[1] }; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_undefined_pd() +{ + return (__m128d)__builtin_ia32_undef128(); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_set_sd(double __w) +{ + return (__m128d){ __w, 0 }; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_set1_pd(double __w) +{ + return (__m128d){ __w, __w }; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_set_pd(double __w, double __x) +{ + return (__m128d){ __x, __w }; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_setr_pd(double __w, double __x) +{ + return (__m128d){ __w, __x }; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_setzero_pd(void) +{ + return (__m128d){ 0, 0 }; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_move_sd(__m128d __a, __m128d __b) +{ + return (__m128d){ __b[0], __a[1] }; +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_store_sd(double *__dp, __m128d __a) +{ + struct __mm_store_sd_struct { + double __u; + } __attribute__((__packed__, __may_alias__)); + ((struct __mm_store_sd_struct*)__dp)->__u = __a[0]; +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_store1_pd(double *__dp, __m128d __a) +{ + struct __mm_store1_pd_struct { + double __u[2]; + } __attribute__((__packed__, __may_alias__)); + ((struct __mm_store1_pd_struct*)__dp)->__u[0] = __a[0]; + ((struct __mm_store1_pd_struct*)__dp)->__u[1] = __a[0]; +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_store_pd(double *__dp, __m128d __a) +{ + *(__m128d *)__dp = __a; +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_storeu_pd(double *__dp, __m128d __a) +{ + __builtin_ia32_storeupd(__dp, __a); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_storer_pd(double *__dp, __m128d __a) +{ + __a = __builtin_shufflevector(__a, __a, 1, 0); + *(__m128d *)__dp = __a; +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_storeh_pd(double *__dp, __m128d __a) +{ + struct __mm_storeh_pd_struct { + double __u; + } __attribute__((__packed__, __may_alias__)); + ((struct __mm_storeh_pd_struct*)__dp)->__u = __a[1]; +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_storel_pd(double *__dp, __m128d __a) +{ + struct __mm_storeh_pd_struct { + double __u; + } __attribute__((__packed__, __may_alias__)); + ((struct __mm_storeh_pd_struct*)__dp)->__u = __a[0]; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_add_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)((__v16qi)__a + (__v16qi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_add_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)((__v8hi)__a + (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_add_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)((__v4si)__a + (__v4si)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_add_si64(__m64 __a, __m64 __b) +{ + return __a + __b; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_add_epi64(__m128i __a, __m128i __b) +{ + return __a + __b; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_adds_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_paddsb128((__v16qi)__a, (__v16qi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_adds_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_paddsw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_adds_epu8(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_paddusb128((__v16qi)__a, (__v16qi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_adds_epu16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_paddusw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_avg_epu8(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_pavgb128((__v16qi)__a, (__v16qi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_avg_epu16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_pavgw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_madd_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_pmaddwd128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_max_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_pmaxsw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_max_epu8(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_pmaxub128((__v16qi)__a, (__v16qi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_min_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_pminsw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_min_epu8(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_pminub128((__v16qi)__a, (__v16qi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mulhi_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_pmulhw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mulhi_epu16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_pmulhuw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mullo_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)((__v8hi)__a * (__v8hi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_mul_su32(__m64 __a, __m64 __b) +{ + return __builtin_ia32_pmuludq((__v2si)__a, (__v2si)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mul_epu32(__m128i __a, __m128i __b) +{ + return __builtin_ia32_pmuludq128((__v4si)__a, (__v4si)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sad_epu8(__m128i __a, __m128i __b) +{ + return __builtin_ia32_psadbw128((__v16qi)__a, (__v16qi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sub_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)((__v16qi)__a - (__v16qi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sub_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)((__v8hi)__a - (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sub_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)((__v4si)__a - (__v4si)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_sub_si64(__m64 __a, __m64 __b) +{ + return __a - __b; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sub_epi64(__m128i __a, __m128i __b) +{ + return __a - __b; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_subs_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_psubsb128((__v16qi)__a, (__v16qi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_subs_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_psubsw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_subs_epu8(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_psubusb128((__v16qi)__a, (__v16qi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_subs_epu16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_psubusw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_and_si128(__m128i __a, __m128i __b) +{ + return __a & __b; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_andnot_si128(__m128i __a, __m128i __b) +{ + return ~__a & __b; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_or_si128(__m128i __a, __m128i __b) +{ + return __a | __b; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_xor_si128(__m128i __a, __m128i __b) +{ + return __a ^ __b; +} + +#define _mm_slli_si128(a, imm) __extension__ ({ \ + (__m128i)__builtin_shufflevector((__v16qi)_mm_setzero_si128(), \ + (__v16qi)(__m128i)(a), \ + ((imm)&0xF0) ? 0 : 16 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 17 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 18 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 19 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 20 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 21 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 22 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 23 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 24 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 25 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 26 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 27 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 28 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 29 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 30 - ((imm)&0xF), \ + ((imm)&0xF0) ? 0 : 31 - ((imm)&0xF)); }) + +#define _mm_bslli_si128(a, imm) \ + _mm_slli_si128((a), (imm)) + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_slli_epi16(__m128i __a, int __count) +{ + return (__m128i)__builtin_ia32_psllwi128((__v8hi)__a, __count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sll_epi16(__m128i __a, __m128i __count) +{ + return (__m128i)__builtin_ia32_psllw128((__v8hi)__a, (__v8hi)__count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_slli_epi32(__m128i __a, int __count) +{ + return (__m128i)__builtin_ia32_pslldi128((__v4si)__a, __count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sll_epi32(__m128i __a, __m128i __count) +{ + return (__m128i)__builtin_ia32_pslld128((__v4si)__a, (__v4si)__count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_slli_epi64(__m128i __a, int __count) +{ + return __builtin_ia32_psllqi128(__a, __count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sll_epi64(__m128i __a, __m128i __count) +{ + return __builtin_ia32_psllq128(__a, __count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_srai_epi16(__m128i __a, int __count) +{ + return (__m128i)__builtin_ia32_psrawi128((__v8hi)__a, __count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sra_epi16(__m128i __a, __m128i __count) +{ + return (__m128i)__builtin_ia32_psraw128((__v8hi)__a, (__v8hi)__count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_srai_epi32(__m128i __a, int __count) +{ + return (__m128i)__builtin_ia32_psradi128((__v4si)__a, __count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sra_epi32(__m128i __a, __m128i __count) +{ + return (__m128i)__builtin_ia32_psrad128((__v4si)__a, (__v4si)__count); +} + +#define _mm_srli_si128(a, imm) __extension__ ({ \ + (__m128i)__builtin_shufflevector((__v16qi)(__m128i)(a), \ + (__v16qi)_mm_setzero_si128(), \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 0, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 1, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 2, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 3, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 4, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 5, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 6, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 7, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 8, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 9, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 10, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 11, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 12, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 13, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 14, \ + ((imm)&0xF0) ? 16 : ((imm)&0xF) + 15); }) + +#define _mm_bsrli_si128(a, imm) \ + _mm_srli_si128((a), (imm)) + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_srli_epi16(__m128i __a, int __count) +{ + return (__m128i)__builtin_ia32_psrlwi128((__v8hi)__a, __count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_srl_epi16(__m128i __a, __m128i __count) +{ + return (__m128i)__builtin_ia32_psrlw128((__v8hi)__a, (__v8hi)__count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_srli_epi32(__m128i __a, int __count) +{ + return (__m128i)__builtin_ia32_psrldi128((__v4si)__a, __count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_srl_epi32(__m128i __a, __m128i __count) +{ + return (__m128i)__builtin_ia32_psrld128((__v4si)__a, (__v4si)__count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_srli_epi64(__m128i __a, int __count) +{ + return __builtin_ia32_psrlqi128(__a, __count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_srl_epi64(__m128i __a, __m128i __count) +{ + return __builtin_ia32_psrlq128(__a, __count); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cmpeq_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)((__v16qi)__a == (__v16qi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cmpeq_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)((__v8hi)__a == (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cmpeq_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)((__v4si)__a == (__v4si)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cmpgt_epi8(__m128i __a, __m128i __b) +{ + /* This function always performs a signed comparison, but __v16qi is a char + which may be signed or unsigned, so use __v16qs. */ + return (__m128i)((__v16qs)__a > (__v16qs)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cmpgt_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)((__v8hi)__a > (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cmpgt_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)((__v4si)__a > (__v4si)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cmplt_epi8(__m128i __a, __m128i __b) +{ + return _mm_cmpgt_epi8(__b, __a); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cmplt_epi16(__m128i __a, __m128i __b) +{ + return _mm_cmpgt_epi16(__b, __a); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cmplt_epi32(__m128i __a, __m128i __b) +{ + return _mm_cmpgt_epi32(__b, __a); +} + +#ifdef __x86_64__ +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_cvtsi64_sd(__m128d __a, long long __b) +{ + __a[0] = __b; + return __a; +} + +static __inline__ long long __DEFAULT_FN_ATTRS +_mm_cvtsd_si64(__m128d __a) +{ + return __builtin_ia32_cvtsd2si64(__a); +} + +static __inline__ long long __DEFAULT_FN_ATTRS +_mm_cvttsd_si64(__m128d __a) +{ + return __a[0]; +} +#endif + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvtepi32_ps(__m128i __a) +{ + return __builtin_ia32_cvtdq2ps((__v4si)__a); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtps_epi32(__m128 __a) +{ + return (__m128i)__builtin_ia32_cvtps2dq(__a); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvttps_epi32(__m128 __a) +{ + return (__m128i)__builtin_ia32_cvttps2dq(__a); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtsi32_si128(int __a) +{ + return (__m128i)(__v4si){ __a, 0, 0, 0 }; +} + +#ifdef __x86_64__ +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtsi64_si128(long long __a) +{ + return (__m128i){ __a, 0 }; +} +#endif + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_cvtsi128_si32(__m128i __a) +{ + __v4si __b = (__v4si)__a; + return __b[0]; +} + +#ifdef __x86_64__ +static __inline__ long long __DEFAULT_FN_ATTRS +_mm_cvtsi128_si64(__m128i __a) +{ + return __a[0]; +} +#endif + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_load_si128(__m128i const *__p) +{ + return *__p; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_loadu_si128(__m128i const *__p) +{ + struct __loadu_si128 { + __m128i __v; + } __attribute__((__packed__, __may_alias__)); + return ((struct __loadu_si128*)__p)->__v; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_loadl_epi64(__m128i const *__p) +{ + struct __mm_loadl_epi64_struct { + long long __u; + } __attribute__((__packed__, __may_alias__)); + return (__m128i) { ((struct __mm_loadl_epi64_struct*)__p)->__u, 0}; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_undefined_si128() +{ + return (__m128i)__builtin_ia32_undef128(); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_set_epi64x(long long __q1, long long __q0) +{ + return (__m128i){ __q0, __q1 }; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_set_epi64(__m64 __q1, __m64 __q0) +{ + return (__m128i){ (long long)__q0, (long long)__q1 }; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_set_epi32(int __i3, int __i2, int __i1, int __i0) +{ + return (__m128i)(__v4si){ __i0, __i1, __i2, __i3}; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_set_epi16(short __w7, short __w6, short __w5, short __w4, short __w3, short __w2, short __w1, short __w0) +{ + return (__m128i)(__v8hi){ __w0, __w1, __w2, __w3, __w4, __w5, __w6, __w7 }; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_set_epi8(char __b15, char __b14, char __b13, char __b12, char __b11, char __b10, char __b9, char __b8, char __b7, char __b6, char __b5, char __b4, char __b3, char __b2, char __b1, char __b0) +{ + return (__m128i)(__v16qi){ __b0, __b1, __b2, __b3, __b4, __b5, __b6, __b7, __b8, __b9, __b10, __b11, __b12, __b13, __b14, __b15 }; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_set1_epi64x(long long __q) +{ + return (__m128i){ __q, __q }; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_set1_epi64(__m64 __q) +{ + return (__m128i){ (long long)__q, (long long)__q }; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_set1_epi32(int __i) +{ + return (__m128i)(__v4si){ __i, __i, __i, __i }; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_set1_epi16(short __w) +{ + return (__m128i)(__v8hi){ __w, __w, __w, __w, __w, __w, __w, __w }; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_set1_epi8(char __b) +{ + return (__m128i)(__v16qi){ __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b }; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_setr_epi64(__m64 __q0, __m64 __q1) +{ + return (__m128i){ (long long)__q0, (long long)__q1 }; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_setr_epi32(int __i0, int __i1, int __i2, int __i3) +{ + return (__m128i)(__v4si){ __i0, __i1, __i2, __i3}; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_setr_epi16(short __w0, short __w1, short __w2, short __w3, short __w4, short __w5, short __w6, short __w7) +{ + return (__m128i)(__v8hi){ __w0, __w1, __w2, __w3, __w4, __w5, __w6, __w7 }; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_setr_epi8(char __b0, char __b1, char __b2, char __b3, char __b4, char __b5, char __b6, char __b7, char __b8, char __b9, char __b10, char __b11, char __b12, char __b13, char __b14, char __b15) +{ + return (__m128i)(__v16qi){ __b0, __b1, __b2, __b3, __b4, __b5, __b6, __b7, __b8, __b9, __b10, __b11, __b12, __b13, __b14, __b15 }; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_setzero_si128(void) +{ + return (__m128i){ 0LL, 0LL }; +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_store_si128(__m128i *__p, __m128i __b) +{ + *__p = __b; +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_storeu_si128(__m128i *__p, __m128i __b) +{ + __builtin_ia32_storedqu((char *)__p, (__v16qi)__b); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_maskmoveu_si128(__m128i __d, __m128i __n, char *__p) +{ + __builtin_ia32_maskmovdqu((__v16qi)__d, (__v16qi)__n, __p); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_storel_epi64(__m128i *__p, __m128i __a) +{ + struct __mm_storel_epi64_struct { + long long __u; + } __attribute__((__packed__, __may_alias__)); + ((struct __mm_storel_epi64_struct*)__p)->__u = __a[0]; +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_stream_pd(double *__p, __m128d __a) +{ + __builtin_ia32_movntpd(__p, __a); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_stream_si128(__m128i *__p, __m128i __a) +{ + __builtin_ia32_movntdq(__p, __a); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_stream_si32(int *__p, int __a) +{ + __builtin_ia32_movnti(__p, __a); +} + +#ifdef __x86_64__ +static __inline__ void __DEFAULT_FN_ATTRS +_mm_stream_si64(long long *__p, long long __a) +{ + __builtin_ia32_movnti64(__p, __a); +} +#endif + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_clflush(void const *__p) +{ + __builtin_ia32_clflush(__p); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_lfence(void) +{ + __builtin_ia32_lfence(); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_mfence(void) +{ + __builtin_ia32_mfence(); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_packs_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_packsswb128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_packs_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_packssdw128((__v4si)__a, (__v4si)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_packus_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_packuswb128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_extract_epi16(__m128i __a, int __imm) +{ + __v8hi __b = (__v8hi)__a; + return (unsigned short)__b[__imm & 7]; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_insert_epi16(__m128i __a, int __b, int __imm) +{ + __v8hi __c = (__v8hi)__a; + __c[__imm & 7] = __b; + return (__m128i)__c; +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_movemask_epi8(__m128i __a) +{ + return __builtin_ia32_pmovmskb128((__v16qi)__a); +} + +#define _mm_shuffle_epi32(a, imm) __extension__ ({ \ + (__m128i)__builtin_shufflevector((__v4si)(__m128i)(a), \ + (__v4si)_mm_set1_epi32(0), \ + (imm) & 0x3, ((imm) & 0xc) >> 2, \ + ((imm) & 0x30) >> 4, ((imm) & 0xc0) >> 6); }) + +#define _mm_shufflelo_epi16(a, imm) __extension__ ({ \ + (__m128i)__builtin_shufflevector((__v8hi)(__m128i)(a), \ + (__v8hi)_mm_set1_epi16(0), \ + (imm) & 0x3, ((imm) & 0xc) >> 2, \ + ((imm) & 0x30) >> 4, ((imm) & 0xc0) >> 6, \ + 4, 5, 6, 7); }) + +#define _mm_shufflehi_epi16(a, imm) __extension__ ({ \ + (__m128i)__builtin_shufflevector((__v8hi)(__m128i)(a), \ + (__v8hi)_mm_set1_epi16(0), \ + 0, 1, 2, 3, \ + 4 + (((imm) & 0x03) >> 0), \ + 4 + (((imm) & 0x0c) >> 2), \ + 4 + (((imm) & 0x30) >> 4), \ + 4 + (((imm) & 0xc0) >> 6)); }) + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_unpackhi_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_shufflevector((__v16qi)__a, (__v16qi)__b, 8, 16+8, 9, 16+9, 10, 16+10, 11, 16+11, 12, 16+12, 13, 16+13, 14, 16+14, 15, 16+15); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_unpackhi_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_shufflevector((__v8hi)__a, (__v8hi)__b, 4, 8+4, 5, 8+5, 6, 8+6, 7, 8+7); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_unpackhi_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_shufflevector((__v4si)__a, (__v4si)__b, 2, 4+2, 3, 4+3); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_unpackhi_epi64(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_shufflevector(__a, __b, 1, 2+1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_unpacklo_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_shufflevector((__v16qi)__a, (__v16qi)__b, 0, 16+0, 1, 16+1, 2, 16+2, 3, 16+3, 4, 16+4, 5, 16+5, 6, 16+6, 7, 16+7); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_unpacklo_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_shufflevector((__v8hi)__a, (__v8hi)__b, 0, 8+0, 1, 8+1, 2, 8+2, 3, 8+3); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_unpacklo_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_shufflevector((__v4si)__a, (__v4si)__b, 0, 4+0, 1, 4+1); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_unpacklo_epi64(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_shufflevector(__a, __b, 0, 2+0); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_movepi64_pi64(__m128i __a) +{ + return (__m64)__a[0]; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_movpi64_epi64(__m64 __a) +{ + return (__m128i){ (long long)__a, 0 }; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_move_epi64(__m128i __a) +{ + return __builtin_shufflevector(__a, (__m128i){ 0 }, 0, 2); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_unpackhi_pd(__m128d __a, __m128d __b) +{ + return __builtin_shufflevector(__a, __b, 1, 2+1); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_unpacklo_pd(__m128d __a, __m128d __b) +{ + return __builtin_shufflevector(__a, __b, 0, 2+0); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_movemask_pd(__m128d __a) +{ + return __builtin_ia32_movmskpd(__a); +} + +#define _mm_shuffle_pd(a, b, i) __extension__ ({ \ + __builtin_shufflevector((__m128d)(a), (__m128d)(b), \ + (i) & 1, (((i) & 2) >> 1) + 2); }) + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_castpd_ps(__m128d __a) +{ + return (__m128)__a; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_castpd_si128(__m128d __a) +{ + return (__m128i)__a; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_castps_pd(__m128 __a) +{ + return (__m128d)__a; +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_castps_si128(__m128 __a) +{ + return (__m128i)__a; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_castsi128_ps(__m128i __a) +{ + return (__m128)__a; +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_castsi128_pd(__m128i __a) +{ + return (__m128d)__a; +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_pause(void) +{ + __asm__ volatile ("pause"); +} + +#undef __DEFAULT_FN_ATTRS + +#define _MM_SHUFFLE2(x, y) (((x) << 1) | (y)) + +#endif /* __EMMINTRIN_H */ diff --git a/headers/clang/f16cintrin.h b/headers/clang/f16cintrin.h new file mode 100644 index 0000000000..9fb454574a --- /dev/null +++ b/headers/clang/f16cintrin.h @@ -0,0 +1,59 @@ +/*===---- f16cintrin.h - F16C intrinsics -----------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#if !defined __X86INTRIN_H && !defined __EMMINTRIN_H && !defined __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __F16CINTRIN_H +#define __F16CINTRIN_H + +typedef float __v8sf __attribute__ ((__vector_size__ (32))); +typedef float __m256 __attribute__ ((__vector_size__ (32))); + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("f16c"))) + +#define _mm_cvtps_ph(a, imm) __extension__ ({ \ + __m128 __a = (a); \ + (__m128i)__builtin_ia32_vcvtps2ph((__v4sf)__a, (imm)); }) + +#define _mm256_cvtps_ph(a, imm) __extension__ ({ \ + __m256 __a = (a); \ + (__m128i)__builtin_ia32_vcvtps2ph256((__v8sf)__a, (imm)); }) + +static __inline __m128 __DEFAULT_FN_ATTRS +_mm_cvtph_ps(__m128i __a) +{ + return (__m128)__builtin_ia32_vcvtph2ps((__v8hi)__a); +} + +static __inline __m256 __DEFAULT_FN_ATTRS +_mm256_cvtph_ps(__m128i __a) +{ + return (__m256)__builtin_ia32_vcvtph2ps256((__v8hi)__a); +} + +#undef __DEFAULT_FN_ATTRS + +#endif /* __F16CINTRIN_H */ diff --git a/headers/clang/float.h b/headers/clang/float.h new file mode 100644 index 0000000000..238cf76b05 --- /dev/null +++ b/headers/clang/float.h @@ -0,0 +1,124 @@ +/*===---- float.h - Characteristics of floating point types ----------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __FLOAT_H +#define __FLOAT_H + +/* If we're on MinGW, fall back to the system's float.h, which might have + * additional definitions provided for Windows. + * For more details see http://msdn.microsoft.com/en-us/library/y0ybw9fy.aspx + */ +#if (defined(__MINGW32__) || defined(_MSC_VER)) && __STDC_HOSTED__ && \ + __has_include_next() +# include_next + +/* Undefine anything that we'll be redefining below. */ +# undef FLT_EVAL_METHOD +# undef FLT_ROUNDS +# undef FLT_RADIX +# undef FLT_MANT_DIG +# undef DBL_MANT_DIG +# undef LDBL_MANT_DIG +# undef DECIMAL_DIG +# undef FLT_DIG +# undef DBL_DIG +# undef LDBL_DIG +# undef FLT_MIN_EXP +# undef DBL_MIN_EXP +# undef LDBL_MIN_EXP +# undef FLT_MIN_10_EXP +# undef DBL_MIN_10_EXP +# undef LDBL_MIN_10_EXP +# undef FLT_MAX_EXP +# undef DBL_MAX_EXP +# undef LDBL_MAX_EXP +# undef FLT_MAX_10_EXP +# undef DBL_MAX_10_EXP +# undef LDBL_MAX_10_EXP +# undef FLT_MAX +# undef DBL_MAX +# undef LDBL_MAX +# undef FLT_EPSILON +# undef DBL_EPSILON +# undef LDBL_EPSILON +# undef FLT_MIN +# undef DBL_MIN +# undef LDBL_MIN +# if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) +# undef FLT_TRUE_MIN +# undef DBL_TRUE_MIN +# undef LDBL_TRUE_MIN +# endif +#endif + +/* Characteristics of floating point types, C99 5.2.4.2.2 */ + +#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ +#define FLT_ROUNDS (__builtin_flt_rounds()) +#define FLT_RADIX __FLT_RADIX__ + +#define FLT_MANT_DIG __FLT_MANT_DIG__ +#define DBL_MANT_DIG __DBL_MANT_DIG__ +#define LDBL_MANT_DIG __LDBL_MANT_DIG__ + +#define DECIMAL_DIG __DECIMAL_DIG__ + +#define FLT_DIG __FLT_DIG__ +#define DBL_DIG __DBL_DIG__ +#define LDBL_DIG __LDBL_DIG__ + +#define FLT_MIN_EXP __FLT_MIN_EXP__ +#define DBL_MIN_EXP __DBL_MIN_EXP__ +#define LDBL_MIN_EXP __LDBL_MIN_EXP__ + +#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__ +#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__ +#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__ + +#define FLT_MAX_EXP __FLT_MAX_EXP__ +#define DBL_MAX_EXP __DBL_MAX_EXP__ +#define LDBL_MAX_EXP __LDBL_MAX_EXP__ + +#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__ +#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__ +#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__ + +#define FLT_MAX __FLT_MAX__ +#define DBL_MAX __DBL_MAX__ +#define LDBL_MAX __LDBL_MAX__ + +#define FLT_EPSILON __FLT_EPSILON__ +#define DBL_EPSILON __DBL_EPSILON__ +#define LDBL_EPSILON __LDBL_EPSILON__ + +#define FLT_MIN __FLT_MIN__ +#define DBL_MIN __DBL_MIN__ +#define LDBL_MIN __LDBL_MIN__ + +#if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) +# define FLT_TRUE_MIN __FLT_DENORM_MIN__ +# define DBL_TRUE_MIN __DBL_DENORM_MIN__ +# define LDBL_TRUE_MIN __LDBL_DENORM_MIN__ +#endif + +#endif /* __FLOAT_H */ diff --git a/headers/clang/fma4intrin.h b/headers/clang/fma4intrin.h new file mode 100644 index 0000000000..f1178877b2 --- /dev/null +++ b/headers/clang/fma4intrin.h @@ -0,0 +1,230 @@ +/*===---- fma4intrin.h - FMA4 intrinsics -----------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __X86INTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __FMA4INTRIN_H +#define __FMA4INTRIN_H + +#include + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("fma4"))) + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_macc_ps(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfmaddps(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_macc_pd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfmaddpd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_macc_ss(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfmaddss(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_macc_sd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfmaddsd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_msub_ps(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfmsubps(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_msub_pd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfmsubpd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_msub_ss(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfmsubss(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_msub_sd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfmsubsd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_nmacc_ps(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfnmaddps(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_nmacc_pd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfnmaddpd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_nmacc_ss(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfnmaddss(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_nmacc_sd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfnmaddsd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_nmsub_ps(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfnmsubps(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_nmsub_pd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfnmsubpd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_nmsub_ss(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfnmsubss(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_nmsub_sd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfnmsubsd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_maddsub_ps(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfmaddsubps(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_maddsub_pd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfmaddsubpd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_msubadd_ps(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfmsubaddps(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_msubadd_pd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfmsubaddpd(__A, __B, __C); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_macc_ps(__m256 __A, __m256 __B, __m256 __C) +{ + return (__m256)__builtin_ia32_vfmaddps256(__A, __B, __C); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_macc_pd(__m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d)__builtin_ia32_vfmaddpd256(__A, __B, __C); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_msub_ps(__m256 __A, __m256 __B, __m256 __C) +{ + return (__m256)__builtin_ia32_vfmsubps256(__A, __B, __C); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_msub_pd(__m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d)__builtin_ia32_vfmsubpd256(__A, __B, __C); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_nmacc_ps(__m256 __A, __m256 __B, __m256 __C) +{ + return (__m256)__builtin_ia32_vfnmaddps256(__A, __B, __C); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_nmacc_pd(__m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d)__builtin_ia32_vfnmaddpd256(__A, __B, __C); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_nmsub_ps(__m256 __A, __m256 __B, __m256 __C) +{ + return (__m256)__builtin_ia32_vfnmsubps256(__A, __B, __C); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_nmsub_pd(__m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d)__builtin_ia32_vfnmsubpd256(__A, __B, __C); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_maddsub_ps(__m256 __A, __m256 __B, __m256 __C) +{ + return (__m256)__builtin_ia32_vfmaddsubps256(__A, __B, __C); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_maddsub_pd(__m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d)__builtin_ia32_vfmaddsubpd256(__A, __B, __C); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_msubadd_ps(__m256 __A, __m256 __B, __m256 __C) +{ + return (__m256)__builtin_ia32_vfmsubaddps256(__A, __B, __C); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_msubadd_pd(__m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d)__builtin_ia32_vfmsubaddpd256(__A, __B, __C); +} + +#undef __DEFAULT_FN_ATTRS + +#endif /* __FMA4INTRIN_H */ diff --git a/headers/clang/fmaintrin.h b/headers/clang/fmaintrin.h new file mode 100644 index 0000000000..114a14380e --- /dev/null +++ b/headers/clang/fmaintrin.h @@ -0,0 +1,228 @@ +/*===---- fma4intrin.h - FMA4 intrinsics -----------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __FMAINTRIN_H +#define __FMAINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("fma"))) + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_fmadd_ps(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfmaddps(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_fmadd_pd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfmaddpd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_fmadd_ss(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfmaddss(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_fmadd_sd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfmaddsd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_fmsub_ps(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfmsubps(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_fmsub_pd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfmsubpd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_fmsub_ss(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfmsubss(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_fmsub_sd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfmsubsd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_fnmadd_ps(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfnmaddps(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_fnmadd_pd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfnmaddpd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_fnmadd_ss(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfnmaddss(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_fnmadd_sd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfnmaddsd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_fnmsub_ps(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfnmsubps(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_fnmsub_pd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfnmsubpd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_fnmsub_ss(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfnmsubss(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_fnmsub_sd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfnmsubsd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_fmaddsub_ps(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfmaddsubps(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_fmaddsub_pd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfmaddsubpd(__A, __B, __C); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_fmsubadd_ps(__m128 __A, __m128 __B, __m128 __C) +{ + return (__m128)__builtin_ia32_vfmsubaddps(__A, __B, __C); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_fmsubadd_pd(__m128d __A, __m128d __B, __m128d __C) +{ + return (__m128d)__builtin_ia32_vfmsubaddpd(__A, __B, __C); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_fmadd_ps(__m256 __A, __m256 __B, __m256 __C) +{ + return (__m256)__builtin_ia32_vfmaddps256(__A, __B, __C); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_fmadd_pd(__m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d)__builtin_ia32_vfmaddpd256(__A, __B, __C); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_fmsub_ps(__m256 __A, __m256 __B, __m256 __C) +{ + return (__m256)__builtin_ia32_vfmsubps256(__A, __B, __C); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_fmsub_pd(__m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d)__builtin_ia32_vfmsubpd256(__A, __B, __C); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_fnmadd_ps(__m256 __A, __m256 __B, __m256 __C) +{ + return (__m256)__builtin_ia32_vfnmaddps256(__A, __B, __C); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_fnmadd_pd(__m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d)__builtin_ia32_vfnmaddpd256(__A, __B, __C); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_fnmsub_ps(__m256 __A, __m256 __B, __m256 __C) +{ + return (__m256)__builtin_ia32_vfnmsubps256(__A, __B, __C); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_fnmsub_pd(__m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d)__builtin_ia32_vfnmsubpd256(__A, __B, __C); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_fmaddsub_ps(__m256 __A, __m256 __B, __m256 __C) +{ + return (__m256)__builtin_ia32_vfmaddsubps256(__A, __B, __C); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_fmaddsub_pd(__m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d)__builtin_ia32_vfmaddsubpd256(__A, __B, __C); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_fmsubadd_ps(__m256 __A, __m256 __B, __m256 __C) +{ + return (__m256)__builtin_ia32_vfmsubaddps256(__A, __B, __C); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_fmsubadd_pd(__m256d __A, __m256d __B, __m256d __C) +{ + return (__m256d)__builtin_ia32_vfmsubaddpd256(__A, __B, __C); +} + +#undef __DEFAULT_FN_ATTRS + +#endif /* __FMAINTRIN_H */ diff --git a/headers/clang/fxsrintrin.h b/headers/clang/fxsrintrin.h new file mode 100644 index 0000000000..ac6026aa5b --- /dev/null +++ b/headers/clang/fxsrintrin.h @@ -0,0 +1,55 @@ +/*===---- fxsrintrin.h - FXSR intrinsic ------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __FXSRINTRIN_H +#define __FXSRINTRIN_H + +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("fxsr"))) + +static __inline__ void __DEFAULT_FN_ATTRS +_fxsave(void *__p) { + return __builtin_ia32_fxsave(__p); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_fxsave64(void *__p) { + return __builtin_ia32_fxsave64(__p); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_fxrstor(void *__p) { + return __builtin_ia32_fxrstor(__p); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_fxrstor64(void *__p) { + return __builtin_ia32_fxrstor64(__p); +} + +#undef __DEFAULT_FN_ATTRS + +#endif diff --git a/headers/clang/htmintrin.h b/headers/clang/htmintrin.h new file mode 100644 index 0000000000..0088c7ccab --- /dev/null +++ b/headers/clang/htmintrin.h @@ -0,0 +1,226 @@ +/*===---- htmintrin.h - Standard header for PowerPC HTM ---------------===*\ + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * +\*===----------------------------------------------------------------------===*/ + +#ifndef __HTMINTRIN_H +#define __HTMINTRIN_H + +#ifndef __HTM__ +#error "HTM instruction set not enabled" +#endif + +#ifdef __powerpc__ + +#include + +typedef uint64_t texasr_t; +typedef uint32_t texasru_t; +typedef uint32_t texasrl_t; +typedef uintptr_t tfiar_t; +typedef uintptr_t tfhar_t; + +#define _HTM_STATE(CR0) ((CR0 >> 1) & 0x3) +#define _HTM_NONTRANSACTIONAL 0x0 +#define _HTM_SUSPENDED 0x1 +#define _HTM_TRANSACTIONAL 0x2 + +#define _TEXASR_EXTRACT_BITS(TEXASR,BITNUM,SIZE) \ + (((TEXASR) >> (63-(BITNUM))) & ((1<<(SIZE))-1)) +#define _TEXASRU_EXTRACT_BITS(TEXASR,BITNUM,SIZE) \ + (((TEXASR) >> (31-(BITNUM))) & ((1<<(SIZE))-1)) + +#define _TEXASR_FAILURE_CODE(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 7, 8) +#define _TEXASRU_FAILURE_CODE(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 7, 8) + +#define _TEXASR_FAILURE_PERSISTENT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 7, 1) +#define _TEXASRU_FAILURE_PERSISTENT(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 7, 1) + +#define _TEXASR_DISALLOWED(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 8, 1) +#define _TEXASRU_DISALLOWED(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 8, 1) + +#define _TEXASR_NESTING_OVERFLOW(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 9, 1) +#define _TEXASRU_NESTING_OVERFLOW(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 9, 1) + +#define _TEXASR_FOOTPRINT_OVERFLOW(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 10, 1) +#define _TEXASRU_FOOTPRINT_OVERFLOW(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 10, 1) + +#define _TEXASR_SELF_INDUCED_CONFLICT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 11, 1) +#define _TEXASRU_SELF_INDUCED_CONFLICT(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 11, 1) + +#define _TEXASR_NON_TRANSACTIONAL_CONFLICT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 12, 1) +#define _TEXASRU_NON_TRANSACTIONAL_CONFLICT(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 12, 1) + +#define _TEXASR_TRANSACTION_CONFLICT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 13, 1) +#define _TEXASRU_TRANSACTION_CONFLICT(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 13, 1) + +#define _TEXASR_TRANSLATION_INVALIDATION_CONFLICT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 14, 1) +#define _TEXASRU_TRANSLATION_INVALIDATION_CONFLICT(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 14, 1) + +#define _TEXASR_IMPLEMENTAION_SPECIFIC(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 15, 1) +#define _TEXASRU_IMPLEMENTAION_SPECIFIC(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 15, 1) + +#define _TEXASR_INSTRUCTION_FETCH_CONFLICT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 16, 1) +#define _TEXASRU_INSTRUCTION_FETCH_CONFLICT(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 16, 1) + +#define _TEXASR_ABORT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 31, 1) +#define _TEXASRU_ABORT(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 31, 1) + + +#define _TEXASR_SUSPENDED(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 32, 1) + +#define _TEXASR_PRIVILEGE(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 35, 2) + +#define _TEXASR_FAILURE_SUMMARY(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 36, 1) + +#define _TEXASR_TFIAR_EXACT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 37, 1) + +#define _TEXASR_ROT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 38, 1) + +#define _TEXASR_TRANSACTION_LEVEL(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 63, 12) + +#endif /* __powerpc */ + +#ifdef __s390__ + +/* Condition codes generated by tbegin */ +#define _HTM_TBEGIN_STARTED 0 +#define _HTM_TBEGIN_INDETERMINATE 1 +#define _HTM_TBEGIN_TRANSIENT 2 +#define _HTM_TBEGIN_PERSISTENT 3 + +/* The abort codes below this threshold are reserved for machine use. */ +#define _HTM_FIRST_USER_ABORT_CODE 256 + +/* The transaction diagnostic block is it is defined in the Principles + of Operation chapter 5-91. */ + +struct __htm_tdb { + unsigned char format; /* 0 */ + unsigned char flags; + unsigned char reserved1[4]; + unsigned short nesting_depth; + unsigned long long abort_code; /* 8 */ + unsigned long long conflict_token; /* 16 */ + unsigned long long atia; /* 24 */ + unsigned char eaid; /* 32 */ + unsigned char dxc; + unsigned char reserved2[2]; + unsigned int program_int_id; + unsigned long long exception_id; /* 40 */ + unsigned long long bea; /* 48 */ + unsigned char reserved3[72]; /* 56 */ + unsigned long long gprs[16]; /* 128 */ +} __attribute__((__packed__, __aligned__ (8))); + + +/* Helper intrinsics to retry tbegin in case of transient failure. */ + +static __inline int __attribute__((__always_inline__, __nodebug__)) +__builtin_tbegin_retry_null (int retry) +{ + int cc, i = 0; + + while ((cc = __builtin_tbegin(0)) == _HTM_TBEGIN_TRANSIENT + && i++ < retry) + __builtin_tx_assist(i); + + return cc; +} + +static __inline int __attribute__((__always_inline__, __nodebug__)) +__builtin_tbegin_retry_tdb (void *tdb, int retry) +{ + int cc, i = 0; + + while ((cc = __builtin_tbegin(tdb)) == _HTM_TBEGIN_TRANSIENT + && i++ < retry) + __builtin_tx_assist(i); + + return cc; +} + +#define __builtin_tbegin_retry(tdb, retry) \ + (__builtin_constant_p(tdb == 0) && tdb == 0 ? \ + __builtin_tbegin_retry_null(retry) : \ + __builtin_tbegin_retry_tdb(tdb, retry)) + +static __inline int __attribute__((__always_inline__, __nodebug__)) +__builtin_tbegin_retry_nofloat_null (int retry) +{ + int cc, i = 0; + + while ((cc = __builtin_tbegin_nofloat(0)) == _HTM_TBEGIN_TRANSIENT + && i++ < retry) + __builtin_tx_assist(i); + + return cc; +} + +static __inline int __attribute__((__always_inline__, __nodebug__)) +__builtin_tbegin_retry_nofloat_tdb (void *tdb, int retry) +{ + int cc, i = 0; + + while ((cc = __builtin_tbegin_nofloat(tdb)) == _HTM_TBEGIN_TRANSIENT + && i++ < retry) + __builtin_tx_assist(i); + + return cc; +} + +#define __builtin_tbegin_retry_nofloat(tdb, retry) \ + (__builtin_constant_p(tdb == 0) && tdb == 0 ? \ + __builtin_tbegin_retry_nofloat_null(retry) : \ + __builtin_tbegin_retry_nofloat_tdb(tdb, retry)) + +#endif /* __s390__ */ + +#endif /* __HTMINTRIN_H */ diff --git a/headers/clang/htmxlintrin.h b/headers/clang/htmxlintrin.h new file mode 100644 index 0000000000..c7571ecd06 --- /dev/null +++ b/headers/clang/htmxlintrin.h @@ -0,0 +1,363 @@ +/*===---- htmxlintrin.h - XL compiler HTM execution intrinsics-------------===*\ + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * +\*===----------------------------------------------------------------------===*/ + +#ifndef __HTMXLINTRIN_H +#define __HTMXLINTRIN_H + +#ifndef __HTM__ +#error "HTM instruction set not enabled" +#endif + +#include + +#ifdef __powerpc__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define _TEXASR_PTR(TM_BUF) \ + ((texasr_t *)((TM_BUF)+0)) +#define _TEXASRU_PTR(TM_BUF) \ + ((texasru_t *)((TM_BUF)+0)) +#define _TEXASRL_PTR(TM_BUF) \ + ((texasrl_t *)((TM_BUF)+4)) +#define _TFIAR_PTR(TM_BUF) \ + ((tfiar_t *)((TM_BUF)+8)) + +typedef char TM_buff_type[16]; + +/* This macro can be used to determine whether a transaction was successfully + started from the __TM_begin() and __TM_simple_begin() intrinsic functions + below. */ +#define _HTM_TBEGIN_STARTED 1 + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_simple_begin (void) +{ + if (__builtin_expect (__builtin_tbegin (0), 1)) + return _HTM_TBEGIN_STARTED; + return 0; +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_begin (void* const TM_buff) +{ + *_TEXASRL_PTR (TM_buff) = 0; + if (__builtin_expect (__builtin_tbegin (0), 1)) + return _HTM_TBEGIN_STARTED; +#ifdef __powerpc64__ + *_TEXASR_PTR (TM_buff) = __builtin_get_texasr (); +#else + *_TEXASRU_PTR (TM_buff) = __builtin_get_texasru (); + *_TEXASRL_PTR (TM_buff) = __builtin_get_texasr (); +#endif + *_TFIAR_PTR (TM_buff) = __builtin_get_tfiar (); + return 0; +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_end (void) +{ + if (__builtin_expect (__builtin_tend (0), 1)) + return 1; + return 0; +} + +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_abort (void) +{ + __builtin_tabort (0); +} + +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_named_abort (unsigned char const code) +{ + __builtin_tabort (code); +} + +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_resume (void) +{ + __builtin_tresume (); +} + +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_suspend (void) +{ + __builtin_tsuspend (); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_user_abort (void* const TM_buff) +{ + texasru_t texasru = *_TEXASRU_PTR (TM_buff); + return _TEXASRU_ABORT (texasru); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_named_user_abort (void* const TM_buff, unsigned char *code) +{ + texasru_t texasru = *_TEXASRU_PTR (TM_buff); + + *code = _TEXASRU_FAILURE_CODE (texasru); + return _TEXASRU_ABORT (texasru); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_illegal (void* const TM_buff) +{ + texasru_t texasru = *_TEXASRU_PTR (TM_buff); + return _TEXASRU_DISALLOWED (texasru); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_footprint_exceeded (void* const TM_buff) +{ + texasru_t texasru = *_TEXASRU_PTR (TM_buff); + return _TEXASRU_FOOTPRINT_OVERFLOW (texasru); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_nesting_depth (void* const TM_buff) +{ + texasrl_t texasrl; + + if (_HTM_STATE (__builtin_ttest ()) == _HTM_NONTRANSACTIONAL) + { + texasrl = *_TEXASRL_PTR (TM_buff); + if (!_TEXASR_FAILURE_SUMMARY (texasrl)) + texasrl = 0; + } + else + texasrl = (texasrl_t) __builtin_get_texasr (); + + return _TEXASR_TRANSACTION_LEVEL (texasrl); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_nested_too_deep(void* const TM_buff) +{ + texasru_t texasru = *_TEXASRU_PTR (TM_buff); + return _TEXASRU_NESTING_OVERFLOW (texasru); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_conflict(void* const TM_buff) +{ + texasru_t texasru = *_TEXASRU_PTR (TM_buff); + /* Return TEXASR bits 11 (Self-Induced Conflict) through + 14 (Translation Invalidation Conflict). */ + return (_TEXASRU_EXTRACT_BITS (texasru, 14, 4)) ? 1 : 0; +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_failure_persistent(void* const TM_buff) +{ + texasru_t texasru = *_TEXASRU_PTR (TM_buff); + return _TEXASRU_FAILURE_PERSISTENT (texasru); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_failure_address(void* const TM_buff) +{ + return *_TFIAR_PTR (TM_buff); +} + +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_failure_code(void* const TM_buff) +{ + return *_TEXASR_PTR (TM_buff); +} + +#ifdef __cplusplus +} +#endif + +#endif /* __powerpc__ */ + +#ifdef __s390__ + +#include + +/* These intrinsics are being made available for compatibility with + the IBM XL compiler. For documentation please see the "z/OS XL + C/C++ Programming Guide" publically available on the web. */ + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_simple_begin () +{ + return __builtin_tbegin_nofloat (0); +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_begin (void* const tdb) +{ + return __builtin_tbegin_nofloat (tdb); +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_end () +{ + return __builtin_tend (); +} + +static __inline void __attribute__((__always_inline__)) +__TM_abort () +{ + return __builtin_tabort (_HTM_FIRST_USER_ABORT_CODE); +} + +static __inline void __attribute__((__always_inline__, __nodebug__)) +__TM_named_abort (unsigned char const code) +{ + return __builtin_tabort ((int)_HTM_FIRST_USER_ABORT_CODE + code); +} + +static __inline void __attribute__((__always_inline__, __nodebug__)) +__TM_non_transactional_store (void* const addr, long long const value) +{ + __builtin_non_tx_store ((uint64_t*)addr, (uint64_t)value); +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_nesting_depth (void* const tdb_ptr) +{ + int depth = __builtin_tx_nesting_depth (); + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + if (depth != 0) + return depth; + + if (tdb->format != 1) + return 0; + return tdb->nesting_depth; +} + +/* Transaction failure diagnostics */ + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_is_user_abort (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + if (tdb->format != 1) + return 0; + + return !!(tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE); +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_is_named_user_abort (void* const tdb_ptr, unsigned char* code) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + if (tdb->format != 1) + return 0; + + if (tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE) + { + *code = tdb->abort_code - _HTM_FIRST_USER_ABORT_CODE; + return 1; + } + return 0; +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_is_illegal (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return (tdb->format == 1 + && (tdb->abort_code == 4 /* unfiltered program interruption */ + || tdb->abort_code == 11 /* restricted instruction */)); +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_is_footprint_exceeded (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return (tdb->format == 1 + && (tdb->abort_code == 7 /* fetch overflow */ + || tdb->abort_code == 8 /* store overflow */)); +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_is_nested_too_deep (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return tdb->format == 1 && tdb->abort_code == 13; /* depth exceeded */ +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_is_conflict (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return (tdb->format == 1 + && (tdb->abort_code == 9 /* fetch conflict */ + || tdb->abort_code == 10 /* store conflict */)); +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_is_failure_persistent (long const result) +{ + return result == _HTM_TBEGIN_PERSISTENT; +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_failure_address (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + return tdb->atia; +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_failure_code (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return tdb->abort_code; +} + +#endif /* __s390__ */ + +#endif /* __HTMXLINTRIN_H */ diff --git a/headers/clang/ia32intrin.h b/headers/clang/ia32intrin.h new file mode 100644 index 0000000000..5adf3f1f5d --- /dev/null +++ b/headers/clang/ia32intrin.h @@ -0,0 +1,101 @@ +/* ===-------- ia32intrin.h ---------------------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __X86INTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __IA32INTRIN_H +#define __IA32INTRIN_H + +#ifdef __x86_64__ +static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) +__readeflags(void) +{ + unsigned long long __res = 0; + __asm__ __volatile__ ("pushf\n\t" + "popq %0\n" + :"=r"(__res) + : + : + ); + return __res; +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +__writeeflags(unsigned long long __f) +{ + __asm__ __volatile__ ("pushq %0\n\t" + "popf\n" + : + :"r"(__f) + :"flags" + ); +} + +#else /* !__x86_64__ */ +static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__)) +__readeflags(void) +{ + unsigned int __res = 0; + __asm__ __volatile__ ("pushf\n\t" + "popl %0\n" + :"=r"(__res) + : + : + ); + return __res; +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +__writeeflags(unsigned int __f) +{ + __asm__ __volatile__ ("pushl %0\n\t" + "popf\n" + : + :"r"(__f) + :"flags" + ); +} +#endif /* !__x86_64__ */ + +static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) +__rdpmc(int __A) { + return __builtin_ia32_rdpmc(__A); +} + +/* __rdtsc */ +static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) +__rdtsc(void) { + return __builtin_ia32_rdtsc(); +} + +/* __rdtscp */ +static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__)) +__rdtscp(unsigned int *__A) { + return __builtin_ia32_rdtscp(__A); +} + +#define _rdtsc() __rdtsc() + +#endif /* __IA32INTRIN_H */ diff --git a/headers/clang/immintrin.h b/headers/clang/immintrin.h new file mode 100644 index 0000000000..a28222b79e --- /dev/null +++ b/headers/clang/immintrin.h @@ -0,0 +1,159 @@ +/*===---- immintrin.h - Intel intrinsics -----------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#define __IMMINTRIN_H + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +static __inline__ int __attribute__((__always_inline__, __nodebug__, __target__("rdrnd"))) +_rdrand16_step(unsigned short *__p) +{ + return __builtin_ia32_rdrand16_step(__p); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__, __target__("rdrnd"))) +_rdrand32_step(unsigned int *__p) +{ + return __builtin_ia32_rdrand32_step(__p); +} + +#ifdef __x86_64__ +static __inline__ int __attribute__((__always_inline__, __nodebug__, __target__("rdrnd"))) +_rdrand64_step(unsigned long long *__p) +{ + return __builtin_ia32_rdrand64_step(__p); +} +#endif + +#ifdef __x86_64__ +static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase"))) +_readfsbase_u32(void) +{ + return __builtin_ia32_rdfsbase32(); +} + +static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase"))) +_readfsbase_u64(void) +{ + return __builtin_ia32_rdfsbase64(); +} + +static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase"))) +_readgsbase_u32(void) +{ + return __builtin_ia32_rdgsbase32(); +} + +static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase"))) +_readgsbase_u64(void) +{ + return __builtin_ia32_rdgsbase64(); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase"))) +_writefsbase_u32(unsigned int __V) +{ + return __builtin_ia32_wrfsbase32(__V); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase"))) +_writefsbase_u64(unsigned long long __V) +{ + return __builtin_ia32_wrfsbase64(__V); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase"))) +_writegsbase_u32(unsigned int __V) +{ + return __builtin_ia32_wrgsbase32(__V); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase"))) +_writegsbase_u64(unsigned long long __V) +{ + return __builtin_ia32_wrgsbase64(__V); +} +#endif + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +/* Some intrinsics inside adxintrin.h are available only on processors with ADX, + * whereas others are also available at all times. */ +#include + +#endif /* __IMMINTRIN_H */ diff --git a/headers/clang/inttypes.h b/headers/clang/inttypes.h new file mode 100644 index 0000000000..3d59d141de --- /dev/null +++ b/headers/clang/inttypes.h @@ -0,0 +1,102 @@ +/*===---- inttypes.h - Standard header for integer printf macros ----------===*\ + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * +\*===----------------------------------------------------------------------===*/ + +#ifndef __CLANG_INTTYPES_H +#define __CLANG_INTTYPES_H + +#include_next + +#if defined(_MSC_VER) && _MSC_VER < 1900 +/* MSVC headers define int32_t as int, but PRIx32 as "lx" instead of "x". + * This triggers format warnings, so fix it up here. */ +#undef PRId32 +#undef PRIdLEAST32 +#undef PRIdFAST32 +#undef PRIi32 +#undef PRIiLEAST32 +#undef PRIiFAST32 +#undef PRIo32 +#undef PRIoLEAST32 +#undef PRIoFAST32 +#undef PRIu32 +#undef PRIuLEAST32 +#undef PRIuFAST32 +#undef PRIx32 +#undef PRIxLEAST32 +#undef PRIxFAST32 +#undef PRIX32 +#undef PRIXLEAST32 +#undef PRIXFAST32 + +#undef SCNd32 +#undef SCNdLEAST32 +#undef SCNdFAST32 +#undef SCNi32 +#undef SCNiLEAST32 +#undef SCNiFAST32 +#undef SCNo32 +#undef SCNoLEAST32 +#undef SCNoFAST32 +#undef SCNu32 +#undef SCNuLEAST32 +#undef SCNuFAST32 +#undef SCNx32 +#undef SCNxLEAST32 +#undef SCNxFAST32 + +#define PRId32 "d" +#define PRIdLEAST32 "d" +#define PRIdFAST32 "d" +#define PRIi32 "i" +#define PRIiLEAST32 "i" +#define PRIiFAST32 "i" +#define PRIo32 "o" +#define PRIoLEAST32 "o" +#define PRIoFAST32 "o" +#define PRIu32 "u" +#define PRIuLEAST32 "u" +#define PRIuFAST32 "u" +#define PRIx32 "x" +#define PRIxLEAST32 "x" +#define PRIxFAST32 "x" +#define PRIX32 "X" +#define PRIXLEAST32 "X" +#define PRIXFAST32 "X" + +#define SCNd32 "d" +#define SCNdLEAST32 "d" +#define SCNdFAST32 "d" +#define SCNi32 "i" +#define SCNiLEAST32 "i" +#define SCNiFAST32 "i" +#define SCNo32 "o" +#define SCNoLEAST32 "o" +#define SCNoFAST32 "o" +#define SCNu32 "u" +#define SCNuLEAST32 "u" +#define SCNuFAST32 "u" +#define SCNx32 "x" +#define SCNxLEAST32 "x" +#define SCNxFAST32 "x" +#endif + +#endif /* __CLANG_INTTYPES_H */ diff --git a/headers/clang/iso646.h b/headers/clang/iso646.h new file mode 100644 index 0000000000..dca13c5bab --- /dev/null +++ b/headers/clang/iso646.h @@ -0,0 +1,43 @@ +/*===---- iso646.h - Standard header for alternate spellings of operators---=== + * + * Copyright (c) 2008 Eli Friedman + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __ISO646_H +#define __ISO646_H + +#ifndef __cplusplus +#define and && +#define and_eq &= +#define bitand & +#define bitor | +#define compl ~ +#define not ! +#define not_eq != +#define or || +#define or_eq |= +#define xor ^ +#define xor_eq ^= +#endif + +#endif /* __ISO646_H */ diff --git a/headers/clang/limits.h b/headers/clang/limits.h new file mode 100644 index 0000000000..f04187ced2 --- /dev/null +++ b/headers/clang/limits.h @@ -0,0 +1,118 @@ +/*===---- limits.h - Standard header for integer sizes --------------------===*\ + * + * Copyright (c) 2009 Chris Lattner + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * +\*===----------------------------------------------------------------------===*/ + +#ifndef __CLANG_LIMITS_H +#define __CLANG_LIMITS_H + +/* The system's limits.h may, in turn, try to #include_next GCC's limits.h. + Avert this #include_next madness. */ +#if defined __GNUC__ && !defined _GCC_LIMITS_H_ +#define _GCC_LIMITS_H_ +#endif + +/* System headers include a number of constants from POSIX in . + Include it if we're hosted. */ +#if __STDC_HOSTED__ && __has_include_next() +#include_next +#endif + +/* Many system headers try to "help us out" by defining these. No really, we + know how big each datatype is. */ +#undef SCHAR_MIN +#undef SCHAR_MAX +#undef UCHAR_MAX +#undef SHRT_MIN +#undef SHRT_MAX +#undef USHRT_MAX +#undef INT_MIN +#undef INT_MAX +#undef UINT_MAX +#undef LONG_MIN +#undef LONG_MAX +#undef ULONG_MAX + +#undef CHAR_BIT +#undef CHAR_MIN +#undef CHAR_MAX + +/* C90/99 5.2.4.2.1 */ +#define SCHAR_MAX __SCHAR_MAX__ +#define SHRT_MAX __SHRT_MAX__ +#define INT_MAX __INT_MAX__ +#define LONG_MAX __LONG_MAX__ + +#define SCHAR_MIN (-__SCHAR_MAX__-1) +#define SHRT_MIN (-__SHRT_MAX__ -1) +#define INT_MIN (-__INT_MAX__ -1) +#define LONG_MIN (-__LONG_MAX__ -1L) + +#define UCHAR_MAX (__SCHAR_MAX__*2 +1) +#define USHRT_MAX (__SHRT_MAX__ *2 +1) +#define UINT_MAX (__INT_MAX__ *2U +1U) +#define ULONG_MAX (__LONG_MAX__ *2UL+1UL) + +#ifndef MB_LEN_MAX +#define MB_LEN_MAX 1 +#endif + +#define CHAR_BIT __CHAR_BIT__ + +#ifdef __CHAR_UNSIGNED__ /* -funsigned-char */ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX __SCHAR_MAX__ +#endif + +/* C99 5.2.4.2.1: Added long long. + C++11 18.3.3.2: same contents as the Standard C Library header . + */ +#if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L + +#undef LLONG_MIN +#undef LLONG_MAX +#undef ULLONG_MAX + +#define LLONG_MAX __LONG_LONG_MAX__ +#define LLONG_MIN (-__LONG_LONG_MAX__-1LL) +#define ULLONG_MAX (__LONG_LONG_MAX__*2ULL+1ULL) +#endif + +/* LONG_LONG_MIN/LONG_LONG_MAX/ULONG_LONG_MAX are a GNU extension. It's too bad + that we don't have something like #pragma poison that could be used to + deprecate a macro - the code should just use LLONG_MAX and friends. + */ +#if defined(__GNU_LIBRARY__) ? defined(__USE_GNU) : !defined(__STRICT_ANSI__) + +#undef LONG_LONG_MIN +#undef LONG_LONG_MAX +#undef ULONG_LONG_MAX + +#define LONG_LONG_MAX __LONG_LONG_MAX__ +#define LONG_LONG_MIN (-__LONG_LONG_MAX__-1LL) +#define ULONG_LONG_MAX (__LONG_LONG_MAX__*2ULL+1ULL) +#endif + +#endif /* __CLANG_LIMITS_H */ diff --git a/headers/clang/lzcntintrin.h b/headers/clang/lzcntintrin.h new file mode 100644 index 0000000000..4c00e42ac3 --- /dev/null +++ b/headers/clang/lzcntintrin.h @@ -0,0 +1,68 @@ +/*===---- lzcntintrin.h - LZCNT intrinsics ---------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __LZCNTINTRIN_H +#define __LZCNTINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("lzcnt"))) + +static __inline__ unsigned short __DEFAULT_FN_ATTRS +__lzcnt16(unsigned short __X) +{ + return __X ? __builtin_clzs(__X) : 16; +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__lzcnt32(unsigned int __X) +{ + return __X ? __builtin_clz(__X) : 32; +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +_lzcnt_u32(unsigned int __X) +{ + return __X ? __builtin_clz(__X) : 32; +} + +#ifdef __x86_64__ +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__lzcnt64(unsigned long long __X) +{ + return __X ? __builtin_clzll(__X) : 64; +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +_lzcnt_u64(unsigned long long __X) +{ + return __X ? __builtin_clzll(__X) : 64; +} +#endif + +#undef __DEFAULT_FN_ATTRS + +#endif /* __LZCNTINTRIN_H */ diff --git a/headers/clang/mm3dnow.h b/headers/clang/mm3dnow.h new file mode 100644 index 0000000000..cb93faf2b6 --- /dev/null +++ b/headers/clang/mm3dnow.h @@ -0,0 +1,171 @@ +/*===---- mm3dnow.h - 3DNow! intrinsics ------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef _MM3DNOW_H_INCLUDED +#define _MM3DNOW_H_INCLUDED + +#include +#include + +typedef float __v2sf __attribute__((__vector_size__(8))); + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("3dnow"))) + +static __inline__ void __DEFAULT_FN_ATTRS +_m_femms() { + __builtin_ia32_femms(); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pavgusb(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pavgusb((__v8qi)__m1, (__v8qi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pf2id(__m64 __m) { + return (__m64)__builtin_ia32_pf2id((__v2sf)__m); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfacc(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfacc((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfadd(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfadd((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfcmpeq(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfcmpeq((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfcmpge(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfcmpge((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfcmpgt(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfcmpgt((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfmax(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfmax((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfmin(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfmin((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfmul(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfmul((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfrcp(__m64 __m) { + return (__m64)__builtin_ia32_pfrcp((__v2sf)__m); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfrcpit1(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfrcpit1((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfrcpit2(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfrcpit2((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfrsqrt(__m64 __m) { + return (__m64)__builtin_ia32_pfrsqrt((__v2sf)__m); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfrsqrtit1(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfrsqit1((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfsub(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfsub((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfsubr(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfsubr((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pi2fd(__m64 __m) { + return (__m64)__builtin_ia32_pi2fd((__v2si)__m); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pmulhrw(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pmulhrw((__v4hi)__m1, (__v4hi)__m2); +} + +/* Handle the 3dnowa instructions here. */ +#undef __DEFAULT_FN_ATTRS +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("3dnowa"))) + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pf2iw(__m64 __m) { + return (__m64)__builtin_ia32_pf2iw((__v2sf)__m); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfnacc(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfnacc((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pfpnacc(__m64 __m1, __m64 __m2) { + return (__m64)__builtin_ia32_pfpnacc((__v2sf)__m1, (__v2sf)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pi2fw(__m64 __m) { + return (__m64)__builtin_ia32_pi2fw((__v2si)__m); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pswapdsf(__m64 __m) { + return (__m64)__builtin_ia32_pswapdsf((__v2sf)__m); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_m_pswapdsi(__m64 __m) { + return (__m64)__builtin_ia32_pswapdsi((__v2si)__m); +} + +#undef __DEFAULT_FN_ATTRS + +#endif diff --git a/headers/clang/mm_malloc.h b/headers/clang/mm_malloc.h new file mode 100644 index 0000000000..305afd31ad --- /dev/null +++ b/headers/clang/mm_malloc.h @@ -0,0 +1,75 @@ +/*===---- mm_malloc.h - Allocating and Freeing Aligned Memory Blocks -------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __MM_MALLOC_H +#define __MM_MALLOC_H + +#include + +#ifdef _WIN32 +#include +#else +#ifndef __cplusplus +extern int posix_memalign(void **__memptr, size_t __alignment, size_t __size); +#else +// Some systems (e.g. those with GNU libc) declare posix_memalign with an +// exception specifier. Via an "egregious workaround" in +// Sema::CheckEquivalentExceptionSpec, Clang accepts the following as a valid +// redeclaration of glibc's declaration. +extern "C" int posix_memalign(void **__memptr, size_t __alignment, size_t __size); +#endif +#endif + +#if !(defined(_WIN32) && defined(_mm_malloc)) +static __inline__ void *__attribute__((__always_inline__, __nodebug__, + __malloc__)) +_mm_malloc(size_t __size, size_t __align) +{ + if (__align == 1) { + return malloc(__size); + } + + if (!(__align & (__align - 1)) && __align < sizeof(void *)) + __align = sizeof(void *); + + void *__mallocedMemory; +#if defined(__MINGW32__) + __mallocedMemory = __mingw_aligned_malloc(__size, __align); +#elif defined(_WIN32) + __mallocedMemory = _aligned_malloc(__size, __align); +#else + if (posix_memalign(&__mallocedMemory, __align, __size)) + return 0; +#endif + + return __mallocedMemory; +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_free(void *__p) +{ + free(__p); +} +#endif + +#endif /* __MM_MALLOC_H */ diff --git a/headers/clang/mmintrin.h b/headers/clang/mmintrin.h new file mode 100644 index 0000000000..1a9eb10d73 --- /dev/null +++ b/headers/clang/mmintrin.h @@ -0,0 +1,501 @@ +/*===---- mmintrin.h - MMX intrinsics --------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __MMINTRIN_H +#define __MMINTRIN_H + +typedef long long __m64 __attribute__((__vector_size__(8))); + +typedef int __v2si __attribute__((__vector_size__(8))); +typedef short __v4hi __attribute__((__vector_size__(8))); +typedef char __v8qi __attribute__((__vector_size__(8))); + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("mmx"))) + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_empty(void) +{ + __builtin_ia32_emms(); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cvtsi32_si64(int __i) +{ + return (__m64)__builtin_ia32_vec_init_v2si(__i, 0); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_cvtsi64_si32(__m64 __m) +{ + return __builtin_ia32_vec_ext_v2si((__v2si)__m, 0); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cvtsi64_m64(long long __i) +{ + return (__m64)__i; +} + +static __inline__ long long __DEFAULT_FN_ATTRS +_mm_cvtm64_si64(__m64 __m) +{ + return (long long)__m; +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_packs_pi16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_packsswb((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_packs_pi32(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_packssdw((__v2si)__m1, (__v2si)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_packs_pu16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_packuswb((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_unpackhi_pi8(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_punpckhbw((__v8qi)__m1, (__v8qi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_unpackhi_pi16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_punpckhwd((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_unpackhi_pi32(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_punpckhdq((__v2si)__m1, (__v2si)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_unpacklo_pi8(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_punpcklbw((__v8qi)__m1, (__v8qi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_unpacklo_pi16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_punpcklwd((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_unpacklo_pi32(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_punpckldq((__v2si)__m1, (__v2si)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_add_pi8(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_paddb((__v8qi)__m1, (__v8qi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_add_pi16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_paddw((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_add_pi32(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_paddd((__v2si)__m1, (__v2si)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_adds_pi8(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_paddsb((__v8qi)__m1, (__v8qi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_adds_pi16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_paddsw((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_adds_pu8(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_paddusb((__v8qi)__m1, (__v8qi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_adds_pu16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_paddusw((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_sub_pi8(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_psubb((__v8qi)__m1, (__v8qi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_sub_pi16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_psubw((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_sub_pi32(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_psubd((__v2si)__m1, (__v2si)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_subs_pi8(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_psubsb((__v8qi)__m1, (__v8qi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_subs_pi16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_psubsw((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_subs_pu8(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_psubusb((__v8qi)__m1, (__v8qi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_subs_pu16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_psubusw((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_madd_pi16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_pmaddwd((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_mulhi_pi16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_pmulhw((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_mullo_pi16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_pmullw((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_sll_pi16(__m64 __m, __m64 __count) +{ + return (__m64)__builtin_ia32_psllw((__v4hi)__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_slli_pi16(__m64 __m, int __count) +{ + return (__m64)__builtin_ia32_psllwi((__v4hi)__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_sll_pi32(__m64 __m, __m64 __count) +{ + return (__m64)__builtin_ia32_pslld((__v2si)__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_slli_pi32(__m64 __m, int __count) +{ + return (__m64)__builtin_ia32_pslldi((__v2si)__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_sll_si64(__m64 __m, __m64 __count) +{ + return (__m64)__builtin_ia32_psllq(__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_slli_si64(__m64 __m, int __count) +{ + return (__m64)__builtin_ia32_psllqi(__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_sra_pi16(__m64 __m, __m64 __count) +{ + return (__m64)__builtin_ia32_psraw((__v4hi)__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_srai_pi16(__m64 __m, int __count) +{ + return (__m64)__builtin_ia32_psrawi((__v4hi)__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_sra_pi32(__m64 __m, __m64 __count) +{ + return (__m64)__builtin_ia32_psrad((__v2si)__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_srai_pi32(__m64 __m, int __count) +{ + return (__m64)__builtin_ia32_psradi((__v2si)__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_srl_pi16(__m64 __m, __m64 __count) +{ + return (__m64)__builtin_ia32_psrlw((__v4hi)__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_srli_pi16(__m64 __m, int __count) +{ + return (__m64)__builtin_ia32_psrlwi((__v4hi)__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_srl_pi32(__m64 __m, __m64 __count) +{ + return (__m64)__builtin_ia32_psrld((__v2si)__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_srli_pi32(__m64 __m, int __count) +{ + return (__m64)__builtin_ia32_psrldi((__v2si)__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_srl_si64(__m64 __m, __m64 __count) +{ + return (__m64)__builtin_ia32_psrlq(__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_srli_si64(__m64 __m, int __count) +{ + return (__m64)__builtin_ia32_psrlqi(__m, __count); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_and_si64(__m64 __m1, __m64 __m2) +{ + return __builtin_ia32_pand(__m1, __m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_andnot_si64(__m64 __m1, __m64 __m2) +{ + return __builtin_ia32_pandn(__m1, __m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_or_si64(__m64 __m1, __m64 __m2) +{ + return __builtin_ia32_por(__m1, __m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_xor_si64(__m64 __m1, __m64 __m2) +{ + return __builtin_ia32_pxor(__m1, __m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cmpeq_pi8(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_pcmpeqb((__v8qi)__m1, (__v8qi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cmpeq_pi16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_pcmpeqw((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cmpeq_pi32(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_pcmpeqd((__v2si)__m1, (__v2si)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cmpgt_pi8(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_pcmpgtb((__v8qi)__m1, (__v8qi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cmpgt_pi16(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_pcmpgtw((__v4hi)__m1, (__v4hi)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cmpgt_pi32(__m64 __m1, __m64 __m2) +{ + return (__m64)__builtin_ia32_pcmpgtd((__v2si)__m1, (__v2si)__m2); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_setzero_si64(void) +{ + return (__m64){ 0LL }; +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_set_pi32(int __i1, int __i0) +{ + return (__m64)__builtin_ia32_vec_init_v2si(__i0, __i1); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_set_pi16(short __s3, short __s2, short __s1, short __s0) +{ + return (__m64)__builtin_ia32_vec_init_v4hi(__s0, __s1, __s2, __s3); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_set_pi8(char __b7, char __b6, char __b5, char __b4, char __b3, char __b2, + char __b1, char __b0) +{ + return (__m64)__builtin_ia32_vec_init_v8qi(__b0, __b1, __b2, __b3, + __b4, __b5, __b6, __b7); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_set1_pi32(int __i) +{ + return _mm_set_pi32(__i, __i); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_set1_pi16(short __w) +{ + return _mm_set_pi16(__w, __w, __w, __w); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_set1_pi8(char __b) +{ + return _mm_set_pi8(__b, __b, __b, __b, __b, __b, __b, __b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_setr_pi32(int __i0, int __i1) +{ + return _mm_set_pi32(__i1, __i0); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_setr_pi16(short __w0, short __w1, short __w2, short __w3) +{ + return _mm_set_pi16(__w3, __w2, __w1, __w0); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_setr_pi8(char __b0, char __b1, char __b2, char __b3, char __b4, char __b5, + char __b6, char __b7) +{ + return _mm_set_pi8(__b7, __b6, __b5, __b4, __b3, __b2, __b1, __b0); +} + +#undef __DEFAULT_FN_ATTRS + +/* Aliases for compatibility. */ +#define _m_empty _mm_empty +#define _m_from_int _mm_cvtsi32_si64 +#define _m_to_int _mm_cvtsi64_si32 +#define _m_packsswb _mm_packs_pi16 +#define _m_packssdw _mm_packs_pi32 +#define _m_packuswb _mm_packs_pu16 +#define _m_punpckhbw _mm_unpackhi_pi8 +#define _m_punpckhwd _mm_unpackhi_pi16 +#define _m_punpckhdq _mm_unpackhi_pi32 +#define _m_punpcklbw _mm_unpacklo_pi8 +#define _m_punpcklwd _mm_unpacklo_pi16 +#define _m_punpckldq _mm_unpacklo_pi32 +#define _m_paddb _mm_add_pi8 +#define _m_paddw _mm_add_pi16 +#define _m_paddd _mm_add_pi32 +#define _m_paddsb _mm_adds_pi8 +#define _m_paddsw _mm_adds_pi16 +#define _m_paddusb _mm_adds_pu8 +#define _m_paddusw _mm_adds_pu16 +#define _m_psubb _mm_sub_pi8 +#define _m_psubw _mm_sub_pi16 +#define _m_psubd _mm_sub_pi32 +#define _m_psubsb _mm_subs_pi8 +#define _m_psubsw _mm_subs_pi16 +#define _m_psubusb _mm_subs_pu8 +#define _m_psubusw _mm_subs_pu16 +#define _m_pmaddwd _mm_madd_pi16 +#define _m_pmulhw _mm_mulhi_pi16 +#define _m_pmullw _mm_mullo_pi16 +#define _m_psllw _mm_sll_pi16 +#define _m_psllwi _mm_slli_pi16 +#define _m_pslld _mm_sll_pi32 +#define _m_pslldi _mm_slli_pi32 +#define _m_psllq _mm_sll_si64 +#define _m_psllqi _mm_slli_si64 +#define _m_psraw _mm_sra_pi16 +#define _m_psrawi _mm_srai_pi16 +#define _m_psrad _mm_sra_pi32 +#define _m_psradi _mm_srai_pi32 +#define _m_psrlw _mm_srl_pi16 +#define _m_psrlwi _mm_srli_pi16 +#define _m_psrld _mm_srl_pi32 +#define _m_psrldi _mm_srli_pi32 +#define _m_psrlq _mm_srl_si64 +#define _m_psrlqi _mm_srli_si64 +#define _m_pand _mm_and_si64 +#define _m_pandn _mm_andnot_si64 +#define _m_por _mm_or_si64 +#define _m_pxor _mm_xor_si64 +#define _m_pcmpeqb _mm_cmpeq_pi8 +#define _m_pcmpeqw _mm_cmpeq_pi16 +#define _m_pcmpeqd _mm_cmpeq_pi32 +#define _m_pcmpgtb _mm_cmpgt_pi8 +#define _m_pcmpgtw _mm_cmpgt_pi16 +#define _m_pcmpgtd _mm_cmpgt_pi32 + +#endif /* __MMINTRIN_H */ + diff --git a/headers/clang/module.modulemap b/headers/clang/module.modulemap new file mode 100644 index 0000000000..b147e891dc --- /dev/null +++ b/headers/clang/module.modulemap @@ -0,0 +1,171 @@ +module _Builtin_intrinsics [system] [extern_c] { + explicit module altivec { + requires altivec + header "altivec.h" + } + + explicit module arm { + requires arm + + explicit module acle { + header "arm_acle.h" + export * + } + + explicit module neon { + requires neon + header "arm_neon.h" + export * + } + } + + explicit module intel { + requires x86 + export * + + header "immintrin.h" + header "x86intrin.h" + + explicit module mm_malloc { + header "mm_malloc.h" + export * // note: for dependency + } + + explicit module cpuid { + header "cpuid.h" + } + + explicit module mmx { + header "mmintrin.h" + } + + explicit module f16c { + header "f16cintrin.h" + } + + explicit module sse { + export mmx + export sse2 // note: for hackish dependency + header "xmmintrin.h" + } + + explicit module sse2 { + export sse + header "emmintrin.h" + } + + explicit module sse3 { + export sse2 + header "pmmintrin.h" + } + + explicit module ssse3 { + export sse3 + header "tmmintrin.h" + } + + explicit module sse4_1 { + export ssse3 + header "smmintrin.h" + } + + explicit module sse4_2 { + export sse4_1 + header "nmmintrin.h" + } + + explicit module sse4a { + export sse3 + header "ammintrin.h" + } + + explicit module avx { + export sse4_2 + header "avxintrin.h" + } + + explicit module avx2 { + export avx + header "avx2intrin.h" + } + + explicit module avx512f { + export avx2 + header "avx512fintrin.h" + } + + explicit module avx512er { + header "avx512erintrin.h" + } + + explicit module bmi { + header "bmiintrin.h" + } + + explicit module bmi2 { + header "bmi2intrin.h" + } + + explicit module fma { + header "fmaintrin.h" + } + + explicit module fma4 { + export sse3 + header "fma4intrin.h" + } + + explicit module lzcnt { + header "lzcntintrin.h" + } + + explicit module popcnt { + header "popcntintrin.h" + } + + explicit module mm3dnow { + header "mm3dnow.h" + } + + explicit module xop { + export fma4 + header "xopintrin.h" + } + + explicit module aes_pclmul { + header "wmmintrin.h" + export aes + export pclmul + } + + explicit module aes { + header "__wmmintrin_aes.h" + } + + explicit module pclmul { + header "__wmmintrin_pclmul.h" + } + } + + explicit module systemz { + requires systemz + export * + + header "s390intrin.h" + + explicit module htm { + requires htm + header "htmintrin.h" + header "htmxlintrin.h" + } + + explicit module zvector { + requires zvector, vx + header "vecintrin.h" + } + } +} + +module _Builtin_stddef_max_align_t [system] [extern_c] { + header "__stddef_max_align_t.h" +} diff --git a/headers/clang/nmmintrin.h b/headers/clang/nmmintrin.h new file mode 100644 index 0000000000..57fec15963 --- /dev/null +++ b/headers/clang/nmmintrin.h @@ -0,0 +1,30 @@ +/*===---- nmmintrin.h - SSE4 intrinsics ------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef _NMMINTRIN_H +#define _NMMINTRIN_H + +/* To match expectations of gcc we put the sse4.2 definitions into smmintrin.h, + just include it now then. */ +#include +#endif /* _NMMINTRIN_H */ diff --git a/headers/clang/pmmintrin.h b/headers/clang/pmmintrin.h new file mode 100644 index 0000000000..0ff9409124 --- /dev/null +++ b/headers/clang/pmmintrin.h @@ -0,0 +1,116 @@ +/*===---- pmmintrin.h - SSE3 intrinsics ------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __PMMINTRIN_H +#define __PMMINTRIN_H + +#include + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("sse3"))) + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_lddqu_si128(__m128i const *__p) +{ + return (__m128i)__builtin_ia32_lddqu((char const *)__p); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_addsub_ps(__m128 __a, __m128 __b) +{ + return __builtin_ia32_addsubps(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_hadd_ps(__m128 __a, __m128 __b) +{ + return __builtin_ia32_haddps(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_hsub_ps(__m128 __a, __m128 __b) +{ + return __builtin_ia32_hsubps(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_movehdup_ps(__m128 __a) +{ + return __builtin_shufflevector(__a, __a, 1, 1, 3, 3); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_moveldup_ps(__m128 __a) +{ + return __builtin_shufflevector(__a, __a, 0, 0, 2, 2); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_addsub_pd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_addsubpd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_hadd_pd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_haddpd(__a, __b); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_hsub_pd(__m128d __a, __m128d __b) +{ + return __builtin_ia32_hsubpd(__a, __b); +} + +#define _mm_loaddup_pd(dp) _mm_load1_pd(dp) + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_movedup_pd(__m128d __a) +{ + return __builtin_shufflevector(__a, __a, 0, 0); +} + +#define _MM_DENORMALS_ZERO_ON (0x0040) +#define _MM_DENORMALS_ZERO_OFF (0x0000) + +#define _MM_DENORMALS_ZERO_MASK (0x0040) + +#define _MM_GET_DENORMALS_ZERO_MODE() (_mm_getcsr() & _MM_DENORMALS_ZERO_MASK) +#define _MM_SET_DENORMALS_ZERO_MODE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) | (x))) + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_monitor(void const *__p, unsigned __extensions, unsigned __hints) +{ + __builtin_ia32_monitor((void *)__p, __extensions, __hints); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_mwait(unsigned __extensions, unsigned __hints) +{ + __builtin_ia32_mwait(__extensions, __hints); +} + +#undef __DEFAULT_FN_ATTRS + +#endif /* __PMMINTRIN_H */ diff --git a/headers/clang/popcntintrin.h b/headers/clang/popcntintrin.h new file mode 100644 index 0000000000..29c074b61d --- /dev/null +++ b/headers/clang/popcntintrin.h @@ -0,0 +1,46 @@ +/*===---- popcntintrin.h - POPCNT intrinsics -------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef _POPCNTINTRIN_H +#define _POPCNTINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("popcnt"))) + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_popcnt_u32(unsigned int __A) +{ + return __builtin_popcount(__A); +} + +#ifdef __x86_64__ +static __inline__ long long __DEFAULT_FN_ATTRS +_mm_popcnt_u64(unsigned long long __A) +{ + return __builtin_popcountll(__A); +} +#endif /* __x86_64__ */ + +#undef __DEFAULT_FN_ATTRS + +#endif /* _POPCNTINTRIN_H */ diff --git a/headers/clang/prfchwintrin.h b/headers/clang/prfchwintrin.h new file mode 100644 index 0000000000..ba02857518 --- /dev/null +++ b/headers/clang/prfchwintrin.h @@ -0,0 +1,45 @@ +/*===---- prfchwintrin.h - PREFETCHW intrinsic -----------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#if !defined(__X86INTRIN_H) && !defined(_MM3DNOW_H_INCLUDED) +#error "Never use directly; include or instead." +#endif + +#ifndef __PRFCHWINTRIN_H +#define __PRFCHWINTRIN_H + +#if defined(__PRFCHW__) || defined(__3dNOW__) +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_m_prefetch(void *__P) +{ + __builtin_prefetch (__P, 0, 3 /* _MM_HINT_T0 */); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_m_prefetchw(void *__P) +{ + __builtin_prefetch (__P, 1, 3 /* _MM_HINT_T0 */); +} +#endif + +#endif /* __PRFCHWINTRIN_H */ diff --git a/headers/clang/rdseedintrin.h b/headers/clang/rdseedintrin.h new file mode 100644 index 0000000000..421f4ea487 --- /dev/null +++ b/headers/clang/rdseedintrin.h @@ -0,0 +1,56 @@ +/*===---- rdseedintrin.h - RDSEED intrinsics -------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __X86INTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __RDSEEDINTRIN_H +#define __RDSEEDINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("rdseed"))) + +static __inline__ int __DEFAULT_FN_ATTRS +_rdseed16_step(unsigned short *__p) +{ + return __builtin_ia32_rdseed16_step(__p); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_rdseed32_step(unsigned int *__p) +{ + return __builtin_ia32_rdseed32_step(__p); +} + +#ifdef __x86_64__ +static __inline__ int __DEFAULT_FN_ATTRS +_rdseed64_step(unsigned long long *__p) +{ + return __builtin_ia32_rdseed64_step(__p); +} +#endif + +#undef __DEFAULT_FN_ATTRS + +#endif /* __RDSEEDINTRIN_H */ diff --git a/headers/clang/rtmintrin.h b/headers/clang/rtmintrin.h new file mode 100644 index 0000000000..e6a58d743b --- /dev/null +++ b/headers/clang/rtmintrin.h @@ -0,0 +1,59 @@ +/*===---- rtmintrin.h - RTM intrinsics -------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __RTMINTRIN_H +#define __RTMINTRIN_H + +#define _XBEGIN_STARTED (~0u) +#define _XABORT_EXPLICIT (1 << 0) +#define _XABORT_RETRY (1 << 1) +#define _XABORT_CONFLICT (1 << 2) +#define _XABORT_CAPACITY (1 << 3) +#define _XABORT_DEBUG (1 << 4) +#define _XABORT_NESTED (1 << 5) +#define _XABORT_CODE(x) (((x) >> 24) & 0xFF) + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("rtm"))) + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +_xbegin(void) +{ + return __builtin_ia32_xbegin(); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_xend(void) +{ + __builtin_ia32_xend(); +} + +#define _xabort(imm) __builtin_ia32_xabort((imm)) + +#undef __DEFAULT_FN_ATTRS + +#endif /* __RTMINTRIN_H */ diff --git a/headers/clang/s390intrin.h b/headers/clang/s390intrin.h new file mode 100644 index 0000000000..d51274c07d --- /dev/null +++ b/headers/clang/s390intrin.h @@ -0,0 +1,39 @@ +/*===---- s390intrin.h - SystemZ intrinsics --------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __S390INTRIN_H +#define __S390INTRIN_H + +#ifndef __s390__ +#error " is for s390 only" +#endif + +#ifdef __HTM__ +#include +#endif + +#ifdef __VEC__ +#include +#endif + +#endif /* __S390INTRIN_H*/ diff --git a/headers/clang/shaintrin.h b/headers/clang/shaintrin.h new file mode 100644 index 0000000000..8602d0249d --- /dev/null +++ b/headers/clang/shaintrin.h @@ -0,0 +1,75 @@ +/*===---- shaintrin.h - SHA intrinsics -------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __SHAINTRIN_H +#define __SHAINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("sha"))) + +#define _mm_sha1rnds4_epu32(V1, V2, M) __extension__ ({ \ + __builtin_ia32_sha1rnds4((V1), (V2), (M)); }) + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sha1nexte_epu32(__m128i __X, __m128i __Y) +{ + return (__m128i)__builtin_ia32_sha1nexte((__v4si)__X, (__v4si)__Y); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sha1msg1_epu32(__m128i __X, __m128i __Y) +{ + return (__m128i)__builtin_ia32_sha1msg1((__v4si)__X, (__v4si)__Y); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sha1msg2_epu32(__m128i __X, __m128i __Y) +{ + return (__m128i)__builtin_ia32_sha1msg2((__v4si)__X, (__v4si)__Y); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sha256rnds2_epu32(__m128i __X, __m128i __Y, __m128i __Z) +{ + return (__m128i)__builtin_ia32_sha256rnds2((__v4si)__X, (__v4si)__Y, (__v4si)__Z); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sha256msg1_epu32(__m128i __X, __m128i __Y) +{ + return (__m128i)__builtin_ia32_sha256msg1((__v4si)__X, (__v4si)__Y); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sha256msg2_epu32(__m128i __X, __m128i __Y) +{ + return (__m128i)__builtin_ia32_sha256msg2((__v4si)__X, (__v4si)__Y); +} + +#undef __DEFAULT_FN_ATTRS + +#endif /* __SHAINTRIN_H */ diff --git a/headers/clang/smmintrin.h b/headers/clang/smmintrin.h new file mode 100644 index 0000000000..89db27f20c --- /dev/null +++ b/headers/clang/smmintrin.h @@ -0,0 +1,491 @@ +/*===---- smmintrin.h - SSE4 intrinsics ------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef _SMMINTRIN_H +#define _SMMINTRIN_H + +#include + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("sse4.1"))) + +/* SSE4 Rounding macros. */ +#define _MM_FROUND_TO_NEAREST_INT 0x00 +#define _MM_FROUND_TO_NEG_INF 0x01 +#define _MM_FROUND_TO_POS_INF 0x02 +#define _MM_FROUND_TO_ZERO 0x03 +#define _MM_FROUND_CUR_DIRECTION 0x04 + +#define _MM_FROUND_RAISE_EXC 0x00 +#define _MM_FROUND_NO_EXC 0x08 + +#define _MM_FROUND_NINT (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_NEAREST_INT) +#define _MM_FROUND_FLOOR (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_NEG_INF) +#define _MM_FROUND_CEIL (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_POS_INF) +#define _MM_FROUND_TRUNC (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_ZERO) +#define _MM_FROUND_RINT (_MM_FROUND_RAISE_EXC | _MM_FROUND_CUR_DIRECTION) +#define _MM_FROUND_NEARBYINT (_MM_FROUND_NO_EXC | _MM_FROUND_CUR_DIRECTION) + +#define _mm_ceil_ps(X) _mm_round_ps((X), _MM_FROUND_CEIL) +#define _mm_ceil_pd(X) _mm_round_pd((X), _MM_FROUND_CEIL) +#define _mm_ceil_ss(X, Y) _mm_round_ss((X), (Y), _MM_FROUND_CEIL) +#define _mm_ceil_sd(X, Y) _mm_round_sd((X), (Y), _MM_FROUND_CEIL) + +#define _mm_floor_ps(X) _mm_round_ps((X), _MM_FROUND_FLOOR) +#define _mm_floor_pd(X) _mm_round_pd((X), _MM_FROUND_FLOOR) +#define _mm_floor_ss(X, Y) _mm_round_ss((X), (Y), _MM_FROUND_FLOOR) +#define _mm_floor_sd(X, Y) _mm_round_sd((X), (Y), _MM_FROUND_FLOOR) + +#define _mm_round_ps(X, M) __extension__ ({ \ + __m128 __X = (X); \ + (__m128) __builtin_ia32_roundps((__v4sf)__X, (M)); }) + +#define _mm_round_ss(X, Y, M) __extension__ ({ \ + __m128 __X = (X); \ + __m128 __Y = (Y); \ + (__m128) __builtin_ia32_roundss((__v4sf)__X, (__v4sf)__Y, (M)); }) + +#define _mm_round_pd(X, M) __extension__ ({ \ + __m128d __X = (X); \ + (__m128d) __builtin_ia32_roundpd((__v2df)__X, (M)); }) + +#define _mm_round_sd(X, Y, M) __extension__ ({ \ + __m128d __X = (X); \ + __m128d __Y = (Y); \ + (__m128d) __builtin_ia32_roundsd((__v2df)__X, (__v2df)__Y, (M)); }) + +/* SSE4 Packed Blending Intrinsics. */ +#define _mm_blend_pd(V1, V2, M) __extension__ ({ \ + __m128d __V1 = (V1); \ + __m128d __V2 = (V2); \ + (__m128d)__builtin_shufflevector((__v2df)__V1, (__v2df)__V2, \ + (((M) & 0x01) ? 2 : 0), \ + (((M) & 0x02) ? 3 : 1)); }) + +#define _mm_blend_ps(V1, V2, M) __extension__ ({ \ + __m128 __V1 = (V1); \ + __m128 __V2 = (V2); \ + (__m128)__builtin_shufflevector((__v4sf)__V1, (__v4sf)__V2, \ + (((M) & 0x01) ? 4 : 0), \ + (((M) & 0x02) ? 5 : 1), \ + (((M) & 0x04) ? 6 : 2), \ + (((M) & 0x08) ? 7 : 3)); }) + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_blendv_pd (__m128d __V1, __m128d __V2, __m128d __M) +{ + return (__m128d) __builtin_ia32_blendvpd ((__v2df)__V1, (__v2df)__V2, + (__v2df)__M); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_blendv_ps (__m128 __V1, __m128 __V2, __m128 __M) +{ + return (__m128) __builtin_ia32_blendvps ((__v4sf)__V1, (__v4sf)__V2, + (__v4sf)__M); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_blendv_epi8 (__m128i __V1, __m128i __V2, __m128i __M) +{ + return (__m128i) __builtin_ia32_pblendvb128 ((__v16qi)__V1, (__v16qi)__V2, + (__v16qi)__M); +} + +#define _mm_blend_epi16(V1, V2, M) __extension__ ({ \ + __m128i __V1 = (V1); \ + __m128i __V2 = (V2); \ + (__m128i)__builtin_shufflevector((__v8hi)__V1, (__v8hi)__V2, \ + (((M) & 0x01) ? 8 : 0), \ + (((M) & 0x02) ? 9 : 1), \ + (((M) & 0x04) ? 10 : 2), \ + (((M) & 0x08) ? 11 : 3), \ + (((M) & 0x10) ? 12 : 4), \ + (((M) & 0x20) ? 13 : 5), \ + (((M) & 0x40) ? 14 : 6), \ + (((M) & 0x80) ? 15 : 7)); }) + +/* SSE4 Dword Multiply Instructions. */ +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mullo_epi32 (__m128i __V1, __m128i __V2) +{ + return (__m128i) ((__v4si)__V1 * (__v4si)__V2); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mul_epi32 (__m128i __V1, __m128i __V2) +{ + return (__m128i) __builtin_ia32_pmuldq128 ((__v4si)__V1, (__v4si)__V2); +} + +/* SSE4 Floating Point Dot Product Instructions. */ +#define _mm_dp_ps(X, Y, M) __extension__ ({ \ + __m128 __X = (X); \ + __m128 __Y = (Y); \ + (__m128) __builtin_ia32_dpps((__v4sf)__X, (__v4sf)__Y, (M)); }) + +#define _mm_dp_pd(X, Y, M) __extension__ ({\ + __m128d __X = (X); \ + __m128d __Y = (Y); \ + (__m128d) __builtin_ia32_dppd((__v2df)__X, (__v2df)__Y, (M)); }) + +/* SSE4 Streaming Load Hint Instruction. */ +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_stream_load_si128 (__m128i const *__V) +{ + return (__m128i) __builtin_ia32_movntdqa ((const __v2di *) __V); +} + +/* SSE4 Packed Integer Min/Max Instructions. */ +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_min_epi8 (__m128i __V1, __m128i __V2) +{ + return (__m128i) __builtin_ia32_pminsb128 ((__v16qi) __V1, (__v16qi) __V2); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_max_epi8 (__m128i __V1, __m128i __V2) +{ + return (__m128i) __builtin_ia32_pmaxsb128 ((__v16qi) __V1, (__v16qi) __V2); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_min_epu16 (__m128i __V1, __m128i __V2) +{ + return (__m128i) __builtin_ia32_pminuw128 ((__v8hi) __V1, (__v8hi) __V2); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_max_epu16 (__m128i __V1, __m128i __V2) +{ + return (__m128i) __builtin_ia32_pmaxuw128 ((__v8hi) __V1, (__v8hi) __V2); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_min_epi32 (__m128i __V1, __m128i __V2) +{ + return (__m128i) __builtin_ia32_pminsd128 ((__v4si) __V1, (__v4si) __V2); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_max_epi32 (__m128i __V1, __m128i __V2) +{ + return (__m128i) __builtin_ia32_pmaxsd128 ((__v4si) __V1, (__v4si) __V2); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_min_epu32 (__m128i __V1, __m128i __V2) +{ + return (__m128i) __builtin_ia32_pminud128((__v4si) __V1, (__v4si) __V2); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_max_epu32 (__m128i __V1, __m128i __V2) +{ + return (__m128i) __builtin_ia32_pmaxud128((__v4si) __V1, (__v4si) __V2); +} + +/* SSE4 Insertion and Extraction from XMM Register Instructions. */ +#define _mm_insert_ps(X, Y, N) __builtin_ia32_insertps128((X), (Y), (N)) +#define _mm_extract_ps(X, N) (__extension__ \ + ({ union { int __i; float __f; } __t; \ + __v4sf __a = (__v4sf)(X); \ + __t.__f = __a[(N) & 3]; \ + __t.__i;})) + +/* Miscellaneous insert and extract macros. */ +/* Extract a single-precision float from X at index N into D. */ +#define _MM_EXTRACT_FLOAT(D, X, N) (__extension__ ({ __v4sf __a = (__v4sf)(X); \ + (D) = __a[N]; })) + +/* Or together 2 sets of indexes (X and Y) with the zeroing bits (Z) to create + an index suitable for _mm_insert_ps. */ +#define _MM_MK_INSERTPS_NDX(X, Y, Z) (((X) << 6) | ((Y) << 4) | (Z)) + +/* Extract a float from X at index N into the first index of the return. */ +#define _MM_PICK_OUT_PS(X, N) _mm_insert_ps (_mm_setzero_ps(), (X), \ + _MM_MK_INSERTPS_NDX((N), 0, 0x0e)) + +/* Insert int into packed integer array at index. */ +#define _mm_insert_epi8(X, I, N) (__extension__ ({ __v16qi __a = (__v16qi)(X); \ + __a[(N) & 15] = (I); \ + __a;})) +#define _mm_insert_epi32(X, I, N) (__extension__ ({ __v4si __a = (__v4si)(X); \ + __a[(N) & 3] = (I); \ + __a;})) +#ifdef __x86_64__ +#define _mm_insert_epi64(X, I, N) (__extension__ ({ __v2di __a = (__v2di)(X); \ + __a[(N) & 1] = (I); \ + __a;})) +#endif /* __x86_64__ */ + +/* Extract int from packed integer array at index. This returns the element + * as a zero extended value, so it is unsigned. + */ +#define _mm_extract_epi8(X, N) (__extension__ ({ __v16qi __a = (__v16qi)(X); \ + (int)(unsigned char) \ + __a[(N) & 15];})) +#define _mm_extract_epi32(X, N) (__extension__ ({ __v4si __a = (__v4si)(X); \ + __a[(N) & 3];})) +#ifdef __x86_64__ +#define _mm_extract_epi64(X, N) (__extension__ ({ __v2di __a = (__v2di)(X); \ + __a[(N) & 1];})) +#endif /* __x86_64 */ + +/* SSE4 128-bit Packed Integer Comparisons. */ +static __inline__ int __DEFAULT_FN_ATTRS +_mm_testz_si128(__m128i __M, __m128i __V) +{ + return __builtin_ia32_ptestz128((__v2di)__M, (__v2di)__V); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_testc_si128(__m128i __M, __m128i __V) +{ + return __builtin_ia32_ptestc128((__v2di)__M, (__v2di)__V); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_testnzc_si128(__m128i __M, __m128i __V) +{ + return __builtin_ia32_ptestnzc128((__v2di)__M, (__v2di)__V); +} + +#define _mm_test_all_ones(V) _mm_testc_si128((V), _mm_cmpeq_epi32((V), (V))) +#define _mm_test_mix_ones_zeros(M, V) _mm_testnzc_si128((M), (V)) +#define _mm_test_all_zeros(M, V) _mm_testz_si128 ((M), (V)) + +/* SSE4 64-bit Packed Integer Comparisons. */ +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cmpeq_epi64(__m128i __V1, __m128i __V2) +{ + return (__m128i)((__v2di)__V1 == (__v2di)__V2); +} + +/* SSE4 Packed Integer Sign-Extension. */ +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtepi8_epi16(__m128i __V) +{ + /* This function always performs a signed extension, but __v16qi is a char + which may be signed or unsigned, so use __v16qs. */ + return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v16qs)__V, (__v16qs)__V, 0, 1, 2, 3, 4, 5, 6, 7), __v8hi); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtepi8_epi32(__m128i __V) +{ + /* This function always performs a signed extension, but __v16qi is a char + which may be signed or unsigned, so use __v16qs. */ + return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v16qs)__V, (__v16qs)__V, 0, 1, 2, 3), __v4si); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtepi8_epi64(__m128i __V) +{ + /* This function always performs a signed extension, but __v16qi is a char + which may be signed or unsigned, so use __v16qs. */ + typedef signed char __v16qs __attribute__((__vector_size__(16))); + return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v16qs)__V, (__v16qs)__V, 0, 1), __v2di); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtepi16_epi32(__m128i __V) +{ + return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v8hi)__V, (__v8hi)__V, 0, 1, 2, 3), __v4si); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtepi16_epi64(__m128i __V) +{ + return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v8hi)__V, (__v8hi)__V, 0, 1), __v2di); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtepi32_epi64(__m128i __V) +{ + return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v4si)__V, (__v4si)__V, 0, 1), __v2di); +} + +/* SSE4 Packed Integer Zero-Extension. */ +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtepu8_epi16(__m128i __V) +{ + return (__m128i) __builtin_ia32_pmovzxbw128((__v16qi) __V); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtepu8_epi32(__m128i __V) +{ + return (__m128i) __builtin_ia32_pmovzxbd128((__v16qi)__V); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtepu8_epi64(__m128i __V) +{ + return (__m128i) __builtin_ia32_pmovzxbq128((__v16qi)__V); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtepu16_epi32(__m128i __V) +{ + return (__m128i) __builtin_ia32_pmovzxwd128((__v8hi)__V); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtepu16_epi64(__m128i __V) +{ + return (__m128i) __builtin_ia32_pmovzxwq128((__v8hi)__V); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cvtepu32_epi64(__m128i __V) +{ + return (__m128i) __builtin_ia32_pmovzxdq128((__v4si)__V); +} + +/* SSE4 Pack with Unsigned Saturation. */ +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_packus_epi32(__m128i __V1, __m128i __V2) +{ + return (__m128i) __builtin_ia32_packusdw128((__v4si)__V1, (__v4si)__V2); +} + +/* SSE4 Multiple Packed Sums of Absolute Difference. */ +#define _mm_mpsadbw_epu8(X, Y, M) __extension__ ({ \ + __m128i __X = (X); \ + __m128i __Y = (Y); \ + (__m128i) __builtin_ia32_mpsadbw128((__v16qi)__X, (__v16qi)__Y, (M)); }) + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_minpos_epu16(__m128i __V) +{ + return (__m128i) __builtin_ia32_phminposuw128((__v8hi)__V); +} + +/* Handle the sse4.2 definitions here. */ + +/* These definitions are normally in nmmintrin.h, but gcc puts them in here + so we'll do the same. */ + +#undef __DEFAULT_FN_ATTRS +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("sse4.2"))) + +/* These specify the type of data that we're comparing. */ +#define _SIDD_UBYTE_OPS 0x00 +#define _SIDD_UWORD_OPS 0x01 +#define _SIDD_SBYTE_OPS 0x02 +#define _SIDD_SWORD_OPS 0x03 + +/* These specify the type of comparison operation. */ +#define _SIDD_CMP_EQUAL_ANY 0x00 +#define _SIDD_CMP_RANGES 0x04 +#define _SIDD_CMP_EQUAL_EACH 0x08 +#define _SIDD_CMP_EQUAL_ORDERED 0x0c + +/* These macros specify the polarity of the operation. */ +#define _SIDD_POSITIVE_POLARITY 0x00 +#define _SIDD_NEGATIVE_POLARITY 0x10 +#define _SIDD_MASKED_POSITIVE_POLARITY 0x20 +#define _SIDD_MASKED_NEGATIVE_POLARITY 0x30 + +/* These macros are used in _mm_cmpXstri() to specify the return. */ +#define _SIDD_LEAST_SIGNIFICANT 0x00 +#define _SIDD_MOST_SIGNIFICANT 0x40 + +/* These macros are used in _mm_cmpXstri() to specify the return. */ +#define _SIDD_BIT_MASK 0x00 +#define _SIDD_UNIT_MASK 0x40 + +/* SSE4.2 Packed Comparison Intrinsics. */ +#define _mm_cmpistrm(A, B, M) __builtin_ia32_pcmpistrm128((A), (B), (M)) +#define _mm_cmpistri(A, B, M) __builtin_ia32_pcmpistri128((A), (B), (M)) + +#define _mm_cmpestrm(A, LA, B, LB, M) \ + __builtin_ia32_pcmpestrm128((A), (LA), (B), (LB), (M)) +#define _mm_cmpestri(A, LA, B, LB, M) \ + __builtin_ia32_pcmpestri128((A), (LA), (B), (LB), (M)) + +/* SSE4.2 Packed Comparison Intrinsics and EFlag Reading. */ +#define _mm_cmpistra(A, B, M) \ + __builtin_ia32_pcmpistria128((A), (B), (M)) +#define _mm_cmpistrc(A, B, M) \ + __builtin_ia32_pcmpistric128((A), (B), (M)) +#define _mm_cmpistro(A, B, M) \ + __builtin_ia32_pcmpistrio128((A), (B), (M)) +#define _mm_cmpistrs(A, B, M) \ + __builtin_ia32_pcmpistris128((A), (B), (M)) +#define _mm_cmpistrz(A, B, M) \ + __builtin_ia32_pcmpistriz128((A), (B), (M)) + +#define _mm_cmpestra(A, LA, B, LB, M) \ + __builtin_ia32_pcmpestria128((A), (LA), (B), (LB), (M)) +#define _mm_cmpestrc(A, LA, B, LB, M) \ + __builtin_ia32_pcmpestric128((A), (LA), (B), (LB), (M)) +#define _mm_cmpestro(A, LA, B, LB, M) \ + __builtin_ia32_pcmpestrio128((A), (LA), (B), (LB), (M)) +#define _mm_cmpestrs(A, LA, B, LB, M) \ + __builtin_ia32_pcmpestris128((A), (LA), (B), (LB), (M)) +#define _mm_cmpestrz(A, LA, B, LB, M) \ + __builtin_ia32_pcmpestriz128((A), (LA), (B), (LB), (M)) + +/* SSE4.2 Compare Packed Data -- Greater Than. */ +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cmpgt_epi64(__m128i __V1, __m128i __V2) +{ + return (__m128i)((__v2di)__V1 > (__v2di)__V2); +} + +/* SSE4.2 Accumulate CRC32. */ +static __inline__ unsigned int __DEFAULT_FN_ATTRS +_mm_crc32_u8(unsigned int __C, unsigned char __D) +{ + return __builtin_ia32_crc32qi(__C, __D); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +_mm_crc32_u16(unsigned int __C, unsigned short __D) +{ + return __builtin_ia32_crc32hi(__C, __D); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +_mm_crc32_u32(unsigned int __C, unsigned int __D) +{ + return __builtin_ia32_crc32si(__C, __D); +} + +#ifdef __x86_64__ +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +_mm_crc32_u64(unsigned long long __C, unsigned long long __D) +{ + return __builtin_ia32_crc32di(__C, __D); +} +#endif /* __x86_64__ */ + +#undef __DEFAULT_FN_ATTRS + +#ifdef __POPCNT__ +#include +#endif + +#endif /* _SMMINTRIN_H */ diff --git a/headers/clang/stdalign.h b/headers/clang/stdalign.h new file mode 100644 index 0000000000..3738d1284f --- /dev/null +++ b/headers/clang/stdalign.h @@ -0,0 +1,35 @@ +/*===---- stdalign.h - Standard header for alignment ------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __STDALIGN_H +#define __STDALIGN_H + +#ifndef __cplusplus +#define alignas _Alignas +#define alignof _Alignof +#endif + +#define __alignas_is_defined 1 +#define __alignof_is_defined 1 + +#endif /* __STDALIGN_H */ diff --git a/headers/clang/stdarg.h b/headers/clang/stdarg.h new file mode 100644 index 0000000000..a57e183648 --- /dev/null +++ b/headers/clang/stdarg.h @@ -0,0 +1,52 @@ +/*===---- stdarg.h - Variable argument handling ----------------------------=== + * + * Copyright (c) 2008 Eli Friedman + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __STDARG_H +#define __STDARG_H + +#ifndef _VA_LIST +typedef __builtin_va_list va_list; +#define _VA_LIST +#endif +#define va_start(ap, param) __builtin_va_start(ap, param) +#define va_end(ap) __builtin_va_end(ap) +#define va_arg(ap, type) __builtin_va_arg(ap, type) + +/* GCC always defines __va_copy, but does not define va_copy unless in c99 mode + * or -ansi is not specified, since it was not part of C90. + */ +#define __va_copy(d,s) __builtin_va_copy(d,s) + +#if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L || !defined(__STRICT_ANSI__) +#define va_copy(dest, src) __builtin_va_copy(dest, src) +#endif + +/* Hack required to make standard headers work, at least on Ubuntu */ +#ifndef __GNUC_VA_LIST +#define __GNUC_VA_LIST 1 +#endif +typedef __builtin_va_list __gnuc_va_list; + +#endif /* __STDARG_H */ diff --git a/headers/clang/stdatomic.h b/headers/clang/stdatomic.h new file mode 100644 index 0000000000..e037987660 --- /dev/null +++ b/headers/clang/stdatomic.h @@ -0,0 +1,190 @@ +/*===---- stdatomic.h - Standard header for atomic types and operations -----=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __CLANG_STDATOMIC_H +#define __CLANG_STDATOMIC_H + +/* If we're hosted, fall back to the system's stdatomic.h. FreeBSD, for + * example, already has a Clang-compatible stdatomic.h header. + */ +#if __STDC_HOSTED__ && __has_include_next() +# include_next +#else + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* 7.17.1 Introduction */ + +#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE +#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE +#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE +#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE +#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE +#define ATOMIC_SHORT_T_LOCK_FREE __GCC_ATOMIC_SHORT_T_LOCK_FREE +#define ATOMIC_INT_T_LOCK_FREE __GCC_ATOMIC_INT_T_LOCK_FREE +#define ATOMIC_LONG_T_LOCK_FREE __GCC_ATOMIC_LONG_T_LOCK_FREE +#define ATOMIC_LLONG_T_LOCK_FREE __GCC_ATOMIC_LLONG_T_LOCK_FREE +#define ATOMIC_POINTER_T_LOCK_FREE __GCC_ATOMIC_POINTER_T_LOCK_FREE + +/* 7.17.2 Initialization */ + +#define ATOMIC_VAR_INIT(value) (value) +#define atomic_init __c11_atomic_init + +/* 7.17.3 Order and consistency */ + +typedef enum memory_order { + memory_order_relaxed = __ATOMIC_RELAXED, + memory_order_consume = __ATOMIC_CONSUME, + memory_order_acquire = __ATOMIC_ACQUIRE, + memory_order_release = __ATOMIC_RELEASE, + memory_order_acq_rel = __ATOMIC_ACQ_REL, + memory_order_seq_cst = __ATOMIC_SEQ_CST +} memory_order; + +#define kill_dependency(y) (y) + +/* 7.17.4 Fences */ + +/* These should be provided by the libc implementation. */ +void atomic_thread_fence(memory_order); +void atomic_signal_fence(memory_order); + +#define atomic_thread_fence(order) __c11_atomic_thread_fence(order) +#define atomic_signal_fence(order) __c11_atomic_signal_fence(order) + +/* 7.17.5 Lock-free property */ + +#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj))) + +/* 7.17.6 Atomic integer types */ + +#ifdef __cplusplus +typedef _Atomic(bool) atomic_bool; +#else +typedef _Atomic(_Bool) atomic_bool; +#endif +typedef _Atomic(char) atomic_char; +typedef _Atomic(signed char) atomic_schar; +typedef _Atomic(unsigned char) atomic_uchar; +typedef _Atomic(short) atomic_short; +typedef _Atomic(unsigned short) atomic_ushort; +typedef _Atomic(int) atomic_int; +typedef _Atomic(unsigned int) atomic_uint; +typedef _Atomic(long) atomic_long; +typedef _Atomic(unsigned long) atomic_ulong; +typedef _Atomic(long long) atomic_llong; +typedef _Atomic(unsigned long long) atomic_ullong; +typedef _Atomic(uint_least16_t) atomic_char16_t; +typedef _Atomic(uint_least32_t) atomic_char32_t; +typedef _Atomic(wchar_t) atomic_wchar_t; +typedef _Atomic(int_least8_t) atomic_int_least8_t; +typedef _Atomic(uint_least8_t) atomic_uint_least8_t; +typedef _Atomic(int_least16_t) atomic_int_least16_t; +typedef _Atomic(uint_least16_t) atomic_uint_least16_t; +typedef _Atomic(int_least32_t) atomic_int_least32_t; +typedef _Atomic(uint_least32_t) atomic_uint_least32_t; +typedef _Atomic(int_least64_t) atomic_int_least64_t; +typedef _Atomic(uint_least64_t) atomic_uint_least64_t; +typedef _Atomic(int_fast8_t) atomic_int_fast8_t; +typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t; +typedef _Atomic(int_fast16_t) atomic_int_fast16_t; +typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t; +typedef _Atomic(int_fast32_t) atomic_int_fast32_t; +typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t; +typedef _Atomic(int_fast64_t) atomic_int_fast64_t; +typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t; +typedef _Atomic(intptr_t) atomic_intptr_t; +typedef _Atomic(uintptr_t) atomic_uintptr_t; +typedef _Atomic(size_t) atomic_size_t; +typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t; +typedef _Atomic(intmax_t) atomic_intmax_t; +typedef _Atomic(uintmax_t) atomic_uintmax_t; + +/* 7.17.7 Operations on atomic types */ + +#define atomic_store(object, desired) __c11_atomic_store(object, desired, __ATOMIC_SEQ_CST) +#define atomic_store_explicit __c11_atomic_store + +#define atomic_load(object) __c11_atomic_load(object, __ATOMIC_SEQ_CST) +#define atomic_load_explicit __c11_atomic_load + +#define atomic_exchange(object, desired) __c11_atomic_exchange(object, desired, __ATOMIC_SEQ_CST) +#define atomic_exchange_explicit __c11_atomic_exchange + +#define atomic_compare_exchange_strong(object, expected, desired) __c11_atomic_compare_exchange_strong(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) +#define atomic_compare_exchange_strong_explicit __c11_atomic_compare_exchange_strong + +#define atomic_compare_exchange_weak(object, expected, desired) __c11_atomic_compare_exchange_weak(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) +#define atomic_compare_exchange_weak_explicit __c11_atomic_compare_exchange_weak + +#define atomic_fetch_add(object, operand) __c11_atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST) +#define atomic_fetch_add_explicit __c11_atomic_fetch_add + +#define atomic_fetch_sub(object, operand) __c11_atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST) +#define atomic_fetch_sub_explicit __c11_atomic_fetch_sub + +#define atomic_fetch_or(object, operand) __c11_atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST) +#define atomic_fetch_or_explicit __c11_atomic_fetch_or + +#define atomic_fetch_xor(object, operand) __c11_atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST) +#define atomic_fetch_xor_explicit __c11_atomic_fetch_xor + +#define atomic_fetch_and(object, operand) __c11_atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST) +#define atomic_fetch_and_explicit __c11_atomic_fetch_and + +/* 7.17.8 Atomic flag type and operations */ + +typedef struct atomic_flag { atomic_bool _Value; } atomic_flag; + +#define ATOMIC_FLAG_INIT { 0 } + +/* These should be provided by the libc implementation. */ +#ifdef __cplusplus +bool atomic_flag_test_and_set(volatile atomic_flag *); +bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order); +#else +_Bool atomic_flag_test_and_set(volatile atomic_flag *); +_Bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order); +#endif +void atomic_flag_clear(volatile atomic_flag *); +void atomic_flag_clear_explicit(volatile atomic_flag *, memory_order); + +#define atomic_flag_test_and_set(object) __c11_atomic_exchange(&(object)->_Value, 1, __ATOMIC_SEQ_CST) +#define atomic_flag_test_and_set_explicit(object, order) __c11_atomic_exchange(&(object)->_Value, 1, order) + +#define atomic_flag_clear(object) __c11_atomic_store(&(object)->_Value, 0, __ATOMIC_SEQ_CST) +#define atomic_flag_clear_explicit(object, order) __c11_atomic_store(&(object)->_Value, 0, order) + +#ifdef __cplusplus +} +#endif + +#endif /* __STDC_HOSTED__ */ +#endif /* __CLANG_STDATOMIC_H */ + diff --git a/headers/clang/stdbool.h b/headers/clang/stdbool.h new file mode 100644 index 0000000000..0467893f34 --- /dev/null +++ b/headers/clang/stdbool.h @@ -0,0 +1,44 @@ +/*===---- stdbool.h - Standard header for booleans -------------------------=== + * + * Copyright (c) 2008 Eli Friedman + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __STDBOOL_H +#define __STDBOOL_H + +/* Don't define bool, true, and false in C++, except as a GNU extension. */ +#ifndef __cplusplus +#define bool _Bool +#define true 1 +#define false 0 +#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) +/* Define _Bool, bool, false, true as a GNU extension. */ +#define _Bool bool +#define bool bool +#define false false +#define true true +#endif + +#define __bool_true_false_are_defined 1 + +#endif /* __STDBOOL_H */ diff --git a/headers/clang/stddef.h b/headers/clang/stddef.h new file mode 100644 index 0000000000..7354996711 --- /dev/null +++ b/headers/clang/stddef.h @@ -0,0 +1,137 @@ +/*===---- stddef.h - Basic type definitions --------------------------------=== + * + * Copyright (c) 2008 Eli Friedman + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#if !defined(__STDDEF_H) || defined(__need_ptrdiff_t) || \ + defined(__need_size_t) || defined(__need_wchar_t) || \ + defined(__need_NULL) || defined(__need_wint_t) + +#if !defined(__need_ptrdiff_t) && !defined(__need_size_t) && \ + !defined(__need_wchar_t) && !defined(__need_NULL) && \ + !defined(__need_wint_t) +/* Always define miscellaneous pieces when modules are available. */ +#if !__has_feature(modules) +#define __STDDEF_H +#endif +#define __need_ptrdiff_t +#define __need_size_t +#define __need_wchar_t +#define __need_NULL +#define __need_STDDEF_H_misc +/* __need_wint_t is intentionally not defined here. */ +#endif + +#if defined(__need_ptrdiff_t) +#if !defined(_PTRDIFF_T) || __has_feature(modules) +/* Always define ptrdiff_t when modules are available. */ +#if !__has_feature(modules) +#define _PTRDIFF_T +#endif +typedef __PTRDIFF_TYPE__ ptrdiff_t; +#endif +#undef __need_ptrdiff_t +#endif /* defined(__need_ptrdiff_t) */ + +#if defined(__need_size_t) +#if !defined(_SIZE_T) || __has_feature(modules) +/* Always define size_t when modules are available. */ +#if !__has_feature(modules) +#define _SIZE_T +#endif +typedef __SIZE_TYPE__ size_t; +#endif +#undef __need_size_t +#endif /*defined(__need_size_t) */ + +#if defined(__need_STDDEF_H_misc) +/* ISO9899:2011 7.20 (C11 Annex K): Define rsize_t if __STDC_WANT_LIB_EXT1__ is + * enabled. */ +#if (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 && \ + !defined(_RSIZE_T)) || __has_feature(modules) +/* Always define rsize_t when modules are available. */ +#if !__has_feature(modules) +#define _RSIZE_T +#endif +typedef __SIZE_TYPE__ rsize_t; +#endif +#endif /* defined(__need_STDDEF_H_misc) */ + +#if defined(__need_wchar_t) +#ifndef __cplusplus +/* Always define wchar_t when modules are available. */ +#if !defined(_WCHAR_T) || __has_feature(modules) +#if !__has_feature(modules) +#define _WCHAR_T +#if defined(_MSC_EXTENSIONS) +#define _WCHAR_T_DEFINED +#endif +#endif +typedef __WCHAR_TYPE__ wchar_t; +#endif +#endif +#undef __need_wchar_t +#endif /* defined(__need_wchar_t) */ + +#if defined(__need_NULL) +#undef NULL +#ifdef __cplusplus +# if !defined(__MINGW32__) && !defined(_MSC_VER) +# define NULL __null +# else +# define NULL 0 +# endif +#else +# define NULL ((void*)0) +#endif +#ifdef __cplusplus +#if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED) +namespace std { typedef decltype(nullptr) nullptr_t; } +using ::std::nullptr_t; +#endif +#endif +#undef __need_NULL +#endif /* defined(__need_NULL) */ + +#if defined(__need_STDDEF_H_misc) +#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L +#include "__stddef_max_align_t.h" +#endif +#define offsetof(t, d) __builtin_offsetof(t, d) +#undef __need_STDDEF_H_misc +#endif /* defined(__need_STDDEF_H_misc) */ + +/* Some C libraries expect to see a wint_t here. Others (notably MinGW) will use +__WINT_TYPE__ directly; accommodate both by requiring __need_wint_t */ +#if defined(__need_wint_t) +/* Always define wint_t when modules are available. */ +#if !defined(_WINT_T) || __has_feature(modules) +#if !__has_feature(modules) +#define _WINT_T +#endif +typedef __WINT_TYPE__ wint_t; +#endif +#undef __need_wint_t +#endif /* __need_wint_t */ + +#endif diff --git a/headers/clang/stdint.h b/headers/clang/stdint.h new file mode 100644 index 0000000000..3f2fcbc570 --- /dev/null +++ b/headers/clang/stdint.h @@ -0,0 +1,707 @@ +/*===---- stdint.h - Standard header for sized integer types --------------===*\ + * + * Copyright (c) 2009 Chris Lattner + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * +\*===----------------------------------------------------------------------===*/ + +#ifndef __CLANG_STDINT_H +#define __CLANG_STDINT_H + +/* If we're hosted, fall back to the system's stdint.h, which might have + * additional definitions. + */ +#if __STDC_HOSTED__ && __has_include_next() + +// C99 7.18.3 Limits of other integer types +// +// Footnote 219, 220: C++ implementations should define these macros only when +// __STDC_LIMIT_MACROS is defined before is included. +// +// Footnote 222: C++ implementations should define these macros only when +// __STDC_CONSTANT_MACROS is defined before is included. +// +// C++11 [cstdint.syn]p2: +// +// The macros defined by are provided unconditionally. In particular, +// the symbols __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS (mentioned in +// footnotes 219, 220, and 222 in the C standard) play no role in C++. +// +// C11 removed the problematic footnotes. +// +// Work around this inconsistency by always defining those macros in C++ mode, +// so that a C library implementation which follows the C99 standard can be +// used in C++. +# ifdef __cplusplus +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS +# define __STDC_LIMIT_MACROS_DEFINED_BY_CLANG +# endif +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS +# define __STDC_CONSTANT_MACROS_DEFINED_BY_CLANG +# endif +# endif + +# include_next + +# ifdef __STDC_LIMIT_MACROS_DEFINED_BY_CLANG +# undef __STDC_LIMIT_MACROS +# undef __STDC_LIMIT_MACROS_DEFINED_BY_CLANG +# endif +# ifdef __STDC_CONSTANT_MACROS_DEFINED_BY_CLANG +# undef __STDC_CONSTANT_MACROS +# undef __STDC_CONSTANT_MACROS_DEFINED_BY_CLANG +# endif + +#else + +/* C99 7.18.1.1 Exact-width integer types. + * C99 7.18.1.2 Minimum-width integer types. + * C99 7.18.1.3 Fastest minimum-width integer types. + * + * The standard requires that exact-width type be defined for 8-, 16-, 32-, and + * 64-bit types if they are implemented. Other exact width types are optional. + * This implementation defines an exact-width types for every integer width + * that is represented in the standard integer types. + * + * The standard also requires minimum-width types be defined for 8-, 16-, 32-, + * and 64-bit widths regardless of whether there are corresponding exact-width + * types. + * + * To accommodate targets that are missing types that are exactly 8, 16, 32, or + * 64 bits wide, this implementation takes an approach of cascading + * redefintions, redefining __int_leastN_t to successively smaller exact-width + * types. It is therefore important that the types are defined in order of + * descending widths. + * + * We currently assume that the minimum-width types and the fastest + * minimum-width types are the same. This is allowed by the standard, but is + * suboptimal. + * + * In violation of the standard, some targets do not implement a type that is + * wide enough to represent all of the required widths (8-, 16-, 32-, 64-bit). + * To accommodate these targets, a required minimum-width type is only + * defined if there exists an exact-width type of equal or greater width. + */ + +#ifdef __INT64_TYPE__ +# ifndef __int8_t_defined /* glibc sys/types.h also defines int64_t*/ +typedef __INT64_TYPE__ int64_t; +# endif /* __int8_t_defined */ +typedef __UINT64_TYPE__ uint64_t; +# define __int_least64_t int64_t +# define __uint_least64_t uint64_t +# define __int_least32_t int64_t +# define __uint_least32_t uint64_t +# define __int_least16_t int64_t +# define __uint_least16_t uint64_t +# define __int_least8_t int64_t +# define __uint_least8_t uint64_t +#endif /* __INT64_TYPE__ */ + +#ifdef __int_least64_t +typedef __int_least64_t int_least64_t; +typedef __uint_least64_t uint_least64_t; +typedef __int_least64_t int_fast64_t; +typedef __uint_least64_t uint_fast64_t; +#endif /* __int_least64_t */ + +#ifdef __INT56_TYPE__ +typedef __INT56_TYPE__ int56_t; +typedef __UINT56_TYPE__ uint56_t; +typedef int56_t int_least56_t; +typedef uint56_t uint_least56_t; +typedef int56_t int_fast56_t; +typedef uint56_t uint_fast56_t; +# define __int_least32_t int56_t +# define __uint_least32_t uint56_t +# define __int_least16_t int56_t +# define __uint_least16_t uint56_t +# define __int_least8_t int56_t +# define __uint_least8_t uint56_t +#endif /* __INT56_TYPE__ */ + + +#ifdef __INT48_TYPE__ +typedef __INT48_TYPE__ int48_t; +typedef __UINT48_TYPE__ uint48_t; +typedef int48_t int_least48_t; +typedef uint48_t uint_least48_t; +typedef int48_t int_fast48_t; +typedef uint48_t uint_fast48_t; +# define __int_least32_t int48_t +# define __uint_least32_t uint48_t +# define __int_least16_t int48_t +# define __uint_least16_t uint48_t +# define __int_least8_t int48_t +# define __uint_least8_t uint48_t +#endif /* __INT48_TYPE__ */ + + +#ifdef __INT40_TYPE__ +typedef __INT40_TYPE__ int40_t; +typedef __UINT40_TYPE__ uint40_t; +typedef int40_t int_least40_t; +typedef uint40_t uint_least40_t; +typedef int40_t int_fast40_t; +typedef uint40_t uint_fast40_t; +# define __int_least32_t int40_t +# define __uint_least32_t uint40_t +# define __int_least16_t int40_t +# define __uint_least16_t uint40_t +# define __int_least8_t int40_t +# define __uint_least8_t uint40_t +#endif /* __INT40_TYPE__ */ + + +#ifdef __INT32_TYPE__ + +# ifndef __int8_t_defined /* glibc sys/types.h also defines int32_t*/ +typedef __INT32_TYPE__ int32_t; +# endif /* __int8_t_defined */ + +# ifndef __uint32_t_defined /* more glibc compatibility */ +# define __uint32_t_defined +typedef __UINT32_TYPE__ uint32_t; +# endif /* __uint32_t_defined */ + +# define __int_least32_t int32_t +# define __uint_least32_t uint32_t +# define __int_least16_t int32_t +# define __uint_least16_t uint32_t +# define __int_least8_t int32_t +# define __uint_least8_t uint32_t +#endif /* __INT32_TYPE__ */ + +#ifdef __int_least32_t +typedef __int_least32_t int_least32_t; +typedef __uint_least32_t uint_least32_t; +typedef __int_least32_t int_fast32_t; +typedef __uint_least32_t uint_fast32_t; +#endif /* __int_least32_t */ + +#ifdef __INT24_TYPE__ +typedef __INT24_TYPE__ int24_t; +typedef __UINT24_TYPE__ uint24_t; +typedef int24_t int_least24_t; +typedef uint24_t uint_least24_t; +typedef int24_t int_fast24_t; +typedef uint24_t uint_fast24_t; +# define __int_least16_t int24_t +# define __uint_least16_t uint24_t +# define __int_least8_t int24_t +# define __uint_least8_t uint24_t +#endif /* __INT24_TYPE__ */ + +#ifdef __INT16_TYPE__ +#ifndef __int8_t_defined /* glibc sys/types.h also defines int16_t*/ +typedef __INT16_TYPE__ int16_t; +#endif /* __int8_t_defined */ +typedef __UINT16_TYPE__ uint16_t; +# define __int_least16_t int16_t +# define __uint_least16_t uint16_t +# define __int_least8_t int16_t +# define __uint_least8_t uint16_t +#endif /* __INT16_TYPE__ */ + +#ifdef __int_least16_t +typedef __int_least16_t int_least16_t; +typedef __uint_least16_t uint_least16_t; +typedef __int_least16_t int_fast16_t; +typedef __uint_least16_t uint_fast16_t; +#endif /* __int_least16_t */ + + +#ifdef __INT8_TYPE__ +#ifndef __int8_t_defined /* glibc sys/types.h also defines int8_t*/ +typedef __INT8_TYPE__ int8_t; +#endif /* __int8_t_defined */ +typedef __UINT8_TYPE__ uint8_t; +# define __int_least8_t int8_t +# define __uint_least8_t uint8_t +#endif /* __INT8_TYPE__ */ + +#ifdef __int_least8_t +typedef __int_least8_t int_least8_t; +typedef __uint_least8_t uint_least8_t; +typedef __int_least8_t int_fast8_t; +typedef __uint_least8_t uint_fast8_t; +#endif /* __int_least8_t */ + +/* prevent glibc sys/types.h from defining conflicting types */ +#ifndef __int8_t_defined +# define __int8_t_defined +#endif /* __int8_t_defined */ + +/* C99 7.18.1.4 Integer types capable of holding object pointers. + */ +#define __stdint_join3(a,b,c) a ## b ## c + +#define __intn_t(n) __stdint_join3( int, n, _t) +#define __uintn_t(n) __stdint_join3(uint, n, _t) + +#ifndef _INTPTR_T +#ifndef __intptr_t_defined +typedef __intn_t(__INTPTR_WIDTH__) intptr_t; +#define __intptr_t_defined +#define _INTPTR_T +#endif +#endif + +#ifndef _UINTPTR_T +typedef __uintn_t(__INTPTR_WIDTH__) uintptr_t; +#define _UINTPTR_T +#endif + +/* C99 7.18.1.5 Greatest-width integer types. + */ +typedef __INTMAX_TYPE__ intmax_t; +typedef __UINTMAX_TYPE__ uintmax_t; + +/* C99 7.18.4 Macros for minimum-width integer constants. + * + * The standard requires that integer constant macros be defined for all the + * minimum-width types defined above. As 8-, 16-, 32-, and 64-bit minimum-width + * types are required, the corresponding integer constant macros are defined + * here. This implementation also defines minimum-width types for every other + * integer width that the target implements, so corresponding macros are + * defined below, too. + * + * These macros are defined using the same successive-shrinking approach as + * the type definitions above. It is likewise important that macros are defined + * in order of decending width. + * + * Note that C++ should not check __STDC_CONSTANT_MACROS here, contrary to the + * claims of the C standard (see C++ 18.3.1p2, [cstdint.syn]). + */ + +#define __int_c_join(a, b) a ## b +#define __int_c(v, suffix) __int_c_join(v, suffix) +#define __uint_c(v, suffix) __int_c_join(v##U, suffix) + + +#ifdef __INT64_TYPE__ +# ifdef __INT64_C_SUFFIX__ +# define __int64_c_suffix __INT64_C_SUFFIX__ +# define __int32_c_suffix __INT64_C_SUFFIX__ +# define __int16_c_suffix __INT64_C_SUFFIX__ +# define __int8_c_suffix __INT64_C_SUFFIX__ +# else +# undef __int64_c_suffix +# undef __int32_c_suffix +# undef __int16_c_suffix +# undef __int8_c_suffix +# endif /* __INT64_C_SUFFIX__ */ +#endif /* __INT64_TYPE__ */ + +#ifdef __int_least64_t +# ifdef __int64_c_suffix +# define INT64_C(v) __int_c(v, __int64_c_suffix) +# define UINT64_C(v) __uint_c(v, __int64_c_suffix) +# else +# define INT64_C(v) v +# define UINT64_C(v) v ## U +# endif /* __int64_c_suffix */ +#endif /* __int_least64_t */ + + +#ifdef __INT56_TYPE__ +# ifdef __INT56_C_SUFFIX__ +# define INT56_C(v) __int_c(v, __INT56_C_SUFFIX__) +# define UINT56_C(v) __uint_c(v, __INT56_C_SUFFIX__) +# define __int32_c_suffix __INT56_C_SUFFIX__ +# define __int16_c_suffix __INT56_C_SUFFIX__ +# define __int8_c_suffix __INT56_C_SUFFIX__ +# else +# define INT56_C(v) v +# define UINT56_C(v) v ## U +# undef __int32_c_suffix +# undef __int16_c_suffix +# undef __int8_c_suffix +# endif /* __INT56_C_SUFFIX__ */ +#endif /* __INT56_TYPE__ */ + + +#ifdef __INT48_TYPE__ +# ifdef __INT48_C_SUFFIX__ +# define INT48_C(v) __int_c(v, __INT48_C_SUFFIX__) +# define UINT48_C(v) __uint_c(v, __INT48_C_SUFFIX__) +# define __int32_c_suffix __INT48_C_SUFFIX__ +# define __int16_c_suffix __INT48_C_SUFFIX__ +# define __int8_c_suffix __INT48_C_SUFFIX__ +# else +# define INT48_C(v) v +# define UINT48_C(v) v ## U +# undef __int32_c_suffix +# undef __int16_c_suffix +# undef __int8_c_suffix +# endif /* __INT48_C_SUFFIX__ */ +#endif /* __INT48_TYPE__ */ + + +#ifdef __INT40_TYPE__ +# ifdef __INT40_C_SUFFIX__ +# define INT40_C(v) __int_c(v, __INT40_C_SUFFIX__) +# define UINT40_C(v) __uint_c(v, __INT40_C_SUFFIX__) +# define __int32_c_suffix __INT40_C_SUFFIX__ +# define __int16_c_suffix __INT40_C_SUFFIX__ +# define __int8_c_suffix __INT40_C_SUFFIX__ +# else +# define INT40_C(v) v +# define UINT40_C(v) v ## U +# undef __int32_c_suffix +# undef __int16_c_suffix +# undef __int8_c_suffix +# endif /* __INT40_C_SUFFIX__ */ +#endif /* __INT40_TYPE__ */ + + +#ifdef __INT32_TYPE__ +# ifdef __INT32_C_SUFFIX__ +# define __int32_c_suffix __INT32_C_SUFFIX__ +# define __int16_c_suffix __INT32_C_SUFFIX__ +# define __int8_c_suffix __INT32_C_SUFFIX__ +#else +# undef __int32_c_suffix +# undef __int16_c_suffix +# undef __int8_c_suffix +# endif /* __INT32_C_SUFFIX__ */ +#endif /* __INT32_TYPE__ */ + +#ifdef __int_least32_t +# ifdef __int32_c_suffix +# define INT32_C(v) __int_c(v, __int32_c_suffix) +# define UINT32_C(v) __uint_c(v, __int32_c_suffix) +# else +# define INT32_C(v) v +# define UINT32_C(v) v ## U +# endif /* __int32_c_suffix */ +#endif /* __int_least32_t */ + + +#ifdef __INT24_TYPE__ +# ifdef __INT24_C_SUFFIX__ +# define INT24_C(v) __int_c(v, __INT24_C_SUFFIX__) +# define UINT24_C(v) __uint_c(v, __INT24_C_SUFFIX__) +# define __int16_c_suffix __INT24_C_SUFFIX__ +# define __int8_c_suffix __INT24_C_SUFFIX__ +# else +# define INT24_C(v) v +# define UINT24_C(v) v ## U +# undef __int16_c_suffix +# undef __int8_c_suffix +# endif /* __INT24_C_SUFFIX__ */ +#endif /* __INT24_TYPE__ */ + + +#ifdef __INT16_TYPE__ +# ifdef __INT16_C_SUFFIX__ +# define __int16_c_suffix __INT16_C_SUFFIX__ +# define __int8_c_suffix __INT16_C_SUFFIX__ +#else +# undef __int16_c_suffix +# undef __int8_c_suffix +# endif /* __INT16_C_SUFFIX__ */ +#endif /* __INT16_TYPE__ */ + +#ifdef __int_least16_t +# ifdef __int16_c_suffix +# define INT16_C(v) __int_c(v, __int16_c_suffix) +# define UINT16_C(v) __uint_c(v, __int16_c_suffix) +# else +# define INT16_C(v) v +# define UINT16_C(v) v ## U +# endif /* __int16_c_suffix */ +#endif /* __int_least16_t */ + + +#ifdef __INT8_TYPE__ +# ifdef __INT8_C_SUFFIX__ +# define __int8_c_suffix __INT8_C_SUFFIX__ +#else +# undef __int8_c_suffix +# endif /* __INT8_C_SUFFIX__ */ +#endif /* __INT8_TYPE__ */ + +#ifdef __int_least8_t +# ifdef __int8_c_suffix +# define INT8_C(v) __int_c(v, __int8_c_suffix) +# define UINT8_C(v) __uint_c(v, __int8_c_suffix) +# else +# define INT8_C(v) v +# define UINT8_C(v) v ## U +# endif /* __int8_c_suffix */ +#endif /* __int_least8_t */ + + +/* C99 7.18.2.1 Limits of exact-width integer types. + * C99 7.18.2.2 Limits of minimum-width integer types. + * C99 7.18.2.3 Limits of fastest minimum-width integer types. + * + * The presence of limit macros are completely optional in C99. This + * implementation defines limits for all of the types (exact- and + * minimum-width) that it defines above, using the limits of the minimum-width + * type for any types that do not have exact-width representations. + * + * As in the type definitions, this section takes an approach of + * successive-shrinking to determine which limits to use for the standard (8, + * 16, 32, 64) bit widths when they don't have exact representations. It is + * therefore important that the defintions be kept in order of decending + * widths. + * + * Note that C++ should not check __STDC_LIMIT_MACROS here, contrary to the + * claims of the C standard (see C++ 18.3.1p2, [cstdint.syn]). + */ + +#ifdef __INT64_TYPE__ +# define INT64_MAX INT64_C( 9223372036854775807) +# define INT64_MIN (-INT64_C( 9223372036854775807)-1) +# define UINT64_MAX UINT64_C(18446744073709551615) +# define __INT_LEAST64_MIN INT64_MIN +# define __INT_LEAST64_MAX INT64_MAX +# define __UINT_LEAST64_MAX UINT64_MAX +# define __INT_LEAST32_MIN INT64_MIN +# define __INT_LEAST32_MAX INT64_MAX +# define __UINT_LEAST32_MAX UINT64_MAX +# define __INT_LEAST16_MIN INT64_MIN +# define __INT_LEAST16_MAX INT64_MAX +# define __UINT_LEAST16_MAX UINT64_MAX +# define __INT_LEAST8_MIN INT64_MIN +# define __INT_LEAST8_MAX INT64_MAX +# define __UINT_LEAST8_MAX UINT64_MAX +#endif /* __INT64_TYPE__ */ + +#ifdef __INT_LEAST64_MIN +# define INT_LEAST64_MIN __INT_LEAST64_MIN +# define INT_LEAST64_MAX __INT_LEAST64_MAX +# define UINT_LEAST64_MAX __UINT_LEAST64_MAX +# define INT_FAST64_MIN __INT_LEAST64_MIN +# define INT_FAST64_MAX __INT_LEAST64_MAX +# define UINT_FAST64_MAX __UINT_LEAST64_MAX +#endif /* __INT_LEAST64_MIN */ + + +#ifdef __INT56_TYPE__ +# define INT56_MAX INT56_C(36028797018963967) +# define INT56_MIN (-INT56_C(36028797018963967)-1) +# define UINT56_MAX UINT56_C(72057594037927935) +# define INT_LEAST56_MIN INT56_MIN +# define INT_LEAST56_MAX INT56_MAX +# define UINT_LEAST56_MAX UINT56_MAX +# define INT_FAST56_MIN INT56_MIN +# define INT_FAST56_MAX INT56_MAX +# define UINT_FAST56_MAX UINT56_MAX +# define __INT_LEAST32_MIN INT56_MIN +# define __INT_LEAST32_MAX INT56_MAX +# define __UINT_LEAST32_MAX UINT56_MAX +# define __INT_LEAST16_MIN INT56_MIN +# define __INT_LEAST16_MAX INT56_MAX +# define __UINT_LEAST16_MAX UINT56_MAX +# define __INT_LEAST8_MIN INT56_MIN +# define __INT_LEAST8_MAX INT56_MAX +# define __UINT_LEAST8_MAX UINT56_MAX +#endif /* __INT56_TYPE__ */ + + +#ifdef __INT48_TYPE__ +# define INT48_MAX INT48_C(140737488355327) +# define INT48_MIN (-INT48_C(140737488355327)-1) +# define UINT48_MAX UINT48_C(281474976710655) +# define INT_LEAST48_MIN INT48_MIN +# define INT_LEAST48_MAX INT48_MAX +# define UINT_LEAST48_MAX UINT48_MAX +# define INT_FAST48_MIN INT48_MIN +# define INT_FAST48_MAX INT48_MAX +# define UINT_FAST48_MAX UINT48_MAX +# define __INT_LEAST32_MIN INT48_MIN +# define __INT_LEAST32_MAX INT48_MAX +# define __UINT_LEAST32_MAX UINT48_MAX +# define __INT_LEAST16_MIN INT48_MIN +# define __INT_LEAST16_MAX INT48_MAX +# define __UINT_LEAST16_MAX UINT48_MAX +# define __INT_LEAST8_MIN INT48_MIN +# define __INT_LEAST8_MAX INT48_MAX +# define __UINT_LEAST8_MAX UINT48_MAX +#endif /* __INT48_TYPE__ */ + + +#ifdef __INT40_TYPE__ +# define INT40_MAX INT40_C(549755813887) +# define INT40_MIN (-INT40_C(549755813887)-1) +# define UINT40_MAX UINT40_C(1099511627775) +# define INT_LEAST40_MIN INT40_MIN +# define INT_LEAST40_MAX INT40_MAX +# define UINT_LEAST40_MAX UINT40_MAX +# define INT_FAST40_MIN INT40_MIN +# define INT_FAST40_MAX INT40_MAX +# define UINT_FAST40_MAX UINT40_MAX +# define __INT_LEAST32_MIN INT40_MIN +# define __INT_LEAST32_MAX INT40_MAX +# define __UINT_LEAST32_MAX UINT40_MAX +# define __INT_LEAST16_MIN INT40_MIN +# define __INT_LEAST16_MAX INT40_MAX +# define __UINT_LEAST16_MAX UINT40_MAX +# define __INT_LEAST8_MIN INT40_MIN +# define __INT_LEAST8_MAX INT40_MAX +# define __UINT_LEAST8_MAX UINT40_MAX +#endif /* __INT40_TYPE__ */ + + +#ifdef __INT32_TYPE__ +# define INT32_MAX INT32_C(2147483647) +# define INT32_MIN (-INT32_C(2147483647)-1) +# define UINT32_MAX UINT32_C(4294967295) +# define __INT_LEAST32_MIN INT32_MIN +# define __INT_LEAST32_MAX INT32_MAX +# define __UINT_LEAST32_MAX UINT32_MAX +# define __INT_LEAST16_MIN INT32_MIN +# define __INT_LEAST16_MAX INT32_MAX +# define __UINT_LEAST16_MAX UINT32_MAX +# define __INT_LEAST8_MIN INT32_MIN +# define __INT_LEAST8_MAX INT32_MAX +# define __UINT_LEAST8_MAX UINT32_MAX +#endif /* __INT32_TYPE__ */ + +#ifdef __INT_LEAST32_MIN +# define INT_LEAST32_MIN __INT_LEAST32_MIN +# define INT_LEAST32_MAX __INT_LEAST32_MAX +# define UINT_LEAST32_MAX __UINT_LEAST32_MAX +# define INT_FAST32_MIN __INT_LEAST32_MIN +# define INT_FAST32_MAX __INT_LEAST32_MAX +# define UINT_FAST32_MAX __UINT_LEAST32_MAX +#endif /* __INT_LEAST32_MIN */ + + +#ifdef __INT24_TYPE__ +# define INT24_MAX INT24_C(8388607) +# define INT24_MIN (-INT24_C(8388607)-1) +# define UINT24_MAX UINT24_C(16777215) +# define INT_LEAST24_MIN INT24_MIN +# define INT_LEAST24_MAX INT24_MAX +# define UINT_LEAST24_MAX UINT24_MAX +# define INT_FAST24_MIN INT24_MIN +# define INT_FAST24_MAX INT24_MAX +# define UINT_FAST24_MAX UINT24_MAX +# define __INT_LEAST16_MIN INT24_MIN +# define __INT_LEAST16_MAX INT24_MAX +# define __UINT_LEAST16_MAX UINT24_MAX +# define __INT_LEAST8_MIN INT24_MIN +# define __INT_LEAST8_MAX INT24_MAX +# define __UINT_LEAST8_MAX UINT24_MAX +#endif /* __INT24_TYPE__ */ + + +#ifdef __INT16_TYPE__ +#define INT16_MAX INT16_C(32767) +#define INT16_MIN (-INT16_C(32767)-1) +#define UINT16_MAX UINT16_C(65535) +# define __INT_LEAST16_MIN INT16_MIN +# define __INT_LEAST16_MAX INT16_MAX +# define __UINT_LEAST16_MAX UINT16_MAX +# define __INT_LEAST8_MIN INT16_MIN +# define __INT_LEAST8_MAX INT16_MAX +# define __UINT_LEAST8_MAX UINT16_MAX +#endif /* __INT16_TYPE__ */ + +#ifdef __INT_LEAST16_MIN +# define INT_LEAST16_MIN __INT_LEAST16_MIN +# define INT_LEAST16_MAX __INT_LEAST16_MAX +# define UINT_LEAST16_MAX __UINT_LEAST16_MAX +# define INT_FAST16_MIN __INT_LEAST16_MIN +# define INT_FAST16_MAX __INT_LEAST16_MAX +# define UINT_FAST16_MAX __UINT_LEAST16_MAX +#endif /* __INT_LEAST16_MIN */ + + +#ifdef __INT8_TYPE__ +# define INT8_MAX INT8_C(127) +# define INT8_MIN (-INT8_C(127)-1) +# define UINT8_MAX UINT8_C(255) +# define __INT_LEAST8_MIN INT8_MIN +# define __INT_LEAST8_MAX INT8_MAX +# define __UINT_LEAST8_MAX UINT8_MAX +#endif /* __INT8_TYPE__ */ + +#ifdef __INT_LEAST8_MIN +# define INT_LEAST8_MIN __INT_LEAST8_MIN +# define INT_LEAST8_MAX __INT_LEAST8_MAX +# define UINT_LEAST8_MAX __UINT_LEAST8_MAX +# define INT_FAST8_MIN __INT_LEAST8_MIN +# define INT_FAST8_MAX __INT_LEAST8_MAX +# define UINT_FAST8_MAX __UINT_LEAST8_MAX +#endif /* __INT_LEAST8_MIN */ + +/* Some utility macros */ +#define __INTN_MIN(n) __stdint_join3( INT, n, _MIN) +#define __INTN_MAX(n) __stdint_join3( INT, n, _MAX) +#define __UINTN_MAX(n) __stdint_join3(UINT, n, _MAX) +#define __INTN_C(n, v) __stdint_join3( INT, n, _C(v)) +#define __UINTN_C(n, v) __stdint_join3(UINT, n, _C(v)) + +/* C99 7.18.2.4 Limits of integer types capable of holding object pointers. */ +/* C99 7.18.3 Limits of other integer types. */ + +#define INTPTR_MIN __INTN_MIN(__INTPTR_WIDTH__) +#define INTPTR_MAX __INTN_MAX(__INTPTR_WIDTH__) +#define UINTPTR_MAX __UINTN_MAX(__INTPTR_WIDTH__) +#define PTRDIFF_MIN __INTN_MIN(__PTRDIFF_WIDTH__) +#define PTRDIFF_MAX __INTN_MAX(__PTRDIFF_WIDTH__) +#define SIZE_MAX __UINTN_MAX(__SIZE_WIDTH__) + +/* ISO9899:2011 7.20 (C11 Annex K): Define RSIZE_MAX if __STDC_WANT_LIB_EXT1__ + * is enabled. */ +#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 +#define RSIZE_MAX (SIZE_MAX >> 1) +#endif + +/* C99 7.18.2.5 Limits of greatest-width integer types. */ +#define INTMAX_MIN __INTN_MIN(__INTMAX_WIDTH__) +#define INTMAX_MAX __INTN_MAX(__INTMAX_WIDTH__) +#define UINTMAX_MAX __UINTN_MAX(__INTMAX_WIDTH__) + +/* C99 7.18.3 Limits of other integer types. */ +#define SIG_ATOMIC_MIN __INTN_MIN(__SIG_ATOMIC_WIDTH__) +#define SIG_ATOMIC_MAX __INTN_MAX(__SIG_ATOMIC_WIDTH__) +#ifdef __WINT_UNSIGNED__ +# define WINT_MIN __UINTN_C(__WINT_WIDTH__, 0) +# define WINT_MAX __UINTN_MAX(__WINT_WIDTH__) +#else +# define WINT_MIN __INTN_MIN(__WINT_WIDTH__) +# define WINT_MAX __INTN_MAX(__WINT_WIDTH__) +#endif + +#ifndef WCHAR_MAX +# define WCHAR_MAX __WCHAR_MAX__ +#endif +#ifndef WCHAR_MIN +# if __WCHAR_MAX__ == __INTN_MAX(__WCHAR_WIDTH__) +# define WCHAR_MIN __INTN_MIN(__WCHAR_WIDTH__) +# else +# define WCHAR_MIN __UINTN_C(__WCHAR_WIDTH__, 0) +# endif +#endif + +/* 7.18.4.2 Macros for greatest-width integer constants. */ +#define INTMAX_C(v) __INTN_C(__INTMAX_WIDTH__, v) +#define UINTMAX_C(v) __UINTN_C(__INTMAX_WIDTH__, v) + +#endif /* __STDC_HOSTED__ */ +#endif /* __CLANG_STDINT_H */ diff --git a/headers/clang/stdnoreturn.h b/headers/clang/stdnoreturn.h new file mode 100644 index 0000000000..a7a301d7e0 --- /dev/null +++ b/headers/clang/stdnoreturn.h @@ -0,0 +1,30 @@ +/*===---- stdnoreturn.h - Standard header for noreturn macro ---------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __STDNORETURN_H +#define __STDNORETURN_H + +#define noreturn _Noreturn +#define __noreturn_is_defined 1 + +#endif /* __STDNORETURN_H */ diff --git a/headers/clang/tbmintrin.h b/headers/clang/tbmintrin.h new file mode 100644 index 0000000000..62f613f9ee --- /dev/null +++ b/headers/clang/tbmintrin.h @@ -0,0 +1,150 @@ +/*===---- tbmintrin.h - TBM intrinsics -------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __X86INTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __TBMINTRIN_H +#define __TBMINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("tbm"))) + +#define __bextri_u32(a, b) (__builtin_ia32_bextri_u32((a), (b))) + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__blcfill_u32(unsigned int a) +{ + return a & (a + 1); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__blci_u32(unsigned int a) +{ + return a | ~(a + 1); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__blcic_u32(unsigned int a) +{ + return ~a & (a + 1); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__blcmsk_u32(unsigned int a) +{ + return a ^ (a + 1); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__blcs_u32(unsigned int a) +{ + return a | (a + 1); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__blsfill_u32(unsigned int a) +{ + return a | (a - 1); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__blsic_u32(unsigned int a) +{ + return ~a | (a - 1); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__t1mskc_u32(unsigned int a) +{ + return ~a | (a + 1); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +__tzmsk_u32(unsigned int a) +{ + return ~a & (a - 1); +} + +#ifdef __x86_64__ +#define __bextri_u64(a, b) (__builtin_ia32_bextri_u64((a), (int)(b))) + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__blcfill_u64(unsigned long long a) +{ + return a & (a + 1); +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__blci_u64(unsigned long long a) +{ + return a | ~(a + 1); +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__blcic_u64(unsigned long long a) +{ + return ~a & (a + 1); +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__blcmsk_u64(unsigned long long a) +{ + return a ^ (a + 1); +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__blcs_u64(unsigned long long a) +{ + return a | (a + 1); +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__blsfill_u64(unsigned long long a) +{ + return a | (a - 1); +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__blsic_u64(unsigned long long a) +{ + return ~a | (a - 1); +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__t1mskc_u64(unsigned long long a) +{ + return ~a | (a + 1); +} + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS +__tzmsk_u64(unsigned long long a) +{ + return ~a & (a - 1); +} +#endif + +#undef __DEFAULT_FN_ATTRS + +#endif /* __TBMINTRIN_H */ diff --git a/headers/clang/tgmath.h b/headers/clang/tgmath.h new file mode 100644 index 0000000000..318e1185fe --- /dev/null +++ b/headers/clang/tgmath.h @@ -0,0 +1,1374 @@ +/*===---- tgmath.h - Standard header for type generic math ----------------===*\ + * + * Copyright (c) 2009 Howard Hinnant + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * +\*===----------------------------------------------------------------------===*/ + +#ifndef __TGMATH_H +#define __TGMATH_H + +/* C99 7.22 Type-generic math . */ +#include + +/* C++ handles type genericity with overloading in math.h. */ +#ifndef __cplusplus +#include + +#define _TG_ATTRSp __attribute__((__overloadable__)) +#define _TG_ATTRS __attribute__((__overloadable__, __always_inline__)) + +// promotion + +typedef void _Argument_type_is_not_arithmetic; +static _Argument_type_is_not_arithmetic __tg_promote(...) + __attribute__((__unavailable__,__overloadable__)); +static double _TG_ATTRSp __tg_promote(int); +static double _TG_ATTRSp __tg_promote(unsigned int); +static double _TG_ATTRSp __tg_promote(long); +static double _TG_ATTRSp __tg_promote(unsigned long); +static double _TG_ATTRSp __tg_promote(long long); +static double _TG_ATTRSp __tg_promote(unsigned long long); +static float _TG_ATTRSp __tg_promote(float); +static double _TG_ATTRSp __tg_promote(double); +static long double _TG_ATTRSp __tg_promote(long double); +static float _Complex _TG_ATTRSp __tg_promote(float _Complex); +static double _Complex _TG_ATTRSp __tg_promote(double _Complex); +static long double _Complex _TG_ATTRSp __tg_promote(long double _Complex); + +#define __tg_promote1(__x) (__typeof__(__tg_promote(__x))) +#define __tg_promote2(__x, __y) (__typeof__(__tg_promote(__x) + \ + __tg_promote(__y))) +#define __tg_promote3(__x, __y, __z) (__typeof__(__tg_promote(__x) + \ + __tg_promote(__y) + \ + __tg_promote(__z))) + +// acos + +static float + _TG_ATTRS + __tg_acos(float __x) {return acosf(__x);} + +static double + _TG_ATTRS + __tg_acos(double __x) {return acos(__x);} + +static long double + _TG_ATTRS + __tg_acos(long double __x) {return acosl(__x);} + +static float _Complex + _TG_ATTRS + __tg_acos(float _Complex __x) {return cacosf(__x);} + +static double _Complex + _TG_ATTRS + __tg_acos(double _Complex __x) {return cacos(__x);} + +static long double _Complex + _TG_ATTRS + __tg_acos(long double _Complex __x) {return cacosl(__x);} + +#undef acos +#define acos(__x) __tg_acos(__tg_promote1((__x))(__x)) + +// asin + +static float + _TG_ATTRS + __tg_asin(float __x) {return asinf(__x);} + +static double + _TG_ATTRS + __tg_asin(double __x) {return asin(__x);} + +static long double + _TG_ATTRS + __tg_asin(long double __x) {return asinl(__x);} + +static float _Complex + _TG_ATTRS + __tg_asin(float _Complex __x) {return casinf(__x);} + +static double _Complex + _TG_ATTRS + __tg_asin(double _Complex __x) {return casin(__x);} + +static long double _Complex + _TG_ATTRS + __tg_asin(long double _Complex __x) {return casinl(__x);} + +#undef asin +#define asin(__x) __tg_asin(__tg_promote1((__x))(__x)) + +// atan + +static float + _TG_ATTRS + __tg_atan(float __x) {return atanf(__x);} + +static double + _TG_ATTRS + __tg_atan(double __x) {return atan(__x);} + +static long double + _TG_ATTRS + __tg_atan(long double __x) {return atanl(__x);} + +static float _Complex + _TG_ATTRS + __tg_atan(float _Complex __x) {return catanf(__x);} + +static double _Complex + _TG_ATTRS + __tg_atan(double _Complex __x) {return catan(__x);} + +static long double _Complex + _TG_ATTRS + __tg_atan(long double _Complex __x) {return catanl(__x);} + +#undef atan +#define atan(__x) __tg_atan(__tg_promote1((__x))(__x)) + +// acosh + +static float + _TG_ATTRS + __tg_acosh(float __x) {return acoshf(__x);} + +static double + _TG_ATTRS + __tg_acosh(double __x) {return acosh(__x);} + +static long double + _TG_ATTRS + __tg_acosh(long double __x) {return acoshl(__x);} + +static float _Complex + _TG_ATTRS + __tg_acosh(float _Complex __x) {return cacoshf(__x);} + +static double _Complex + _TG_ATTRS + __tg_acosh(double _Complex __x) {return cacosh(__x);} + +static long double _Complex + _TG_ATTRS + __tg_acosh(long double _Complex __x) {return cacoshl(__x);} + +#undef acosh +#define acosh(__x) __tg_acosh(__tg_promote1((__x))(__x)) + +// asinh + +static float + _TG_ATTRS + __tg_asinh(float __x) {return asinhf(__x);} + +static double + _TG_ATTRS + __tg_asinh(double __x) {return asinh(__x);} + +static long double + _TG_ATTRS + __tg_asinh(long double __x) {return asinhl(__x);} + +static float _Complex + _TG_ATTRS + __tg_asinh(float _Complex __x) {return casinhf(__x);} + +static double _Complex + _TG_ATTRS + __tg_asinh(double _Complex __x) {return casinh(__x);} + +static long double _Complex + _TG_ATTRS + __tg_asinh(long double _Complex __x) {return casinhl(__x);} + +#undef asinh +#define asinh(__x) __tg_asinh(__tg_promote1((__x))(__x)) + +// atanh + +static float + _TG_ATTRS + __tg_atanh(float __x) {return atanhf(__x);} + +static double + _TG_ATTRS + __tg_atanh(double __x) {return atanh(__x);} + +static long double + _TG_ATTRS + __tg_atanh(long double __x) {return atanhl(__x);} + +static float _Complex + _TG_ATTRS + __tg_atanh(float _Complex __x) {return catanhf(__x);} + +static double _Complex + _TG_ATTRS + __tg_atanh(double _Complex __x) {return catanh(__x);} + +static long double _Complex + _TG_ATTRS + __tg_atanh(long double _Complex __x) {return catanhl(__x);} + +#undef atanh +#define atanh(__x) __tg_atanh(__tg_promote1((__x))(__x)) + +// cos + +static float + _TG_ATTRS + __tg_cos(float __x) {return cosf(__x);} + +static double + _TG_ATTRS + __tg_cos(double __x) {return cos(__x);} + +static long double + _TG_ATTRS + __tg_cos(long double __x) {return cosl(__x);} + +static float _Complex + _TG_ATTRS + __tg_cos(float _Complex __x) {return ccosf(__x);} + +static double _Complex + _TG_ATTRS + __tg_cos(double _Complex __x) {return ccos(__x);} + +static long double _Complex + _TG_ATTRS + __tg_cos(long double _Complex __x) {return ccosl(__x);} + +#undef cos +#define cos(__x) __tg_cos(__tg_promote1((__x))(__x)) + +// sin + +static float + _TG_ATTRS + __tg_sin(float __x) {return sinf(__x);} + +static double + _TG_ATTRS + __tg_sin(double __x) {return sin(__x);} + +static long double + _TG_ATTRS + __tg_sin(long double __x) {return sinl(__x);} + +static float _Complex + _TG_ATTRS + __tg_sin(float _Complex __x) {return csinf(__x);} + +static double _Complex + _TG_ATTRS + __tg_sin(double _Complex __x) {return csin(__x);} + +static long double _Complex + _TG_ATTRS + __tg_sin(long double _Complex __x) {return csinl(__x);} + +#undef sin +#define sin(__x) __tg_sin(__tg_promote1((__x))(__x)) + +// tan + +static float + _TG_ATTRS + __tg_tan(float __x) {return tanf(__x);} + +static double + _TG_ATTRS + __tg_tan(double __x) {return tan(__x);} + +static long double + _TG_ATTRS + __tg_tan(long double __x) {return tanl(__x);} + +static float _Complex + _TG_ATTRS + __tg_tan(float _Complex __x) {return ctanf(__x);} + +static double _Complex + _TG_ATTRS + __tg_tan(double _Complex __x) {return ctan(__x);} + +static long double _Complex + _TG_ATTRS + __tg_tan(long double _Complex __x) {return ctanl(__x);} + +#undef tan +#define tan(__x) __tg_tan(__tg_promote1((__x))(__x)) + +// cosh + +static float + _TG_ATTRS + __tg_cosh(float __x) {return coshf(__x);} + +static double + _TG_ATTRS + __tg_cosh(double __x) {return cosh(__x);} + +static long double + _TG_ATTRS + __tg_cosh(long double __x) {return coshl(__x);} + +static float _Complex + _TG_ATTRS + __tg_cosh(float _Complex __x) {return ccoshf(__x);} + +static double _Complex + _TG_ATTRS + __tg_cosh(double _Complex __x) {return ccosh(__x);} + +static long double _Complex + _TG_ATTRS + __tg_cosh(long double _Complex __x) {return ccoshl(__x);} + +#undef cosh +#define cosh(__x) __tg_cosh(__tg_promote1((__x))(__x)) + +// sinh + +static float + _TG_ATTRS + __tg_sinh(float __x) {return sinhf(__x);} + +static double + _TG_ATTRS + __tg_sinh(double __x) {return sinh(__x);} + +static long double + _TG_ATTRS + __tg_sinh(long double __x) {return sinhl(__x);} + +static float _Complex + _TG_ATTRS + __tg_sinh(float _Complex __x) {return csinhf(__x);} + +static double _Complex + _TG_ATTRS + __tg_sinh(double _Complex __x) {return csinh(__x);} + +static long double _Complex + _TG_ATTRS + __tg_sinh(long double _Complex __x) {return csinhl(__x);} + +#undef sinh +#define sinh(__x) __tg_sinh(__tg_promote1((__x))(__x)) + +// tanh + +static float + _TG_ATTRS + __tg_tanh(float __x) {return tanhf(__x);} + +static double + _TG_ATTRS + __tg_tanh(double __x) {return tanh(__x);} + +static long double + _TG_ATTRS + __tg_tanh(long double __x) {return tanhl(__x);} + +static float _Complex + _TG_ATTRS + __tg_tanh(float _Complex __x) {return ctanhf(__x);} + +static double _Complex + _TG_ATTRS + __tg_tanh(double _Complex __x) {return ctanh(__x);} + +static long double _Complex + _TG_ATTRS + __tg_tanh(long double _Complex __x) {return ctanhl(__x);} + +#undef tanh +#define tanh(__x) __tg_tanh(__tg_promote1((__x))(__x)) + +// exp + +static float + _TG_ATTRS + __tg_exp(float __x) {return expf(__x);} + +static double + _TG_ATTRS + __tg_exp(double __x) {return exp(__x);} + +static long double + _TG_ATTRS + __tg_exp(long double __x) {return expl(__x);} + +static float _Complex + _TG_ATTRS + __tg_exp(float _Complex __x) {return cexpf(__x);} + +static double _Complex + _TG_ATTRS + __tg_exp(double _Complex __x) {return cexp(__x);} + +static long double _Complex + _TG_ATTRS + __tg_exp(long double _Complex __x) {return cexpl(__x);} + +#undef exp +#define exp(__x) __tg_exp(__tg_promote1((__x))(__x)) + +// log + +static float + _TG_ATTRS + __tg_log(float __x) {return logf(__x);} + +static double + _TG_ATTRS + __tg_log(double __x) {return log(__x);} + +static long double + _TG_ATTRS + __tg_log(long double __x) {return logl(__x);} + +static float _Complex + _TG_ATTRS + __tg_log(float _Complex __x) {return clogf(__x);} + +static double _Complex + _TG_ATTRS + __tg_log(double _Complex __x) {return clog(__x);} + +static long double _Complex + _TG_ATTRS + __tg_log(long double _Complex __x) {return clogl(__x);} + +#undef log +#define log(__x) __tg_log(__tg_promote1((__x))(__x)) + +// pow + +static float + _TG_ATTRS + __tg_pow(float __x, float __y) {return powf(__x, __y);} + +static double + _TG_ATTRS + __tg_pow(double __x, double __y) {return pow(__x, __y);} + +static long double + _TG_ATTRS + __tg_pow(long double __x, long double __y) {return powl(__x, __y);} + +static float _Complex + _TG_ATTRS + __tg_pow(float _Complex __x, float _Complex __y) {return cpowf(__x, __y);} + +static double _Complex + _TG_ATTRS + __tg_pow(double _Complex __x, double _Complex __y) {return cpow(__x, __y);} + +static long double _Complex + _TG_ATTRS + __tg_pow(long double _Complex __x, long double _Complex __y) + {return cpowl(__x, __y);} + +#undef pow +#define pow(__x, __y) __tg_pow(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// sqrt + +static float + _TG_ATTRS + __tg_sqrt(float __x) {return sqrtf(__x);} + +static double + _TG_ATTRS + __tg_sqrt(double __x) {return sqrt(__x);} + +static long double + _TG_ATTRS + __tg_sqrt(long double __x) {return sqrtl(__x);} + +static float _Complex + _TG_ATTRS + __tg_sqrt(float _Complex __x) {return csqrtf(__x);} + +static double _Complex + _TG_ATTRS + __tg_sqrt(double _Complex __x) {return csqrt(__x);} + +static long double _Complex + _TG_ATTRS + __tg_sqrt(long double _Complex __x) {return csqrtl(__x);} + +#undef sqrt +#define sqrt(__x) __tg_sqrt(__tg_promote1((__x))(__x)) + +// fabs + +static float + _TG_ATTRS + __tg_fabs(float __x) {return fabsf(__x);} + +static double + _TG_ATTRS + __tg_fabs(double __x) {return fabs(__x);} + +static long double + _TG_ATTRS + __tg_fabs(long double __x) {return fabsl(__x);} + +static float + _TG_ATTRS + __tg_fabs(float _Complex __x) {return cabsf(__x);} + +static double + _TG_ATTRS + __tg_fabs(double _Complex __x) {return cabs(__x);} + +static long double + _TG_ATTRS + __tg_fabs(long double _Complex __x) {return cabsl(__x);} + +#undef fabs +#define fabs(__x) __tg_fabs(__tg_promote1((__x))(__x)) + +// atan2 + +static float + _TG_ATTRS + __tg_atan2(float __x, float __y) {return atan2f(__x, __y);} + +static double + _TG_ATTRS + __tg_atan2(double __x, double __y) {return atan2(__x, __y);} + +static long double + _TG_ATTRS + __tg_atan2(long double __x, long double __y) {return atan2l(__x, __y);} + +#undef atan2 +#define atan2(__x, __y) __tg_atan2(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// cbrt + +static float + _TG_ATTRS + __tg_cbrt(float __x) {return cbrtf(__x);} + +static double + _TG_ATTRS + __tg_cbrt(double __x) {return cbrt(__x);} + +static long double + _TG_ATTRS + __tg_cbrt(long double __x) {return cbrtl(__x);} + +#undef cbrt +#define cbrt(__x) __tg_cbrt(__tg_promote1((__x))(__x)) + +// ceil + +static float + _TG_ATTRS + __tg_ceil(float __x) {return ceilf(__x);} + +static double + _TG_ATTRS + __tg_ceil(double __x) {return ceil(__x);} + +static long double + _TG_ATTRS + __tg_ceil(long double __x) {return ceill(__x);} + +#undef ceil +#define ceil(__x) __tg_ceil(__tg_promote1((__x))(__x)) + +// copysign + +static float + _TG_ATTRS + __tg_copysign(float __x, float __y) {return copysignf(__x, __y);} + +static double + _TG_ATTRS + __tg_copysign(double __x, double __y) {return copysign(__x, __y);} + +static long double + _TG_ATTRS + __tg_copysign(long double __x, long double __y) {return copysignl(__x, __y);} + +#undef copysign +#define copysign(__x, __y) __tg_copysign(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// erf + +static float + _TG_ATTRS + __tg_erf(float __x) {return erff(__x);} + +static double + _TG_ATTRS + __tg_erf(double __x) {return erf(__x);} + +static long double + _TG_ATTRS + __tg_erf(long double __x) {return erfl(__x);} + +#undef erf +#define erf(__x) __tg_erf(__tg_promote1((__x))(__x)) + +// erfc + +static float + _TG_ATTRS + __tg_erfc(float __x) {return erfcf(__x);} + +static double + _TG_ATTRS + __tg_erfc(double __x) {return erfc(__x);} + +static long double + _TG_ATTRS + __tg_erfc(long double __x) {return erfcl(__x);} + +#undef erfc +#define erfc(__x) __tg_erfc(__tg_promote1((__x))(__x)) + +// exp2 + +static float + _TG_ATTRS + __tg_exp2(float __x) {return exp2f(__x);} + +static double + _TG_ATTRS + __tg_exp2(double __x) {return exp2(__x);} + +static long double + _TG_ATTRS + __tg_exp2(long double __x) {return exp2l(__x);} + +#undef exp2 +#define exp2(__x) __tg_exp2(__tg_promote1((__x))(__x)) + +// expm1 + +static float + _TG_ATTRS + __tg_expm1(float __x) {return expm1f(__x);} + +static double + _TG_ATTRS + __tg_expm1(double __x) {return expm1(__x);} + +static long double + _TG_ATTRS + __tg_expm1(long double __x) {return expm1l(__x);} + +#undef expm1 +#define expm1(__x) __tg_expm1(__tg_promote1((__x))(__x)) + +// fdim + +static float + _TG_ATTRS + __tg_fdim(float __x, float __y) {return fdimf(__x, __y);} + +static double + _TG_ATTRS + __tg_fdim(double __x, double __y) {return fdim(__x, __y);} + +static long double + _TG_ATTRS + __tg_fdim(long double __x, long double __y) {return fdiml(__x, __y);} + +#undef fdim +#define fdim(__x, __y) __tg_fdim(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// floor + +static float + _TG_ATTRS + __tg_floor(float __x) {return floorf(__x);} + +static double + _TG_ATTRS + __tg_floor(double __x) {return floor(__x);} + +static long double + _TG_ATTRS + __tg_floor(long double __x) {return floorl(__x);} + +#undef floor +#define floor(__x) __tg_floor(__tg_promote1((__x))(__x)) + +// fma + +static float + _TG_ATTRS + __tg_fma(float __x, float __y, float __z) + {return fmaf(__x, __y, __z);} + +static double + _TG_ATTRS + __tg_fma(double __x, double __y, double __z) + {return fma(__x, __y, __z);} + +static long double + _TG_ATTRS + __tg_fma(long double __x,long double __y, long double __z) + {return fmal(__x, __y, __z);} + +#undef fma +#define fma(__x, __y, __z) \ + __tg_fma(__tg_promote3((__x), (__y), (__z))(__x), \ + __tg_promote3((__x), (__y), (__z))(__y), \ + __tg_promote3((__x), (__y), (__z))(__z)) + +// fmax + +static float + _TG_ATTRS + __tg_fmax(float __x, float __y) {return fmaxf(__x, __y);} + +static double + _TG_ATTRS + __tg_fmax(double __x, double __y) {return fmax(__x, __y);} + +static long double + _TG_ATTRS + __tg_fmax(long double __x, long double __y) {return fmaxl(__x, __y);} + +#undef fmax +#define fmax(__x, __y) __tg_fmax(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// fmin + +static float + _TG_ATTRS + __tg_fmin(float __x, float __y) {return fminf(__x, __y);} + +static double + _TG_ATTRS + __tg_fmin(double __x, double __y) {return fmin(__x, __y);} + +static long double + _TG_ATTRS + __tg_fmin(long double __x, long double __y) {return fminl(__x, __y);} + +#undef fmin +#define fmin(__x, __y) __tg_fmin(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// fmod + +static float + _TG_ATTRS + __tg_fmod(float __x, float __y) {return fmodf(__x, __y);} + +static double + _TG_ATTRS + __tg_fmod(double __x, double __y) {return fmod(__x, __y);} + +static long double + _TG_ATTRS + __tg_fmod(long double __x, long double __y) {return fmodl(__x, __y);} + +#undef fmod +#define fmod(__x, __y) __tg_fmod(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// frexp + +static float + _TG_ATTRS + __tg_frexp(float __x, int* __y) {return frexpf(__x, __y);} + +static double + _TG_ATTRS + __tg_frexp(double __x, int* __y) {return frexp(__x, __y);} + +static long double + _TG_ATTRS + __tg_frexp(long double __x, int* __y) {return frexpl(__x, __y);} + +#undef frexp +#define frexp(__x, __y) __tg_frexp(__tg_promote1((__x))(__x), __y) + +// hypot + +static float + _TG_ATTRS + __tg_hypot(float __x, float __y) {return hypotf(__x, __y);} + +static double + _TG_ATTRS + __tg_hypot(double __x, double __y) {return hypot(__x, __y);} + +static long double + _TG_ATTRS + __tg_hypot(long double __x, long double __y) {return hypotl(__x, __y);} + +#undef hypot +#define hypot(__x, __y) __tg_hypot(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// ilogb + +static int + _TG_ATTRS + __tg_ilogb(float __x) {return ilogbf(__x);} + +static int + _TG_ATTRS + __tg_ilogb(double __x) {return ilogb(__x);} + +static int + _TG_ATTRS + __tg_ilogb(long double __x) {return ilogbl(__x);} + +#undef ilogb +#define ilogb(__x) __tg_ilogb(__tg_promote1((__x))(__x)) + +// ldexp + +static float + _TG_ATTRS + __tg_ldexp(float __x, int __y) {return ldexpf(__x, __y);} + +static double + _TG_ATTRS + __tg_ldexp(double __x, int __y) {return ldexp(__x, __y);} + +static long double + _TG_ATTRS + __tg_ldexp(long double __x, int __y) {return ldexpl(__x, __y);} + +#undef ldexp +#define ldexp(__x, __y) __tg_ldexp(__tg_promote1((__x))(__x), __y) + +// lgamma + +static float + _TG_ATTRS + __tg_lgamma(float __x) {return lgammaf(__x);} + +static double + _TG_ATTRS + __tg_lgamma(double __x) {return lgamma(__x);} + +static long double + _TG_ATTRS + __tg_lgamma(long double __x) {return lgammal(__x);} + +#undef lgamma +#define lgamma(__x) __tg_lgamma(__tg_promote1((__x))(__x)) + +// llrint + +static long long + _TG_ATTRS + __tg_llrint(float __x) {return llrintf(__x);} + +static long long + _TG_ATTRS + __tg_llrint(double __x) {return llrint(__x);} + +static long long + _TG_ATTRS + __tg_llrint(long double __x) {return llrintl(__x);} + +#undef llrint +#define llrint(__x) __tg_llrint(__tg_promote1((__x))(__x)) + +// llround + +static long long + _TG_ATTRS + __tg_llround(float __x) {return llroundf(__x);} + +static long long + _TG_ATTRS + __tg_llround(double __x) {return llround(__x);} + +static long long + _TG_ATTRS + __tg_llround(long double __x) {return llroundl(__x);} + +#undef llround +#define llround(__x) __tg_llround(__tg_promote1((__x))(__x)) + +// log10 + +static float + _TG_ATTRS + __tg_log10(float __x) {return log10f(__x);} + +static double + _TG_ATTRS + __tg_log10(double __x) {return log10(__x);} + +static long double + _TG_ATTRS + __tg_log10(long double __x) {return log10l(__x);} + +#undef log10 +#define log10(__x) __tg_log10(__tg_promote1((__x))(__x)) + +// log1p + +static float + _TG_ATTRS + __tg_log1p(float __x) {return log1pf(__x);} + +static double + _TG_ATTRS + __tg_log1p(double __x) {return log1p(__x);} + +static long double + _TG_ATTRS + __tg_log1p(long double __x) {return log1pl(__x);} + +#undef log1p +#define log1p(__x) __tg_log1p(__tg_promote1((__x))(__x)) + +// log2 + +static float + _TG_ATTRS + __tg_log2(float __x) {return log2f(__x);} + +static double + _TG_ATTRS + __tg_log2(double __x) {return log2(__x);} + +static long double + _TG_ATTRS + __tg_log2(long double __x) {return log2l(__x);} + +#undef log2 +#define log2(__x) __tg_log2(__tg_promote1((__x))(__x)) + +// logb + +static float + _TG_ATTRS + __tg_logb(float __x) {return logbf(__x);} + +static double + _TG_ATTRS + __tg_logb(double __x) {return logb(__x);} + +static long double + _TG_ATTRS + __tg_logb(long double __x) {return logbl(__x);} + +#undef logb +#define logb(__x) __tg_logb(__tg_promote1((__x))(__x)) + +// lrint + +static long + _TG_ATTRS + __tg_lrint(float __x) {return lrintf(__x);} + +static long + _TG_ATTRS + __tg_lrint(double __x) {return lrint(__x);} + +static long + _TG_ATTRS + __tg_lrint(long double __x) {return lrintl(__x);} + +#undef lrint +#define lrint(__x) __tg_lrint(__tg_promote1((__x))(__x)) + +// lround + +static long + _TG_ATTRS + __tg_lround(float __x) {return lroundf(__x);} + +static long + _TG_ATTRS + __tg_lround(double __x) {return lround(__x);} + +static long + _TG_ATTRS + __tg_lround(long double __x) {return lroundl(__x);} + +#undef lround +#define lround(__x) __tg_lround(__tg_promote1((__x))(__x)) + +// nearbyint + +static float + _TG_ATTRS + __tg_nearbyint(float __x) {return nearbyintf(__x);} + +static double + _TG_ATTRS + __tg_nearbyint(double __x) {return nearbyint(__x);} + +static long double + _TG_ATTRS + __tg_nearbyint(long double __x) {return nearbyintl(__x);} + +#undef nearbyint +#define nearbyint(__x) __tg_nearbyint(__tg_promote1((__x))(__x)) + +// nextafter + +static float + _TG_ATTRS + __tg_nextafter(float __x, float __y) {return nextafterf(__x, __y);} + +static double + _TG_ATTRS + __tg_nextafter(double __x, double __y) {return nextafter(__x, __y);} + +static long double + _TG_ATTRS + __tg_nextafter(long double __x, long double __y) {return nextafterl(__x, __y);} + +#undef nextafter +#define nextafter(__x, __y) __tg_nextafter(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// nexttoward + +static float + _TG_ATTRS + __tg_nexttoward(float __x, long double __y) {return nexttowardf(__x, __y);} + +static double + _TG_ATTRS + __tg_nexttoward(double __x, long double __y) {return nexttoward(__x, __y);} + +static long double + _TG_ATTRS + __tg_nexttoward(long double __x, long double __y) {return nexttowardl(__x, __y);} + +#undef nexttoward +#define nexttoward(__x, __y) __tg_nexttoward(__tg_promote1((__x))(__x), (__y)) + +// remainder + +static float + _TG_ATTRS + __tg_remainder(float __x, float __y) {return remainderf(__x, __y);} + +static double + _TG_ATTRS + __tg_remainder(double __x, double __y) {return remainder(__x, __y);} + +static long double + _TG_ATTRS + __tg_remainder(long double __x, long double __y) {return remainderl(__x, __y);} + +#undef remainder +#define remainder(__x, __y) __tg_remainder(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// remquo + +static float + _TG_ATTRS + __tg_remquo(float __x, float __y, int* __z) + {return remquof(__x, __y, __z);} + +static double + _TG_ATTRS + __tg_remquo(double __x, double __y, int* __z) + {return remquo(__x, __y, __z);} + +static long double + _TG_ATTRS + __tg_remquo(long double __x,long double __y, int* __z) + {return remquol(__x, __y, __z);} + +#undef remquo +#define remquo(__x, __y, __z) \ + __tg_remquo(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y), \ + (__z)) + +// rint + +static float + _TG_ATTRS + __tg_rint(float __x) {return rintf(__x);} + +static double + _TG_ATTRS + __tg_rint(double __x) {return rint(__x);} + +static long double + _TG_ATTRS + __tg_rint(long double __x) {return rintl(__x);} + +#undef rint +#define rint(__x) __tg_rint(__tg_promote1((__x))(__x)) + +// round + +static float + _TG_ATTRS + __tg_round(float __x) {return roundf(__x);} + +static double + _TG_ATTRS + __tg_round(double __x) {return round(__x);} + +static long double + _TG_ATTRS + __tg_round(long double __x) {return roundl(__x);} + +#undef round +#define round(__x) __tg_round(__tg_promote1((__x))(__x)) + +// scalbn + +static float + _TG_ATTRS + __tg_scalbn(float __x, int __y) {return scalbnf(__x, __y);} + +static double + _TG_ATTRS + __tg_scalbn(double __x, int __y) {return scalbn(__x, __y);} + +static long double + _TG_ATTRS + __tg_scalbn(long double __x, int __y) {return scalbnl(__x, __y);} + +#undef scalbn +#define scalbn(__x, __y) __tg_scalbn(__tg_promote1((__x))(__x), __y) + +// scalbln + +static float + _TG_ATTRS + __tg_scalbln(float __x, long __y) {return scalblnf(__x, __y);} + +static double + _TG_ATTRS + __tg_scalbln(double __x, long __y) {return scalbln(__x, __y);} + +static long double + _TG_ATTRS + __tg_scalbln(long double __x, long __y) {return scalblnl(__x, __y);} + +#undef scalbln +#define scalbln(__x, __y) __tg_scalbln(__tg_promote1((__x))(__x), __y) + +// tgamma + +static float + _TG_ATTRS + __tg_tgamma(float __x) {return tgammaf(__x);} + +static double + _TG_ATTRS + __tg_tgamma(double __x) {return tgamma(__x);} + +static long double + _TG_ATTRS + __tg_tgamma(long double __x) {return tgammal(__x);} + +#undef tgamma +#define tgamma(__x) __tg_tgamma(__tg_promote1((__x))(__x)) + +// trunc + +static float + _TG_ATTRS + __tg_trunc(float __x) {return truncf(__x);} + +static double + _TG_ATTRS + __tg_trunc(double __x) {return trunc(__x);} + +static long double + _TG_ATTRS + __tg_trunc(long double __x) {return truncl(__x);} + +#undef trunc +#define trunc(__x) __tg_trunc(__tg_promote1((__x))(__x)) + +// carg + +static float + _TG_ATTRS + __tg_carg(float __x) {return atan2f(0.F, __x);} + +static double + _TG_ATTRS + __tg_carg(double __x) {return atan2(0., __x);} + +static long double + _TG_ATTRS + __tg_carg(long double __x) {return atan2l(0.L, __x);} + +static float + _TG_ATTRS + __tg_carg(float _Complex __x) {return cargf(__x);} + +static double + _TG_ATTRS + __tg_carg(double _Complex __x) {return carg(__x);} + +static long double + _TG_ATTRS + __tg_carg(long double _Complex __x) {return cargl(__x);} + +#undef carg +#define carg(__x) __tg_carg(__tg_promote1((__x))(__x)) + +// cimag + +static float + _TG_ATTRS + __tg_cimag(float __x) {return 0;} + +static double + _TG_ATTRS + __tg_cimag(double __x) {return 0;} + +static long double + _TG_ATTRS + __tg_cimag(long double __x) {return 0;} + +static float + _TG_ATTRS + __tg_cimag(float _Complex __x) {return cimagf(__x);} + +static double + _TG_ATTRS + __tg_cimag(double _Complex __x) {return cimag(__x);} + +static long double + _TG_ATTRS + __tg_cimag(long double _Complex __x) {return cimagl(__x);} + +#undef cimag +#define cimag(__x) __tg_cimag(__tg_promote1((__x))(__x)) + +// conj + +static float _Complex + _TG_ATTRS + __tg_conj(float __x) {return __x;} + +static double _Complex + _TG_ATTRS + __tg_conj(double __x) {return __x;} + +static long double _Complex + _TG_ATTRS + __tg_conj(long double __x) {return __x;} + +static float _Complex + _TG_ATTRS + __tg_conj(float _Complex __x) {return conjf(__x);} + +static double _Complex + _TG_ATTRS + __tg_conj(double _Complex __x) {return conj(__x);} + +static long double _Complex + _TG_ATTRS + __tg_conj(long double _Complex __x) {return conjl(__x);} + +#undef conj +#define conj(__x) __tg_conj(__tg_promote1((__x))(__x)) + +// cproj + +static float _Complex + _TG_ATTRS + __tg_cproj(float __x) {return cprojf(__x);} + +static double _Complex + _TG_ATTRS + __tg_cproj(double __x) {return cproj(__x);} + +static long double _Complex + _TG_ATTRS + __tg_cproj(long double __x) {return cprojl(__x);} + +static float _Complex + _TG_ATTRS + __tg_cproj(float _Complex __x) {return cprojf(__x);} + +static double _Complex + _TG_ATTRS + __tg_cproj(double _Complex __x) {return cproj(__x);} + +static long double _Complex + _TG_ATTRS + __tg_cproj(long double _Complex __x) {return cprojl(__x);} + +#undef cproj +#define cproj(__x) __tg_cproj(__tg_promote1((__x))(__x)) + +// creal + +static float + _TG_ATTRS + __tg_creal(float __x) {return __x;} + +static double + _TG_ATTRS + __tg_creal(double __x) {return __x;} + +static long double + _TG_ATTRS + __tg_creal(long double __x) {return __x;} + +static float + _TG_ATTRS + __tg_creal(float _Complex __x) {return crealf(__x);} + +static double + _TG_ATTRS + __tg_creal(double _Complex __x) {return creal(__x);} + +static long double + _TG_ATTRS + __tg_creal(long double _Complex __x) {return creall(__x);} + +#undef creal +#define creal(__x) __tg_creal(__tg_promote1((__x))(__x)) + +#undef _TG_ATTRSp +#undef _TG_ATTRS + +#endif /* __cplusplus */ +#endif /* __TGMATH_H */ diff --git a/headers/clang/tmmintrin.h b/headers/clang/tmmintrin.h new file mode 100644 index 0000000000..8a6dfcbf2a --- /dev/null +++ b/headers/clang/tmmintrin.h @@ -0,0 +1,224 @@ +/*===---- tmmintrin.h - SSSE3 intrinsics -----------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __TMMINTRIN_H +#define __TMMINTRIN_H + +#include + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("ssse3"))) + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_abs_pi8(__m64 __a) +{ + return (__m64)__builtin_ia32_pabsb((__v8qi)__a); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_abs_epi8(__m128i __a) +{ + return (__m128i)__builtin_ia32_pabsb128((__v16qi)__a); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_abs_pi16(__m64 __a) +{ + return (__m64)__builtin_ia32_pabsw((__v4hi)__a); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_abs_epi16(__m128i __a) +{ + return (__m128i)__builtin_ia32_pabsw128((__v8hi)__a); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_abs_pi32(__m64 __a) +{ + return (__m64)__builtin_ia32_pabsd((__v2si)__a); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_abs_epi32(__m128i __a) +{ + return (__m128i)__builtin_ia32_pabsd128((__v4si)__a); +} + +#define _mm_alignr_epi8(a, b, n) __extension__ ({ \ + __m128i __a = (a); \ + __m128i __b = (b); \ + (__m128i)__builtin_ia32_palignr128((__v16qi)__a, (__v16qi)__b, (n)); }) + +#define _mm_alignr_pi8(a, b, n) __extension__ ({ \ + __m64 __a = (a); \ + __m64 __b = (b); \ + (__m64)__builtin_ia32_palignr((__v8qi)__a, (__v8qi)__b, (n)); }) + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_hadd_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_phaddw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_hadd_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_phaddd128((__v4si)__a, (__v4si)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_hadd_pi16(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_phaddw((__v4hi)__a, (__v4hi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_hadd_pi32(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_phaddd((__v2si)__a, (__v2si)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_hadds_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_phaddsw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_hadds_pi16(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_phaddsw((__v4hi)__a, (__v4hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_hsub_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_phsubw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_hsub_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_phsubd128((__v4si)__a, (__v4si)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_hsub_pi16(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_phsubw((__v4hi)__a, (__v4hi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_hsub_pi32(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_phsubd((__v2si)__a, (__v2si)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_hsubs_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_phsubsw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_hsubs_pi16(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_phsubsw((__v4hi)__a, (__v4hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maddubs_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_pmaddubsw128((__v16qi)__a, (__v16qi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_maddubs_pi16(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_pmaddubsw((__v8qi)__a, (__v8qi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_mulhrs_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_pmulhrsw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_mulhrs_pi16(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_pmulhrsw((__v4hi)__a, (__v4hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_shuffle_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_pshufb128((__v16qi)__a, (__v16qi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_shuffle_pi8(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_pshufb((__v8qi)__a, (__v8qi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sign_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_psignb128((__v16qi)__a, (__v16qi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sign_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_psignw128((__v8hi)__a, (__v8hi)__b); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sign_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)__builtin_ia32_psignd128((__v4si)__a, (__v4si)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_sign_pi8(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_psignb((__v8qi)__a, (__v8qi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_sign_pi16(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_psignw((__v4hi)__a, (__v4hi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_sign_pi32(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_psignd((__v2si)__a, (__v2si)__b); +} + +#undef __DEFAULT_FN_ATTRS + +#endif /* __TMMINTRIN_H */ diff --git a/headers/clang/unwind.h b/headers/clang/unwind.h new file mode 100644 index 0000000000..303d79288a --- /dev/null +++ b/headers/clang/unwind.h @@ -0,0 +1,282 @@ +/*===---- unwind.h - Stack unwinding ----------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +/* See "Data Definitions for libgcc_s" in the Linux Standard Base.*/ + +#ifndef __CLANG_UNWIND_H +#define __CLANG_UNWIND_H + +#if defined(__APPLE__) && __has_include_next() +/* Darwin (from 11.x on) provide an unwind.h. If that's available, + * use it. libunwind wraps some of its definitions in #ifdef _GNU_SOURCE, + * so define that around the include.*/ +# ifndef _GNU_SOURCE +# define _SHOULD_UNDEFINE_GNU_SOURCE +# define _GNU_SOURCE +# endif +// libunwind's unwind.h reflects the current visibility. However, Mozilla +// builds with -fvisibility=hidden and relies on gcc's unwind.h to reset the +// visibility to default and export its contents. gcc also allows users to +// override its override by #defining HIDE_EXPORTS (but note, this only obeys +// the user's -fvisibility setting; it doesn't hide any exports on its own). We +// imitate gcc's header here: +# ifdef HIDE_EXPORTS +# include_next +# else +# pragma GCC visibility push(default) +# include_next +# pragma GCC visibility pop +# endif +# ifdef _SHOULD_UNDEFINE_GNU_SOURCE +# undef _GNU_SOURCE +# undef _SHOULD_UNDEFINE_GNU_SOURCE +# endif +#else + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* It is a bit strange for a header to play with the visibility of the + symbols it declares, but this matches gcc's behavior and some programs + depend on it */ +#ifndef HIDE_EXPORTS +#pragma GCC visibility push(default) +#endif + +typedef uintptr_t _Unwind_Word; +typedef intptr_t _Unwind_Sword; +typedef uintptr_t _Unwind_Ptr; +typedef uintptr_t _Unwind_Internal_Ptr; +typedef uint64_t _Unwind_Exception_Class; + +typedef intptr_t _sleb128_t; +typedef uintptr_t _uleb128_t; + +struct _Unwind_Context; +struct _Unwind_Exception; +typedef enum { + _URC_NO_REASON = 0, + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + + _URC_FATAL_PHASE2_ERROR = 2, + _URC_FATAL_PHASE1_ERROR = 3, + _URC_NORMAL_STOP = 4, + + _URC_END_OF_STACK = 5, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8 +} _Unwind_Reason_Code; + +typedef enum { + _UA_SEARCH_PHASE = 1, + _UA_CLEANUP_PHASE = 2, + + _UA_HANDLER_FRAME = 4, + _UA_FORCE_UNWIND = 8, + _UA_END_OF_STACK = 16 /* gcc extension to C++ ABI */ +} _Unwind_Action; + +typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code, + struct _Unwind_Exception *); + +struct _Unwind_Exception { + _Unwind_Exception_Class exception_class; + _Unwind_Exception_Cleanup_Fn exception_cleanup; + _Unwind_Word private_1; + _Unwind_Word private_2; + /* The Itanium ABI requires that _Unwind_Exception objects are "double-word + * aligned". GCC has interpreted this to mean "use the maximum useful + * alignment for the target"; so do we. */ +} __attribute__((__aligned__)); + +typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)(int, _Unwind_Action, + _Unwind_Exception_Class, + struct _Unwind_Exception *, + struct _Unwind_Context *, + void *); + +typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)( + int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, + struct _Unwind_Context *); +typedef _Unwind_Personality_Fn __personality_routine; + +typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *, + void *); + +#if defined(__arm__) && !defined(__APPLE__) + +typedef enum { + _UVRSC_CORE = 0, /* integer register */ + _UVRSC_VFP = 1, /* vfp */ + _UVRSC_WMMXD = 3, /* Intel WMMX data register */ + _UVRSC_WMMXC = 4 /* Intel WMMX control register */ +} _Unwind_VRS_RegClass; + +typedef enum { + _UVRSD_UINT32 = 0, + _UVRSD_VFPX = 1, + _UVRSD_UINT64 = 3, + _UVRSD_FLOAT = 4, + _UVRSD_DOUBLE = 5 +} _Unwind_VRS_DataRepresentation; + +typedef enum { + _UVRSR_OK = 0, + _UVRSR_NOT_IMPLEMENTED = 1, + _UVRSR_FAILED = 2 +} _Unwind_VRS_Result; + +_Unwind_VRS_Result _Unwind_VRS_Get(struct _Unwind_Context *__context, + _Unwind_VRS_RegClass __regclass, + uint32_t __regno, + _Unwind_VRS_DataRepresentation __representation, + void *__valuep); + +_Unwind_VRS_Result _Unwind_VRS_Set(struct _Unwind_Context *__context, + _Unwind_VRS_RegClass __regclass, + uint32_t __regno, + _Unwind_VRS_DataRepresentation __representation, + void *__valuep); + +static __inline__ +_Unwind_Word _Unwind_GetGR(struct _Unwind_Context *__context, int __index) { + _Unwind_Word __value; + _Unwind_VRS_Get(__context, _UVRSC_CORE, __index, _UVRSD_UINT32, &__value); + return __value; +} + +static __inline__ +void _Unwind_SetGR(struct _Unwind_Context *__context, int __index, + _Unwind_Word __value) { + _Unwind_VRS_Set(__context, _UVRSC_CORE, __index, _UVRSD_UINT32, &__value); +} + +static __inline__ +_Unwind_Word _Unwind_GetIP(struct _Unwind_Context *__context) { + _Unwind_Word __ip = _Unwind_GetGR(__context, 15); + return __ip & ~(_Unwind_Word)(0x1); /* Remove thumb mode bit. */ +} + +static __inline__ +void _Unwind_SetIP(struct _Unwind_Context *__context, _Unwind_Word __value) { + _Unwind_Word __thumb_mode_bit = _Unwind_GetGR(__context, 15) & 0x1; + _Unwind_SetGR(__context, 15, __value | __thumb_mode_bit); +} +#else +_Unwind_Word _Unwind_GetGR(struct _Unwind_Context *, int); +void _Unwind_SetGR(struct _Unwind_Context *, int, _Unwind_Word); + +_Unwind_Word _Unwind_GetIP(struct _Unwind_Context *); +void _Unwind_SetIP(struct _Unwind_Context *, _Unwind_Word); +#endif + + +_Unwind_Word _Unwind_GetIPInfo(struct _Unwind_Context *, int *); + +_Unwind_Word _Unwind_GetCFA(struct _Unwind_Context *); + +_Unwind_Word _Unwind_GetBSP(struct _Unwind_Context *); + +void *_Unwind_GetLanguageSpecificData(struct _Unwind_Context *); + +_Unwind_Ptr _Unwind_GetRegionStart(struct _Unwind_Context *); + +/* DWARF EH functions; currently not available on Darwin/ARM */ +#if !defined(__APPLE__) || !defined(__arm__) + +_Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *); +_Unwind_Reason_Code _Unwind_ForcedUnwind(struct _Unwind_Exception *, + _Unwind_Stop_Fn, void *); +void _Unwind_DeleteException(struct _Unwind_Exception *); +void _Unwind_Resume(struct _Unwind_Exception *); +_Unwind_Reason_Code _Unwind_Resume_or_Rethrow(struct _Unwind_Exception *); + +#endif + +_Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void *); + +/* setjmp(3)/longjmp(3) stuff */ +typedef struct SjLj_Function_Context *_Unwind_FunctionContext_t; + +void _Unwind_SjLj_Register(_Unwind_FunctionContext_t); +void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t); +_Unwind_Reason_Code _Unwind_SjLj_RaiseException(struct _Unwind_Exception *); +_Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(struct _Unwind_Exception *, + _Unwind_Stop_Fn, void *); +void _Unwind_SjLj_Resume(struct _Unwind_Exception *); +_Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *); + +void *_Unwind_FindEnclosingFunction(void *); + +#ifdef __APPLE__ + +_Unwind_Ptr _Unwind_GetDataRelBase(struct _Unwind_Context *) + __attribute__((__unavailable__)); +_Unwind_Ptr _Unwind_GetTextRelBase(struct _Unwind_Context *) + __attribute__((__unavailable__)); + +/* Darwin-specific functions */ +void __register_frame(const void *); +void __deregister_frame(const void *); + +struct dwarf_eh_bases { + uintptr_t tbase; + uintptr_t dbase; + uintptr_t func; +}; +void *_Unwind_Find_FDE(const void *, struct dwarf_eh_bases *); + +void __register_frame_info_bases(const void *, void *, void *, void *) + __attribute__((__unavailable__)); +void __register_frame_info(const void *, void *) __attribute__((__unavailable__)); +void __register_frame_info_table_bases(const void *, void*, void *, void *) + __attribute__((__unavailable__)); +void __register_frame_info_table(const void *, void *) + __attribute__((__unavailable__)); +void __register_frame_table(const void *) __attribute__((__unavailable__)); +void __deregister_frame_info(const void *) __attribute__((__unavailable__)); +void __deregister_frame_info_bases(const void *)__attribute__((__unavailable__)); + +#else + +_Unwind_Ptr _Unwind_GetDataRelBase(struct _Unwind_Context *); +_Unwind_Ptr _Unwind_GetTextRelBase(struct _Unwind_Context *); + +#endif + + +#ifndef HIDE_EXPORTS +#pragma GCC visibility pop +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#endif /* __CLANG_UNWIND_H */ diff --git a/headers/clang/vadefs.h b/headers/clang/vadefs.h new file mode 100644 index 0000000000..7fe9a74e3f --- /dev/null +++ b/headers/clang/vadefs.h @@ -0,0 +1,65 @@ +/* ===-------- vadefs.h ---------------------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +/* Only include this if we are aiming for MSVC compatibility. */ +#ifndef _MSC_VER +#include_next +#else + +#ifndef __clang_vadefs_h +#define __clang_vadefs_h + +#include_next + +/* Override macros from vadefs.h with definitions that work with Clang. */ +#ifdef _crt_va_start +#undef _crt_va_start +#define _crt_va_start(ap, param) __builtin_va_start(ap, param) +#endif +#ifdef _crt_va_end +#undef _crt_va_end +#define _crt_va_end(ap) __builtin_va_end(ap) +#endif +#ifdef _crt_va_arg +#undef _crt_va_arg +#define _crt_va_arg(ap, type) __builtin_va_arg(ap, type) +#endif + +/* VS 2015 switched to double underscore names, which is an improvement, but now + * we have to intercept those names too. + */ +#ifdef __crt_va_start +#undef __crt_va_start +#define __crt_va_start(ap, param) __builtin_va_start(ap, param) +#endif +#ifdef __crt_va_end +#undef __crt_va_end +#define __crt_va_end(ap) __builtin_va_end(ap) +#endif +#ifdef __crt_va_arg +#undef __crt_va_arg +#define __crt_va_arg(ap, type) __builtin_va_arg(ap, type) +#endif + +#endif +#endif diff --git a/headers/clang/varargs.h b/headers/clang/varargs.h new file mode 100644 index 0000000000..b5477d0a6a --- /dev/null +++ b/headers/clang/varargs.h @@ -0,0 +1,26 @@ +/*===---- varargs.h - Variable argument handling -------------------------------------=== +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +*===-----------------------------------------------------------------------=== +*/ +#ifndef __VARARGS_H +#define __VARARGS_H + #error "Please use instead of " +#endif diff --git a/headers/clang/vecintrin.h b/headers/clang/vecintrin.h new file mode 100644 index 0000000000..ca7acb4731 --- /dev/null +++ b/headers/clang/vecintrin.h @@ -0,0 +1,8946 @@ +/*===---- vecintrin.h - Vector intrinsics ----------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#if defined(__s390x__) && defined(__VEC__) + +#define __ATTRS_ai __attribute__((__always_inline__)) +#define __ATTRS_o __attribute__((__overloadable__)) +#define __ATTRS_o_ai __attribute__((__overloadable__, __always_inline__)) + +#define __constant(PARM) \ + __attribute__((__enable_if__ ((PARM) == (PARM), \ + "argument must be a constant integer"))) +#define __constant_range(PARM, LOW, HIGH) \ + __attribute__((__enable_if__ ((PARM) >= (LOW) && (PARM) <= (HIGH), \ + "argument must be a constant integer from " #LOW " to " #HIGH))) +#define __constant_pow2_range(PARM, LOW, HIGH) \ + __attribute__((__enable_if__ ((PARM) >= (LOW) && (PARM) <= (HIGH) && \ + ((PARM) & ((PARM) - 1)) == 0, \ + "argument must be a constant power of 2 from " #LOW " to " #HIGH))) + +/*-- __lcbb -----------------------------------------------------------------*/ + +extern __ATTRS_o unsigned int +__lcbb(const void *__ptr, unsigned short __len) + __constant_pow2_range(__len, 64, 4096); + +#define __lcbb(X, Y) ((__typeof__((__lcbb)((X), (Y)))) \ + __builtin_s390_lcbb((X), __builtin_constant_p((Y))? \ + ((Y) == 64 ? 0 : \ + (Y) == 128 ? 1 : \ + (Y) == 256 ? 2 : \ + (Y) == 512 ? 3 : \ + (Y) == 1024 ? 4 : \ + (Y) == 2048 ? 5 : \ + (Y) == 4096 ? 6 : 0) : 0)) + +/*-- vec_extract ------------------------------------------------------------*/ + +static inline __ATTRS_o_ai signed char +vec_extract(vector signed char __vec, int __index) { + return __vec[__index & 15]; +} + +static inline __ATTRS_o_ai unsigned char +vec_extract(vector bool char __vec, int __index) { + return __vec[__index & 15]; +} + +static inline __ATTRS_o_ai unsigned char +vec_extract(vector unsigned char __vec, int __index) { + return __vec[__index & 15]; +} + +static inline __ATTRS_o_ai signed short +vec_extract(vector signed short __vec, int __index) { + return __vec[__index & 7]; +} + +static inline __ATTRS_o_ai unsigned short +vec_extract(vector bool short __vec, int __index) { + return __vec[__index & 7]; +} + +static inline __ATTRS_o_ai unsigned short +vec_extract(vector unsigned short __vec, int __index) { + return __vec[__index & 7]; +} + +static inline __ATTRS_o_ai signed int +vec_extract(vector signed int __vec, int __index) { + return __vec[__index & 3]; +} + +static inline __ATTRS_o_ai unsigned int +vec_extract(vector bool int __vec, int __index) { + return __vec[__index & 3]; +} + +static inline __ATTRS_o_ai unsigned int +vec_extract(vector unsigned int __vec, int __index) { + return __vec[__index & 3]; +} + +static inline __ATTRS_o_ai signed long long +vec_extract(vector signed long long __vec, int __index) { + return __vec[__index & 1]; +} + +static inline __ATTRS_o_ai unsigned long long +vec_extract(vector bool long long __vec, int __index) { + return __vec[__index & 1]; +} + +static inline __ATTRS_o_ai unsigned long long +vec_extract(vector unsigned long long __vec, int __index) { + return __vec[__index & 1]; +} + +static inline __ATTRS_o_ai double +vec_extract(vector double __vec, int __index) { + return __vec[__index & 1]; +} + +/*-- vec_insert -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_insert(signed char __scalar, vector signed char __vec, int __index) { + __vec[__index & 15] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector unsigned char +vec_insert(unsigned char __scalar, vector bool char __vec, int __index) { + vector unsigned char __newvec = (vector unsigned char)__vec; + __newvec[__index & 15] = (unsigned char)__scalar; + return __newvec; +} + +static inline __ATTRS_o_ai vector unsigned char +vec_insert(unsigned char __scalar, vector unsigned char __vec, int __index) { + __vec[__index & 15] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector signed short +vec_insert(signed short __scalar, vector signed short __vec, int __index) { + __vec[__index & 7] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector unsigned short +vec_insert(unsigned short __scalar, vector bool short __vec, int __index) { + vector unsigned short __newvec = (vector unsigned short)__vec; + __newvec[__index & 7] = (unsigned short)__scalar; + return __newvec; +} + +static inline __ATTRS_o_ai vector unsigned short +vec_insert(unsigned short __scalar, vector unsigned short __vec, int __index) { + __vec[__index & 7] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector signed int +vec_insert(signed int __scalar, vector signed int __vec, int __index) { + __vec[__index & 3] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector unsigned int +vec_insert(unsigned int __scalar, vector bool int __vec, int __index) { + vector unsigned int __newvec = (vector unsigned int)__vec; + __newvec[__index & 3] = __scalar; + return __newvec; +} + +static inline __ATTRS_o_ai vector unsigned int +vec_insert(unsigned int __scalar, vector unsigned int __vec, int __index) { + __vec[__index & 3] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector signed long long +vec_insert(signed long long __scalar, vector signed long long __vec, + int __index) { + __vec[__index & 1] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_insert(unsigned long long __scalar, vector bool long long __vec, + int __index) { + vector unsigned long long __newvec = (vector unsigned long long)__vec; + __newvec[__index & 1] = __scalar; + return __newvec; +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_insert(unsigned long long __scalar, vector unsigned long long __vec, + int __index) { + __vec[__index & 1] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector double +vec_insert(double __scalar, vector double __vec, int __index) { + __vec[__index & 1] = __scalar; + return __vec; +} + +/*-- vec_promote ------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_promote(signed char __scalar, int __index) { + const vector signed char __zero = (vector signed char)0; + vector signed char __vec = __builtin_shufflevector(__zero, __zero, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); + __vec[__index & 15] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector unsigned char +vec_promote(unsigned char __scalar, int __index) { + const vector unsigned char __zero = (vector unsigned char)0; + vector unsigned char __vec = __builtin_shufflevector(__zero, __zero, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); + __vec[__index & 15] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector signed short +vec_promote(signed short __scalar, int __index) { + const vector signed short __zero = (vector signed short)0; + vector signed short __vec = __builtin_shufflevector(__zero, __zero, + -1, -1, -1, -1, -1, -1, -1, -1); + __vec[__index & 7] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector unsigned short +vec_promote(unsigned short __scalar, int __index) { + const vector unsigned short __zero = (vector unsigned short)0; + vector unsigned short __vec = __builtin_shufflevector(__zero, __zero, + -1, -1, -1, -1, -1, -1, -1, -1); + __vec[__index & 7] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector signed int +vec_promote(signed int __scalar, int __index) { + const vector signed int __zero = (vector signed int)0; + vector signed int __vec = __builtin_shufflevector(__zero, __zero, + -1, -1, -1, -1); + __vec[__index & 3] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector unsigned int +vec_promote(unsigned int __scalar, int __index) { + const vector unsigned int __zero = (vector unsigned int)0; + vector unsigned int __vec = __builtin_shufflevector(__zero, __zero, + -1, -1, -1, -1); + __vec[__index & 3] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector signed long long +vec_promote(signed long long __scalar, int __index) { + const vector signed long long __zero = (vector signed long long)0; + vector signed long long __vec = __builtin_shufflevector(__zero, __zero, + -1, -1); + __vec[__index & 1] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_promote(unsigned long long __scalar, int __index) { + const vector unsigned long long __zero = (vector unsigned long long)0; + vector unsigned long long __vec = __builtin_shufflevector(__zero, __zero, + -1, -1); + __vec[__index & 1] = __scalar; + return __vec; +} + +static inline __ATTRS_o_ai vector double +vec_promote(double __scalar, int __index) { + const vector double __zero = (vector double)0; + vector double __vec = __builtin_shufflevector(__zero, __zero, -1, -1); + __vec[__index & 1] = __scalar; + return __vec; +} + +/*-- vec_insert_and_zero ----------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_insert_and_zero(const signed char *__ptr) { + vector signed char __vec = (vector signed char)0; + __vec[7] = *__ptr; + return __vec; +} + +static inline __ATTRS_o_ai vector unsigned char +vec_insert_and_zero(const unsigned char *__ptr) { + vector unsigned char __vec = (vector unsigned char)0; + __vec[7] = *__ptr; + return __vec; +} + +static inline __ATTRS_o_ai vector signed short +vec_insert_and_zero(const signed short *__ptr) { + vector signed short __vec = (vector signed short)0; + __vec[3] = *__ptr; + return __vec; +} + +static inline __ATTRS_o_ai vector unsigned short +vec_insert_and_zero(const unsigned short *__ptr) { + vector unsigned short __vec = (vector unsigned short)0; + __vec[3] = *__ptr; + return __vec; +} + +static inline __ATTRS_o_ai vector signed int +vec_insert_and_zero(const signed int *__ptr) { + vector signed int __vec = (vector signed int)0; + __vec[1] = *__ptr; + return __vec; +} + +static inline __ATTRS_o_ai vector unsigned int +vec_insert_and_zero(const unsigned int *__ptr) { + vector unsigned int __vec = (vector unsigned int)0; + __vec[1] = *__ptr; + return __vec; +} + +static inline __ATTRS_o_ai vector signed long long +vec_insert_and_zero(const signed long long *__ptr) { + vector signed long long __vec = (vector signed long long)0; + __vec[0] = *__ptr; + return __vec; +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_insert_and_zero(const unsigned long long *__ptr) { + vector unsigned long long __vec = (vector unsigned long long)0; + __vec[0] = *__ptr; + return __vec; +} + +static inline __ATTRS_o_ai vector double +vec_insert_and_zero(const double *__ptr) { + vector double __vec = (vector double)0; + __vec[0] = *__ptr; + return __vec; +} + +/*-- vec_perm ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_perm(vector signed char __a, vector signed char __b, + vector unsigned char __c) { + return (vector signed char)__builtin_s390_vperm( + (vector unsigned char)__a, (vector unsigned char)__b, __c); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_perm(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return (vector unsigned char)__builtin_s390_vperm( + (vector unsigned char)__a, (vector unsigned char)__b, __c); +} + +static inline __ATTRS_o_ai vector bool char +vec_perm(vector bool char __a, vector bool char __b, + vector unsigned char __c) { + return (vector bool char)__builtin_s390_vperm( + (vector unsigned char)__a, (vector unsigned char)__b, __c); +} + +static inline __ATTRS_o_ai vector signed short +vec_perm(vector signed short __a, vector signed short __b, + vector unsigned char __c) { + return (vector signed short)__builtin_s390_vperm( + (vector unsigned char)__a, (vector unsigned char)__b, __c); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_perm(vector unsigned short __a, vector unsigned short __b, + vector unsigned char __c) { + return (vector unsigned short)__builtin_s390_vperm( + (vector unsigned char)__a, (vector unsigned char)__b, __c); +} + +static inline __ATTRS_o_ai vector bool short +vec_perm(vector bool short __a, vector bool short __b, + vector unsigned char __c) { + return (vector bool short)__builtin_s390_vperm( + (vector unsigned char)__a, (vector unsigned char)__b, __c); +} + +static inline __ATTRS_o_ai vector signed int +vec_perm(vector signed int __a, vector signed int __b, + vector unsigned char __c) { + return (vector signed int)__builtin_s390_vperm( + (vector unsigned char)__a, (vector unsigned char)__b, __c); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_perm(vector unsigned int __a, vector unsigned int __b, + vector unsigned char __c) { + return (vector unsigned int)__builtin_s390_vperm( + (vector unsigned char)__a, (vector unsigned char)__b, __c); +} + +static inline __ATTRS_o_ai vector bool int +vec_perm(vector bool int __a, vector bool int __b, + vector unsigned char __c) { + return (vector bool int)__builtin_s390_vperm( + (vector unsigned char)__a, (vector unsigned char)__b, __c); +} + +static inline __ATTRS_o_ai vector signed long long +vec_perm(vector signed long long __a, vector signed long long __b, + vector unsigned char __c) { + return (vector signed long long)__builtin_s390_vperm( + (vector unsigned char)__a, (vector unsigned char)__b, __c); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_perm(vector unsigned long long __a, vector unsigned long long __b, + vector unsigned char __c) { + return (vector unsigned long long)__builtin_s390_vperm( + (vector unsigned char)__a, (vector unsigned char)__b, __c); +} + +static inline __ATTRS_o_ai vector bool long long +vec_perm(vector bool long long __a, vector bool long long __b, + vector unsigned char __c) { + return (vector bool long long)__builtin_s390_vperm( + (vector unsigned char)__a, (vector unsigned char)__b, __c); +} + +static inline __ATTRS_o_ai vector double +vec_perm(vector double __a, vector double __b, + vector unsigned char __c) { + return (vector double)__builtin_s390_vperm( + (vector unsigned char)__a, (vector unsigned char)__b, __c); +} + +/*-- vec_permi --------------------------------------------------------------*/ + +extern __ATTRS_o vector signed long long +vec_permi(vector signed long long __a, vector signed long long __b, int __c) + __constant_range(__c, 0, 3); + +extern __ATTRS_o vector unsigned long long +vec_permi(vector unsigned long long __a, vector unsigned long long __b, int __c) + __constant_range(__c, 0, 3); + +extern __ATTRS_o vector bool long long +vec_permi(vector bool long long __a, vector bool long long __b, int __c) + __constant_range(__c, 0, 3); + +extern __ATTRS_o vector double +vec_permi(vector double __a, vector double __b, int __c) + __constant_range(__c, 0, 3); + +#define vec_permi(X, Y, Z) ((__typeof__((vec_permi)((X), (Y), (Z)))) \ + __builtin_s390_vpdi((vector unsigned long long)(X), \ + (vector unsigned long long)(Y), \ + (((Z) & 2) << 1) | ((Z) & 1))) + +/*-- vec_sel ----------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_sel(vector signed char __a, vector signed char __b, + vector unsigned char __c) { + return ((vector signed char)__c & __b) | (~(vector signed char)__c & __a); +} + +static inline __ATTRS_o_ai vector signed char +vec_sel(vector signed char __a, vector signed char __b, vector bool char __c) { + return ((vector signed char)__c & __b) | (~(vector signed char)__c & __a); +} + +static inline __ATTRS_o_ai vector bool char +vec_sel(vector bool char __a, vector bool char __b, vector unsigned char __c) { + return ((vector bool char)__c & __b) | (~(vector bool char)__c & __a); +} + +static inline __ATTRS_o_ai vector bool char +vec_sel(vector bool char __a, vector bool char __b, vector bool char __c) { + return (__c & __b) | (~__c & __a); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_sel(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return (__c & __b) | (~__c & __a); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_sel(vector unsigned char __a, vector unsigned char __b, + vector bool char __c) { + return ((vector unsigned char)__c & __b) | (~(vector unsigned char)__c & __a); +} + +static inline __ATTRS_o_ai vector signed short +vec_sel(vector signed short __a, vector signed short __b, + vector unsigned short __c) { + return ((vector signed short)__c & __b) | (~(vector signed short)__c & __a); +} + +static inline __ATTRS_o_ai vector signed short +vec_sel(vector signed short __a, vector signed short __b, + vector bool short __c) { + return ((vector signed short)__c & __b) | (~(vector signed short)__c & __a); +} + +static inline __ATTRS_o_ai vector bool short +vec_sel(vector bool short __a, vector bool short __b, + vector unsigned short __c) { + return ((vector bool short)__c & __b) | (~(vector bool short)__c & __a); +} + +static inline __ATTRS_o_ai vector bool short +vec_sel(vector bool short __a, vector bool short __b, vector bool short __c) { + return (__c & __b) | (~__c & __a); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_sel(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c) { + return (__c & __b) | (~__c & __a); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_sel(vector unsigned short __a, vector unsigned short __b, + vector bool short __c) { + return (((vector unsigned short)__c & __b) | + (~(vector unsigned short)__c & __a)); +} + +static inline __ATTRS_o_ai vector signed int +vec_sel(vector signed int __a, vector signed int __b, + vector unsigned int __c) { + return ((vector signed int)__c & __b) | (~(vector signed int)__c & __a); +} + +static inline __ATTRS_o_ai vector signed int +vec_sel(vector signed int __a, vector signed int __b, vector bool int __c) { + return ((vector signed int)__c & __b) | (~(vector signed int)__c & __a); +} + +static inline __ATTRS_o_ai vector bool int +vec_sel(vector bool int __a, vector bool int __b, vector unsigned int __c) { + return ((vector bool int)__c & __b) | (~(vector bool int)__c & __a); +} + +static inline __ATTRS_o_ai vector bool int +vec_sel(vector bool int __a, vector bool int __b, vector bool int __c) { + return (__c & __b) | (~__c & __a); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_sel(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c) { + return (__c & __b) | (~__c & __a); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_sel(vector unsigned int __a, vector unsigned int __b, vector bool int __c) { + return ((vector unsigned int)__c & __b) | (~(vector unsigned int)__c & __a); +} + +static inline __ATTRS_o_ai vector signed long long +vec_sel(vector signed long long __a, vector signed long long __b, + vector unsigned long long __c) { + return (((vector signed long long)__c & __b) | + (~(vector signed long long)__c & __a)); +} + +static inline __ATTRS_o_ai vector signed long long +vec_sel(vector signed long long __a, vector signed long long __b, + vector bool long long __c) { + return (((vector signed long long)__c & __b) | + (~(vector signed long long)__c & __a)); +} + +static inline __ATTRS_o_ai vector bool long long +vec_sel(vector bool long long __a, vector bool long long __b, + vector unsigned long long __c) { + return (((vector bool long long)__c & __b) | + (~(vector bool long long)__c & __a)); +} + +static inline __ATTRS_o_ai vector bool long long +vec_sel(vector bool long long __a, vector bool long long __b, + vector bool long long __c) { + return (__c & __b) | (~__c & __a); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_sel(vector unsigned long long __a, vector unsigned long long __b, + vector unsigned long long __c) { + return (__c & __b) | (~__c & __a); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_sel(vector unsigned long long __a, vector unsigned long long __b, + vector bool long long __c) { + return (((vector unsigned long long)__c & __b) | + (~(vector unsigned long long)__c & __a)); +} + +static inline __ATTRS_o_ai vector double +vec_sel(vector double __a, vector double __b, vector unsigned long long __c) { + return (vector double)((__c & (vector unsigned long long)__b) | + (~__c & (vector unsigned long long)__a)); +} + +static inline __ATTRS_o_ai vector double +vec_sel(vector double __a, vector double __b, vector bool long long __c) { + vector unsigned long long __ac = (vector unsigned long long)__a; + vector unsigned long long __bc = (vector unsigned long long)__b; + vector unsigned long long __cc = (vector unsigned long long)__c; + return (vector double)((__cc & __bc) | (~__cc & __ac)); +} + +/*-- vec_gather_element -----------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed int +vec_gather_element(vector signed int __vec, vector unsigned int __offset, + const signed int *__ptr, int __index) + __constant_range(__index, 0, 3) { + __vec[__index] = *(const signed int *)( + (__INTPTR_TYPE__)__ptr + (__INTPTR_TYPE__)__offset[__index]); + return __vec; +} + +static inline __ATTRS_o_ai vector bool int +vec_gather_element(vector bool int __vec, vector unsigned int __offset, + const unsigned int *__ptr, int __index) + __constant_range(__index, 0, 3) { + __vec[__index] = *(const unsigned int *)( + (__INTPTR_TYPE__)__ptr + (__INTPTR_TYPE__)__offset[__index]); + return __vec; +} + +static inline __ATTRS_o_ai vector unsigned int +vec_gather_element(vector unsigned int __vec, vector unsigned int __offset, + const unsigned int *__ptr, int __index) + __constant_range(__index, 0, 3) { + __vec[__index] = *(const unsigned int *)( + (__INTPTR_TYPE__)__ptr + (__INTPTR_TYPE__)__offset[__index]); + return __vec; +} + +static inline __ATTRS_o_ai vector signed long long +vec_gather_element(vector signed long long __vec, + vector unsigned long long __offset, + const signed long long *__ptr, int __index) + __constant_range(__index, 0, 1) { + __vec[__index] = *(const signed long long *)( + (__INTPTR_TYPE__)__ptr + (__INTPTR_TYPE__)__offset[__index]); + return __vec; +} + +static inline __ATTRS_o_ai vector bool long long +vec_gather_element(vector bool long long __vec, + vector unsigned long long __offset, + const unsigned long long *__ptr, int __index) + __constant_range(__index, 0, 1) { + __vec[__index] = *(const unsigned long long *)( + (__INTPTR_TYPE__)__ptr + (__INTPTR_TYPE__)__offset[__index]); + return __vec; +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_gather_element(vector unsigned long long __vec, + vector unsigned long long __offset, + const unsigned long long *__ptr, int __index) + __constant_range(__index, 0, 1) { + __vec[__index] = *(const unsigned long long *)( + (__INTPTR_TYPE__)__ptr + (__INTPTR_TYPE__)__offset[__index]); + return __vec; +} + +static inline __ATTRS_o_ai vector double +vec_gather_element(vector double __vec, vector unsigned long long __offset, + const double *__ptr, int __index) + __constant_range(__index, 0, 1) { + __vec[__index] = *(const double *)( + (__INTPTR_TYPE__)__ptr + (__INTPTR_TYPE__)__offset[__index]); + return __vec; +} + +/*-- vec_scatter_element ----------------------------------------------------*/ + +static inline __ATTRS_o_ai void +vec_scatter_element(vector signed int __vec, vector unsigned int __offset, + signed int *__ptr, int __index) + __constant_range(__index, 0, 3) { + *(signed int *)((__INTPTR_TYPE__)__ptr + __offset[__index]) = + __vec[__index]; +} + +static inline __ATTRS_o_ai void +vec_scatter_element(vector bool int __vec, vector unsigned int __offset, + unsigned int *__ptr, int __index) + __constant_range(__index, 0, 3) { + *(unsigned int *)((__INTPTR_TYPE__)__ptr + __offset[__index]) = + __vec[__index]; +} + +static inline __ATTRS_o_ai void +vec_scatter_element(vector unsigned int __vec, vector unsigned int __offset, + unsigned int *__ptr, int __index) + __constant_range(__index, 0, 3) { + *(unsigned int *)((__INTPTR_TYPE__)__ptr + __offset[__index]) = + __vec[__index]; +} + +static inline __ATTRS_o_ai void +vec_scatter_element(vector signed long long __vec, + vector unsigned long long __offset, + signed long long *__ptr, int __index) + __constant_range(__index, 0, 1) { + *(signed long long *)((__INTPTR_TYPE__)__ptr + __offset[__index]) = + __vec[__index]; +} + +static inline __ATTRS_o_ai void +vec_scatter_element(vector bool long long __vec, + vector unsigned long long __offset, + unsigned long long *__ptr, int __index) + __constant_range(__index, 0, 1) { + *(unsigned long long *)((__INTPTR_TYPE__)__ptr + __offset[__index]) = + __vec[__index]; +} + +static inline __ATTRS_o_ai void +vec_scatter_element(vector unsigned long long __vec, + vector unsigned long long __offset, + unsigned long long *__ptr, int __index) + __constant_range(__index, 0, 1) { + *(unsigned long long *)((__INTPTR_TYPE__)__ptr + __offset[__index]) = + __vec[__index]; +} + +static inline __ATTRS_o_ai void +vec_scatter_element(vector double __vec, vector unsigned long long __offset, + double *__ptr, int __index) + __constant_range(__index, 0, 1) { + *(double *)((__INTPTR_TYPE__)__ptr + __offset[__index]) = + __vec[__index]; +} + +/*-- vec_xld2 ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_xld2(long __offset, const signed char *__ptr) { + return *(const vector signed char *)((__INTPTR_TYPE__)__ptr + __offset); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_xld2(long __offset, const unsigned char *__ptr) { + return *(const vector unsigned char *)((__INTPTR_TYPE__)__ptr + __offset); +} + +static inline __ATTRS_o_ai vector signed short +vec_xld2(long __offset, const signed short *__ptr) { + return *(const vector signed short *)((__INTPTR_TYPE__)__ptr + __offset); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_xld2(long __offset, const unsigned short *__ptr) { + return *(const vector unsigned short *)((__INTPTR_TYPE__)__ptr + __offset); +} + +static inline __ATTRS_o_ai vector signed int +vec_xld2(long __offset, const signed int *__ptr) { + return *(const vector signed int *)((__INTPTR_TYPE__)__ptr + __offset); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_xld2(long __offset, const unsigned int *__ptr) { + return *(const vector unsigned int *)((__INTPTR_TYPE__)__ptr + __offset); +} + +static inline __ATTRS_o_ai vector signed long long +vec_xld2(long __offset, const signed long long *__ptr) { + return *(const vector signed long long *)((__INTPTR_TYPE__)__ptr + __offset); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_xld2(long __offset, const unsigned long long *__ptr) { + return *(const vector unsigned long long *)((__INTPTR_TYPE__)__ptr + __offset); +} + +static inline __ATTRS_o_ai vector double +vec_xld2(long __offset, const double *__ptr) { + return *(const vector double *)((__INTPTR_TYPE__)__ptr + __offset); +} + +/*-- vec_xlw4 ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_xlw4(long __offset, const signed char *__ptr) { + return *(const vector signed char *)((__INTPTR_TYPE__)__ptr + __offset); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_xlw4(long __offset, const unsigned char *__ptr) { + return *(const vector unsigned char *)((__INTPTR_TYPE__)__ptr + __offset); +} + +static inline __ATTRS_o_ai vector signed short +vec_xlw4(long __offset, const signed short *__ptr) { + return *(const vector signed short *)((__INTPTR_TYPE__)__ptr + __offset); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_xlw4(long __offset, const unsigned short *__ptr) { + return *(const vector unsigned short *)((__INTPTR_TYPE__)__ptr + __offset); +} + +static inline __ATTRS_o_ai vector signed int +vec_xlw4(long __offset, const signed int *__ptr) { + return *(const vector signed int *)((__INTPTR_TYPE__)__ptr + __offset); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_xlw4(long __offset, const unsigned int *__ptr) { + return *(const vector unsigned int *)((__INTPTR_TYPE__)__ptr + __offset); +} + +/*-- vec_xstd2 --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai void +vec_xstd2(vector signed char __vec, long __offset, signed char *__ptr) { + *(vector signed char *)((__INTPTR_TYPE__)__ptr + __offset) = __vec; +} + +static inline __ATTRS_o_ai void +vec_xstd2(vector unsigned char __vec, long __offset, unsigned char *__ptr) { + *(vector unsigned char *)((__INTPTR_TYPE__)__ptr + __offset) = __vec; +} + +static inline __ATTRS_o_ai void +vec_xstd2(vector signed short __vec, long __offset, signed short *__ptr) { + *(vector signed short *)((__INTPTR_TYPE__)__ptr + __offset) = __vec; +} + +static inline __ATTRS_o_ai void +vec_xstd2(vector unsigned short __vec, long __offset, unsigned short *__ptr) { + *(vector unsigned short *)((__INTPTR_TYPE__)__ptr + __offset) = __vec; +} + +static inline __ATTRS_o_ai void +vec_xstd2(vector signed int __vec, long __offset, signed int *__ptr) { + *(vector signed int *)((__INTPTR_TYPE__)__ptr + __offset) = __vec; +} + +static inline __ATTRS_o_ai void +vec_xstd2(vector unsigned int __vec, long __offset, unsigned int *__ptr) { + *(vector unsigned int *)((__INTPTR_TYPE__)__ptr + __offset) = __vec; +} + +static inline __ATTRS_o_ai void +vec_xstd2(vector signed long long __vec, long __offset, + signed long long *__ptr) { + *(vector signed long long *)((__INTPTR_TYPE__)__ptr + __offset) = __vec; +} + +static inline __ATTRS_o_ai void +vec_xstd2(vector unsigned long long __vec, long __offset, + unsigned long long *__ptr) { + *(vector unsigned long long *)((__INTPTR_TYPE__)__ptr + __offset) = + __vec; +} + +static inline __ATTRS_o_ai void +vec_xstd2(vector double __vec, long __offset, double *__ptr) { + *(vector double *)((__INTPTR_TYPE__)__ptr + __offset) = __vec; +} + +/*-- vec_xstw4 --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai void +vec_xstw4(vector signed char __vec, long __offset, signed char *__ptr) { + *(vector signed char *)((__INTPTR_TYPE__)__ptr + __offset) = __vec; +} + +static inline __ATTRS_o_ai void +vec_xstw4(vector unsigned char __vec, long __offset, unsigned char *__ptr) { + *(vector unsigned char *)((__INTPTR_TYPE__)__ptr + __offset) = __vec; +} + +static inline __ATTRS_o_ai void +vec_xstw4(vector signed short __vec, long __offset, signed short *__ptr) { + *(vector signed short *)((__INTPTR_TYPE__)__ptr + __offset) = __vec; +} + +static inline __ATTRS_o_ai void +vec_xstw4(vector unsigned short __vec, long __offset, unsigned short *__ptr) { + *(vector unsigned short *)((__INTPTR_TYPE__)__ptr + __offset) = __vec; +} + +static inline __ATTRS_o_ai void +vec_xstw4(vector signed int __vec, long __offset, signed int *__ptr) { + *(vector signed int *)((__INTPTR_TYPE__)__ptr + __offset) = __vec; +} + +static inline __ATTRS_o_ai void +vec_xstw4(vector unsigned int __vec, long __offset, unsigned int *__ptr) { + *(vector unsigned int *)((__INTPTR_TYPE__)__ptr + __offset) = __vec; +} + +/*-- vec_load_bndry ---------------------------------------------------------*/ + +extern __ATTRS_o vector signed char +vec_load_bndry(const signed char *__ptr, unsigned short __len) + __constant_pow2_range(__len, 64, 4096); + +extern __ATTRS_o vector unsigned char +vec_load_bndry(const unsigned char *__ptr, unsigned short __len) + __constant_pow2_range(__len, 64, 4096); + +extern __ATTRS_o vector signed short +vec_load_bndry(const signed short *__ptr, unsigned short __len) + __constant_pow2_range(__len, 64, 4096); + +extern __ATTRS_o vector unsigned short +vec_load_bndry(const unsigned short *__ptr, unsigned short __len) + __constant_pow2_range(__len, 64, 4096); + +extern __ATTRS_o vector signed int +vec_load_bndry(const signed int *__ptr, unsigned short __len) + __constant_pow2_range(__len, 64, 4096); + +extern __ATTRS_o vector unsigned int +vec_load_bndry(const unsigned int *__ptr, unsigned short __len) + __constant_pow2_range(__len, 64, 4096); + +extern __ATTRS_o vector signed long long +vec_load_bndry(const signed long long *__ptr, unsigned short __len) + __constant_pow2_range(__len, 64, 4096); + +extern __ATTRS_o vector unsigned long long +vec_load_bndry(const unsigned long long *__ptr, unsigned short __len) + __constant_pow2_range(__len, 64, 4096); + +extern __ATTRS_o vector double +vec_load_bndry(const double *__ptr, unsigned short __len) + __constant_pow2_range(__len, 64, 4096); + +#define vec_load_bndry(X, Y) ((__typeof__((vec_load_bndry)((X), (Y)))) \ + __builtin_s390_vlbb((X), ((Y) == 64 ? 0 : \ + (Y) == 128 ? 1 : \ + (Y) == 256 ? 2 : \ + (Y) == 512 ? 3 : \ + (Y) == 1024 ? 4 : \ + (Y) == 2048 ? 5 : \ + (Y) == 4096 ? 6 : -1))) + +/*-- vec_load_len -----------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_load_len(const signed char *__ptr, unsigned int __len) { + return (vector signed char)__builtin_s390_vll(__len, __ptr); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_load_len(const unsigned char *__ptr, unsigned int __len) { + return (vector unsigned char)__builtin_s390_vll(__len, __ptr); +} + +static inline __ATTRS_o_ai vector signed short +vec_load_len(const signed short *__ptr, unsigned int __len) { + return (vector signed short)__builtin_s390_vll(__len, __ptr); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_load_len(const unsigned short *__ptr, unsigned int __len) { + return (vector unsigned short)__builtin_s390_vll(__len, __ptr); +} + +static inline __ATTRS_o_ai vector signed int +vec_load_len(const signed int *__ptr, unsigned int __len) { + return (vector signed int)__builtin_s390_vll(__len, __ptr); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_load_len(const unsigned int *__ptr, unsigned int __len) { + return (vector unsigned int)__builtin_s390_vll(__len, __ptr); +} + +static inline __ATTRS_o_ai vector signed long long +vec_load_len(const signed long long *__ptr, unsigned int __len) { + return (vector signed long long)__builtin_s390_vll(__len, __ptr); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_load_len(const unsigned long long *__ptr, unsigned int __len) { + return (vector unsigned long long)__builtin_s390_vll(__len, __ptr); +} + +static inline __ATTRS_o_ai vector double +vec_load_len(const double *__ptr, unsigned int __len) { + return (vector double)__builtin_s390_vll(__len, __ptr); +} + +/*-- vec_store_len ----------------------------------------------------------*/ + +static inline __ATTRS_o_ai void +vec_store_len(vector signed char __vec, signed char *__ptr, + unsigned int __len) { + __builtin_s390_vstl((vector signed char)__vec, __len, __ptr); +} + +static inline __ATTRS_o_ai void +vec_store_len(vector unsigned char __vec, unsigned char *__ptr, + unsigned int __len) { + __builtin_s390_vstl((vector signed char)__vec, __len, __ptr); +} + +static inline __ATTRS_o_ai void +vec_store_len(vector signed short __vec, signed short *__ptr, + unsigned int __len) { + __builtin_s390_vstl((vector signed char)__vec, __len, __ptr); +} + +static inline __ATTRS_o_ai void +vec_store_len(vector unsigned short __vec, unsigned short *__ptr, + unsigned int __len) { + __builtin_s390_vstl((vector signed char)__vec, __len, __ptr); +} + +static inline __ATTRS_o_ai void +vec_store_len(vector signed int __vec, signed int *__ptr, + unsigned int __len) { + __builtin_s390_vstl((vector signed char)__vec, __len, __ptr); +} + +static inline __ATTRS_o_ai void +vec_store_len(vector unsigned int __vec, unsigned int *__ptr, + unsigned int __len) { + __builtin_s390_vstl((vector signed char)__vec, __len, __ptr); +} + +static inline __ATTRS_o_ai void +vec_store_len(vector signed long long __vec, signed long long *__ptr, + unsigned int __len) { + __builtin_s390_vstl((vector signed char)__vec, __len, __ptr); +} + +static inline __ATTRS_o_ai void +vec_store_len(vector unsigned long long __vec, unsigned long long *__ptr, + unsigned int __len) { + __builtin_s390_vstl((vector signed char)__vec, __len, __ptr); +} + +static inline __ATTRS_o_ai void +vec_store_len(vector double __vec, double *__ptr, + unsigned int __len) { + __builtin_s390_vstl((vector signed char)__vec, __len, __ptr); +} + +/*-- vec_load_pair ----------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed long long +vec_load_pair(signed long long __a, signed long long __b) { + return (vector signed long long)(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_load_pair(unsigned long long __a, unsigned long long __b) { + return (vector unsigned long long)(__a, __b); +} + +/*-- vec_genmask ------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_genmask(unsigned short __mask) + __constant(__mask) { + return (vector unsigned char)( + __mask & 0x8000 ? 0xff : 0, + __mask & 0x4000 ? 0xff : 0, + __mask & 0x2000 ? 0xff : 0, + __mask & 0x1000 ? 0xff : 0, + __mask & 0x0800 ? 0xff : 0, + __mask & 0x0400 ? 0xff : 0, + __mask & 0x0200 ? 0xff : 0, + __mask & 0x0100 ? 0xff : 0, + __mask & 0x0080 ? 0xff : 0, + __mask & 0x0040 ? 0xff : 0, + __mask & 0x0020 ? 0xff : 0, + __mask & 0x0010 ? 0xff : 0, + __mask & 0x0008 ? 0xff : 0, + __mask & 0x0004 ? 0xff : 0, + __mask & 0x0002 ? 0xff : 0, + __mask & 0x0001 ? 0xff : 0); +} + +/*-- vec_genmasks_* ---------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_genmasks_8(unsigned char __first, unsigned char __last) + __constant(__first) __constant(__last) { + unsigned char __bit1 = __first & 7; + unsigned char __bit2 = __last & 7; + unsigned char __mask1 = (unsigned char)(1U << (7 - __bit1) << 1) - 1; + unsigned char __mask2 = (unsigned char)(1U << (7 - __bit2)) - 1; + unsigned char __value = (__bit1 <= __bit2 ? + __mask1 & ~__mask2 : + __mask1 | ~__mask2); + return (vector unsigned char)__value; +} + +static inline __ATTRS_o_ai vector unsigned short +vec_genmasks_16(unsigned char __first, unsigned char __last) + __constant(__first) __constant(__last) { + unsigned char __bit1 = __first & 15; + unsigned char __bit2 = __last & 15; + unsigned short __mask1 = (unsigned short)(1U << (15 - __bit1) << 1) - 1; + unsigned short __mask2 = (unsigned short)(1U << (15 - __bit2)) - 1; + unsigned short __value = (__bit1 <= __bit2 ? + __mask1 & ~__mask2 : + __mask1 | ~__mask2); + return (vector unsigned short)__value; +} + +static inline __ATTRS_o_ai vector unsigned int +vec_genmasks_32(unsigned char __first, unsigned char __last) + __constant(__first) __constant(__last) { + unsigned char __bit1 = __first & 31; + unsigned char __bit2 = __last & 31; + unsigned int __mask1 = (1U << (31 - __bit1) << 1) - 1; + unsigned int __mask2 = (1U << (31 - __bit2)) - 1; + unsigned int __value = (__bit1 <= __bit2 ? + __mask1 & ~__mask2 : + __mask1 | ~__mask2); + return (vector unsigned int)__value; +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_genmasks_64(unsigned char __first, unsigned char __last) + __constant(__first) __constant(__last) { + unsigned char __bit1 = __first & 63; + unsigned char __bit2 = __last & 63; + unsigned long long __mask1 = (1ULL << (63 - __bit1) << 1) - 1; + unsigned long long __mask2 = (1ULL << (63 - __bit2)) - 1; + unsigned long long __value = (__bit1 <= __bit2 ? + __mask1 & ~__mask2 : + __mask1 | ~__mask2); + return (vector unsigned long long)__value; +} + +/*-- vec_splat --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_splat(vector signed char __vec, int __index) + __constant_range(__index, 0, 15) { + return (vector signed char)__vec[__index]; +} + +static inline __ATTRS_o_ai vector bool char +vec_splat(vector bool char __vec, int __index) + __constant_range(__index, 0, 15) { + return (vector bool char)(vector unsigned char)__vec[__index]; +} + +static inline __ATTRS_o_ai vector unsigned char +vec_splat(vector unsigned char __vec, int __index) + __constant_range(__index, 0, 15) { + return (vector unsigned char)__vec[__index]; +} + +static inline __ATTRS_o_ai vector signed short +vec_splat(vector signed short __vec, int __index) + __constant_range(__index, 0, 7) { + return (vector signed short)__vec[__index]; +} + +static inline __ATTRS_o_ai vector bool short +vec_splat(vector bool short __vec, int __index) + __constant_range(__index, 0, 7) { + return (vector bool short)(vector unsigned short)__vec[__index]; +} + +static inline __ATTRS_o_ai vector unsigned short +vec_splat(vector unsigned short __vec, int __index) + __constant_range(__index, 0, 7) { + return (vector unsigned short)__vec[__index]; +} + +static inline __ATTRS_o_ai vector signed int +vec_splat(vector signed int __vec, int __index) + __constant_range(__index, 0, 3) { + return (vector signed int)__vec[__index]; +} + +static inline __ATTRS_o_ai vector bool int +vec_splat(vector bool int __vec, int __index) + __constant_range(__index, 0, 3) { + return (vector bool int)(vector unsigned int)__vec[__index]; +} + +static inline __ATTRS_o_ai vector unsigned int +vec_splat(vector unsigned int __vec, int __index) + __constant_range(__index, 0, 3) { + return (vector unsigned int)__vec[__index]; +} + +static inline __ATTRS_o_ai vector signed long long +vec_splat(vector signed long long __vec, int __index) + __constant_range(__index, 0, 1) { + return (vector signed long long)__vec[__index]; +} + +static inline __ATTRS_o_ai vector bool long long +vec_splat(vector bool long long __vec, int __index) + __constant_range(__index, 0, 1) { + return (vector bool long long)(vector unsigned long long)__vec[__index]; +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_splat(vector unsigned long long __vec, int __index) + __constant_range(__index, 0, 1) { + return (vector unsigned long long)__vec[__index]; +} + +static inline __ATTRS_o_ai vector double +vec_splat(vector double __vec, int __index) + __constant_range(__index, 0, 1) { + return (vector double)__vec[__index]; +} + +/*-- vec_splat_s* -----------------------------------------------------------*/ + +static inline __ATTRS_ai vector signed char +vec_splat_s8(signed char __scalar) + __constant(__scalar) { + return (vector signed char)__scalar; +} + +static inline __ATTRS_ai vector signed short +vec_splat_s16(signed short __scalar) + __constant(__scalar) { + return (vector signed short)__scalar; +} + +static inline __ATTRS_ai vector signed int +vec_splat_s32(signed short __scalar) + __constant(__scalar) { + return (vector signed int)(signed int)__scalar; +} + +static inline __ATTRS_ai vector signed long long +vec_splat_s64(signed short __scalar) + __constant(__scalar) { + return (vector signed long long)(signed long)__scalar; +} + +/*-- vec_splat_u* -----------------------------------------------------------*/ + +static inline __ATTRS_ai vector unsigned char +vec_splat_u8(unsigned char __scalar) + __constant(__scalar) { + return (vector unsigned char)__scalar; +} + +static inline __ATTRS_ai vector unsigned short +vec_splat_u16(unsigned short __scalar) + __constant(__scalar) { + return (vector unsigned short)__scalar; +} + +static inline __ATTRS_ai vector unsigned int +vec_splat_u32(signed short __scalar) + __constant(__scalar) { + return (vector unsigned int)(signed int)__scalar; +} + +static inline __ATTRS_ai vector unsigned long long +vec_splat_u64(signed short __scalar) + __constant(__scalar) { + return (vector unsigned long long)(signed long long)__scalar; +} + +/*-- vec_splats -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_splats(signed char __scalar) { + return (vector signed char)__scalar; +} + +static inline __ATTRS_o_ai vector unsigned char +vec_splats(unsigned char __scalar) { + return (vector unsigned char)__scalar; +} + +static inline __ATTRS_o_ai vector signed short +vec_splats(signed short __scalar) { + return (vector signed short)__scalar; +} + +static inline __ATTRS_o_ai vector unsigned short +vec_splats(unsigned short __scalar) { + return (vector unsigned short)__scalar; +} + +static inline __ATTRS_o_ai vector signed int +vec_splats(signed int __scalar) { + return (vector signed int)__scalar; +} + +static inline __ATTRS_o_ai vector unsigned int +vec_splats(unsigned int __scalar) { + return (vector unsigned int)__scalar; +} + +static inline __ATTRS_o_ai vector signed long long +vec_splats(signed long long __scalar) { + return (vector signed long long)__scalar; +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_splats(unsigned long long __scalar) { + return (vector unsigned long long)__scalar; +} + +static inline __ATTRS_o_ai vector double +vec_splats(double __scalar) { + return (vector double)__scalar; +} + +/*-- vec_extend_s64 ---------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed long long +vec_extend_s64(vector signed char __a) { + return (vector signed long long)(__a[7], __a[15]); +} + +static inline __ATTRS_o_ai vector signed long long +vec_extend_s64(vector signed short __a) { + return (vector signed long long)(__a[3], __a[7]); +} + +static inline __ATTRS_o_ai vector signed long long +vec_extend_s64(vector signed int __a) { + return (vector signed long long)(__a[1], __a[3]); +} + +/*-- vec_mergeh -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_mergeh(vector signed char __a, vector signed char __b) { + return (vector signed char)( + __a[0], __b[0], __a[1], __b[1], __a[2], __b[2], __a[3], __b[3], + __a[4], __b[4], __a[5], __b[5], __a[6], __b[6], __a[7], __b[7]); +} + +static inline __ATTRS_o_ai vector bool char +vec_mergeh(vector bool char __a, vector bool char __b) { + return (vector bool char)( + __a[0], __b[0], __a[1], __b[1], __a[2], __b[2], __a[3], __b[3], + __a[4], __b[4], __a[5], __b[5], __a[6], __b[6], __a[7], __b[7]); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_mergeh(vector unsigned char __a, vector unsigned char __b) { + return (vector unsigned char)( + __a[0], __b[0], __a[1], __b[1], __a[2], __b[2], __a[3], __b[3], + __a[4], __b[4], __a[5], __b[5], __a[6], __b[6], __a[7], __b[7]); +} + +static inline __ATTRS_o_ai vector signed short +vec_mergeh(vector signed short __a, vector signed short __b) { + return (vector signed short)( + __a[0], __b[0], __a[1], __b[1], __a[2], __b[2], __a[3], __b[3]); +} + +static inline __ATTRS_o_ai vector bool short +vec_mergeh(vector bool short __a, vector bool short __b) { + return (vector bool short)( + __a[0], __b[0], __a[1], __b[1], __a[2], __b[2], __a[3], __b[3]); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_mergeh(vector unsigned short __a, vector unsigned short __b) { + return (vector unsigned short)( + __a[0], __b[0], __a[1], __b[1], __a[2], __b[2], __a[3], __b[3]); +} + +static inline __ATTRS_o_ai vector signed int +vec_mergeh(vector signed int __a, vector signed int __b) { + return (vector signed int)(__a[0], __b[0], __a[1], __b[1]); +} + +static inline __ATTRS_o_ai vector bool int +vec_mergeh(vector bool int __a, vector bool int __b) { + return (vector bool int)(__a[0], __b[0], __a[1], __b[1]); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_mergeh(vector unsigned int __a, vector unsigned int __b) { + return (vector unsigned int)(__a[0], __b[0], __a[1], __b[1]); +} + +static inline __ATTRS_o_ai vector signed long long +vec_mergeh(vector signed long long __a, vector signed long long __b) { + return (vector signed long long)(__a[0], __b[0]); +} + +static inline __ATTRS_o_ai vector bool long long +vec_mergeh(vector bool long long __a, vector bool long long __b) { + return (vector bool long long)(__a[0], __b[0]); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_mergeh(vector unsigned long long __a, vector unsigned long long __b) { + return (vector unsigned long long)(__a[0], __b[0]); +} + +static inline __ATTRS_o_ai vector double +vec_mergeh(vector double __a, vector double __b) { + return (vector double)(__a[0], __b[0]); +} + +/*-- vec_mergel -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_mergel(vector signed char __a, vector signed char __b) { + return (vector signed char)( + __a[8], __b[8], __a[9], __b[9], __a[10], __b[10], __a[11], __b[11], + __a[12], __b[12], __a[13], __b[13], __a[14], __b[14], __a[15], __b[15]); +} + +static inline __ATTRS_o_ai vector bool char +vec_mergel(vector bool char __a, vector bool char __b) { + return (vector bool char)( + __a[8], __b[8], __a[9], __b[9], __a[10], __b[10], __a[11], __b[11], + __a[12], __b[12], __a[13], __b[13], __a[14], __b[14], __a[15], __b[15]); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_mergel(vector unsigned char __a, vector unsigned char __b) { + return (vector unsigned char)( + __a[8], __b[8], __a[9], __b[9], __a[10], __b[10], __a[11], __b[11], + __a[12], __b[12], __a[13], __b[13], __a[14], __b[14], __a[15], __b[15]); +} + +static inline __ATTRS_o_ai vector signed short +vec_mergel(vector signed short __a, vector signed short __b) { + return (vector signed short)( + __a[4], __b[4], __a[5], __b[5], __a[6], __b[6], __a[7], __b[7]); +} + +static inline __ATTRS_o_ai vector bool short +vec_mergel(vector bool short __a, vector bool short __b) { + return (vector bool short)( + __a[4], __b[4], __a[5], __b[5], __a[6], __b[6], __a[7], __b[7]); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_mergel(vector unsigned short __a, vector unsigned short __b) { + return (vector unsigned short)( + __a[4], __b[4], __a[5], __b[5], __a[6], __b[6], __a[7], __b[7]); +} + +static inline __ATTRS_o_ai vector signed int +vec_mergel(vector signed int __a, vector signed int __b) { + return (vector signed int)(__a[2], __b[2], __a[3], __b[3]); +} + +static inline __ATTRS_o_ai vector bool int +vec_mergel(vector bool int __a, vector bool int __b) { + return (vector bool int)(__a[2], __b[2], __a[3], __b[3]); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_mergel(vector unsigned int __a, vector unsigned int __b) { + return (vector unsigned int)(__a[2], __b[2], __a[3], __b[3]); +} + +static inline __ATTRS_o_ai vector signed long long +vec_mergel(vector signed long long __a, vector signed long long __b) { + return (vector signed long long)(__a[1], __b[1]); +} + +static inline __ATTRS_o_ai vector bool long long +vec_mergel(vector bool long long __a, vector bool long long __b) { + return (vector bool long long)(__a[1], __b[1]); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_mergel(vector unsigned long long __a, vector unsigned long long __b) { + return (vector unsigned long long)(__a[1], __b[1]); +} + +static inline __ATTRS_o_ai vector double +vec_mergel(vector double __a, vector double __b) { + return (vector double)(__a[1], __b[1]); +} + +/*-- vec_pack ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_pack(vector signed short __a, vector signed short __b) { + vector signed char __ac = (vector signed char)__a; + vector signed char __bc = (vector signed char)__b; + return (vector signed char)( + __ac[1], __ac[3], __ac[5], __ac[7], __ac[9], __ac[11], __ac[13], __ac[15], + __bc[1], __bc[3], __bc[5], __bc[7], __bc[9], __bc[11], __bc[13], __bc[15]); +} + +static inline __ATTRS_o_ai vector bool char +vec_pack(vector bool short __a, vector bool short __b) { + vector bool char __ac = (vector bool char)__a; + vector bool char __bc = (vector bool char)__b; + return (vector bool char)( + __ac[1], __ac[3], __ac[5], __ac[7], __ac[9], __ac[11], __ac[13], __ac[15], + __bc[1], __bc[3], __bc[5], __bc[7], __bc[9], __bc[11], __bc[13], __bc[15]); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_pack(vector unsigned short __a, vector unsigned short __b) { + vector unsigned char __ac = (vector unsigned char)__a; + vector unsigned char __bc = (vector unsigned char)__b; + return (vector unsigned char)( + __ac[1], __ac[3], __ac[5], __ac[7], __ac[9], __ac[11], __ac[13], __ac[15], + __bc[1], __bc[3], __bc[5], __bc[7], __bc[9], __bc[11], __bc[13], __bc[15]); +} + +static inline __ATTRS_o_ai vector signed short +vec_pack(vector signed int __a, vector signed int __b) { + vector signed short __ac = (vector signed short)__a; + vector signed short __bc = (vector signed short)__b; + return (vector signed short)( + __ac[1], __ac[3], __ac[5], __ac[7], + __bc[1], __bc[3], __bc[5], __bc[7]); +} + +static inline __ATTRS_o_ai vector bool short +vec_pack(vector bool int __a, vector bool int __b) { + vector bool short __ac = (vector bool short)__a; + vector bool short __bc = (vector bool short)__b; + return (vector bool short)( + __ac[1], __ac[3], __ac[5], __ac[7], + __bc[1], __bc[3], __bc[5], __bc[7]); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_pack(vector unsigned int __a, vector unsigned int __b) { + vector unsigned short __ac = (vector unsigned short)__a; + vector unsigned short __bc = (vector unsigned short)__b; + return (vector unsigned short)( + __ac[1], __ac[3], __ac[5], __ac[7], + __bc[1], __bc[3], __bc[5], __bc[7]); +} + +static inline __ATTRS_o_ai vector signed int +vec_pack(vector signed long long __a, vector signed long long __b) { + vector signed int __ac = (vector signed int)__a; + vector signed int __bc = (vector signed int)__b; + return (vector signed int)(__ac[1], __ac[3], __bc[1], __bc[3]); +} + +static inline __ATTRS_o_ai vector bool int +vec_pack(vector bool long long __a, vector bool long long __b) { + vector bool int __ac = (vector bool int)__a; + vector bool int __bc = (vector bool int)__b; + return (vector bool int)(__ac[1], __ac[3], __bc[1], __bc[3]); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_pack(vector unsigned long long __a, vector unsigned long long __b) { + vector unsigned int __ac = (vector unsigned int)__a; + vector unsigned int __bc = (vector unsigned int)__b; + return (vector unsigned int)(__ac[1], __ac[3], __bc[1], __bc[3]); +} + +/*-- vec_packs --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_packs(vector signed short __a, vector signed short __b) { + return __builtin_s390_vpksh(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_packs(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vpklsh(__a, __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_packs(vector signed int __a, vector signed int __b) { + return __builtin_s390_vpksf(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_packs(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vpklsf(__a, __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_packs(vector signed long long __a, vector signed long long __b) { + return __builtin_s390_vpksg(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_packs(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_s390_vpklsg(__a, __b); +} + +/*-- vec_packs_cc -----------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_packs_cc(vector signed short __a, vector signed short __b, int *__cc) { + return __builtin_s390_vpkshs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_packs_cc(vector unsigned short __a, vector unsigned short __b, int *__cc) { + return __builtin_s390_vpklshs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector signed short +vec_packs_cc(vector signed int __a, vector signed int __b, int *__cc) { + return __builtin_s390_vpksfs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_packs_cc(vector unsigned int __a, vector unsigned int __b, int *__cc) { + return __builtin_s390_vpklsfs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector signed int +vec_packs_cc(vector signed long long __a, vector signed long long __b, + int *__cc) { + return __builtin_s390_vpksgs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_packs_cc(vector unsigned long long __a, vector unsigned long long __b, + int *__cc) { + return __builtin_s390_vpklsgs(__a, __b, __cc); +} + +/*-- vec_packsu -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_packsu(vector signed short __a, vector signed short __b) { + const vector signed short __zero = (vector signed short)0; + return __builtin_s390_vpklsh( + (vector unsigned short)(__a >= __zero) & (vector unsigned short)__a, + (vector unsigned short)(__b >= __zero) & (vector unsigned short)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_packsu(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vpklsh(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_packsu(vector signed int __a, vector signed int __b) { + const vector signed int __zero = (vector signed int)0; + return __builtin_s390_vpklsf( + (vector unsigned int)(__a >= __zero) & (vector unsigned int)__a, + (vector unsigned int)(__b >= __zero) & (vector unsigned int)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_packsu(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vpklsf(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_packsu(vector signed long long __a, vector signed long long __b) { + const vector signed long long __zero = (vector signed long long)0; + return __builtin_s390_vpklsg( + (vector unsigned long long)(__a >= __zero) & + (vector unsigned long long)__a, + (vector unsigned long long)(__b >= __zero) & + (vector unsigned long long)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_packsu(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_s390_vpklsg(__a, __b); +} + +/*-- vec_packsu_cc ----------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_packsu_cc(vector unsigned short __a, vector unsigned short __b, int *__cc) { + return __builtin_s390_vpklshs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_packsu_cc(vector unsigned int __a, vector unsigned int __b, int *__cc) { + return __builtin_s390_vpklsfs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_packsu_cc(vector unsigned long long __a, vector unsigned long long __b, + int *__cc) { + return __builtin_s390_vpklsgs(__a, __b, __cc); +} + +/*-- vec_unpackh ------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed short +vec_unpackh(vector signed char __a) { + return __builtin_s390_vuphb(__a); +} + +static inline __ATTRS_o_ai vector bool short +vec_unpackh(vector bool char __a) { + return (vector bool short)__builtin_s390_vuphb((vector signed char)__a); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_unpackh(vector unsigned char __a) { + return __builtin_s390_vuplhb(__a); +} + +static inline __ATTRS_o_ai vector signed int +vec_unpackh(vector signed short __a) { + return __builtin_s390_vuphh(__a); +} + +static inline __ATTRS_o_ai vector bool int +vec_unpackh(vector bool short __a) { + return (vector bool int)__builtin_s390_vuphh((vector signed short)__a); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_unpackh(vector unsigned short __a) { + return __builtin_s390_vuplhh(__a); +} + +static inline __ATTRS_o_ai vector signed long long +vec_unpackh(vector signed int __a) { + return __builtin_s390_vuphf(__a); +} + +static inline __ATTRS_o_ai vector bool long long +vec_unpackh(vector bool int __a) { + return (vector bool long long)__builtin_s390_vuphf((vector signed int)__a); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_unpackh(vector unsigned int __a) { + return __builtin_s390_vuplhf(__a); +} + +/*-- vec_unpackl ------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed short +vec_unpackl(vector signed char __a) { + return __builtin_s390_vuplb(__a); +} + +static inline __ATTRS_o_ai vector bool short +vec_unpackl(vector bool char __a) { + return (vector bool short)__builtin_s390_vuplb((vector signed char)__a); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_unpackl(vector unsigned char __a) { + return __builtin_s390_vupllb(__a); +} + +static inline __ATTRS_o_ai vector signed int +vec_unpackl(vector signed short __a) { + return __builtin_s390_vuplhw(__a); +} + +static inline __ATTRS_o_ai vector bool int +vec_unpackl(vector bool short __a) { + return (vector bool int)__builtin_s390_vuplhw((vector signed short)__a); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_unpackl(vector unsigned short __a) { + return __builtin_s390_vupllh(__a); +} + +static inline __ATTRS_o_ai vector signed long long +vec_unpackl(vector signed int __a) { + return __builtin_s390_vuplf(__a); +} + +static inline __ATTRS_o_ai vector bool long long +vec_unpackl(vector bool int __a) { + return (vector bool long long)__builtin_s390_vuplf((vector signed int)__a); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_unpackl(vector unsigned int __a) { + return __builtin_s390_vupllf(__a); +} + +/*-- vec_cmpeq --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_cmpeq(vector bool char __a, vector bool char __b) { + return (vector bool char)(__a == __b); +} + +static inline __ATTRS_o_ai vector bool char +vec_cmpeq(vector signed char __a, vector signed char __b) { + return (vector bool char)(__a == __b); +} + +static inline __ATTRS_o_ai vector bool char +vec_cmpeq(vector unsigned char __a, vector unsigned char __b) { + return (vector bool char)(__a == __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmpeq(vector bool short __a, vector bool short __b) { + return (vector bool short)(__a == __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmpeq(vector signed short __a, vector signed short __b) { + return (vector bool short)(__a == __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmpeq(vector unsigned short __a, vector unsigned short __b) { + return (vector bool short)(__a == __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmpeq(vector bool int __a, vector bool int __b) { + return (vector bool int)(__a == __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmpeq(vector signed int __a, vector signed int __b) { + return (vector bool int)(__a == __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmpeq(vector unsigned int __a, vector unsigned int __b) { + return (vector bool int)(__a == __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmpeq(vector bool long long __a, vector bool long long __b) { + return (vector bool long long)(__a == __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmpeq(vector signed long long __a, vector signed long long __b) { + return (vector bool long long)(__a == __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmpeq(vector unsigned long long __a, vector unsigned long long __b) { + return (vector bool long long)(__a == __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmpeq(vector double __a, vector double __b) { + return (vector bool long long)(__a == __b); +} + +/*-- vec_cmpge --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_cmpge(vector signed char __a, vector signed char __b) { + return (vector bool char)(__a >= __b); +} + +static inline __ATTRS_o_ai vector bool char +vec_cmpge(vector unsigned char __a, vector unsigned char __b) { + return (vector bool char)(__a >= __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmpge(vector signed short __a, vector signed short __b) { + return (vector bool short)(__a >= __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmpge(vector unsigned short __a, vector unsigned short __b) { + return (vector bool short)(__a >= __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmpge(vector signed int __a, vector signed int __b) { + return (vector bool int)(__a >= __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmpge(vector unsigned int __a, vector unsigned int __b) { + return (vector bool int)(__a >= __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmpge(vector signed long long __a, vector signed long long __b) { + return (vector bool long long)(__a >= __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmpge(vector unsigned long long __a, vector unsigned long long __b) { + return (vector bool long long)(__a >= __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmpge(vector double __a, vector double __b) { + return (vector bool long long)(__a >= __b); +} + +/*-- vec_cmpgt --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_cmpgt(vector signed char __a, vector signed char __b) { + return (vector bool char)(__a > __b); +} + +static inline __ATTRS_o_ai vector bool char +vec_cmpgt(vector unsigned char __a, vector unsigned char __b) { + return (vector bool char)(__a > __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmpgt(vector signed short __a, vector signed short __b) { + return (vector bool short)(__a > __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmpgt(vector unsigned short __a, vector unsigned short __b) { + return (vector bool short)(__a > __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmpgt(vector signed int __a, vector signed int __b) { + return (vector bool int)(__a > __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmpgt(vector unsigned int __a, vector unsigned int __b) { + return (vector bool int)(__a > __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmpgt(vector signed long long __a, vector signed long long __b) { + return (vector bool long long)(__a > __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmpgt(vector unsigned long long __a, vector unsigned long long __b) { + return (vector bool long long)(__a > __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmpgt(vector double __a, vector double __b) { + return (vector bool long long)(__a > __b); +} + +/*-- vec_cmple --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_cmple(vector signed char __a, vector signed char __b) { + return (vector bool char)(__a <= __b); +} + +static inline __ATTRS_o_ai vector bool char +vec_cmple(vector unsigned char __a, vector unsigned char __b) { + return (vector bool char)(__a <= __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmple(vector signed short __a, vector signed short __b) { + return (vector bool short)(__a <= __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmple(vector unsigned short __a, vector unsigned short __b) { + return (vector bool short)(__a <= __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmple(vector signed int __a, vector signed int __b) { + return (vector bool int)(__a <= __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmple(vector unsigned int __a, vector unsigned int __b) { + return (vector bool int)(__a <= __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmple(vector signed long long __a, vector signed long long __b) { + return (vector bool long long)(__a <= __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmple(vector unsigned long long __a, vector unsigned long long __b) { + return (vector bool long long)(__a <= __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmple(vector double __a, vector double __b) { + return (vector bool long long)(__a <= __b); +} + +/*-- vec_cmplt --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_cmplt(vector signed char __a, vector signed char __b) { + return (vector bool char)(__a < __b); +} + +static inline __ATTRS_o_ai vector bool char +vec_cmplt(vector unsigned char __a, vector unsigned char __b) { + return (vector bool char)(__a < __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmplt(vector signed short __a, vector signed short __b) { + return (vector bool short)(__a < __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmplt(vector unsigned short __a, vector unsigned short __b) { + return (vector bool short)(__a < __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmplt(vector signed int __a, vector signed int __b) { + return (vector bool int)(__a < __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmplt(vector unsigned int __a, vector unsigned int __b) { + return (vector bool int)(__a < __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmplt(vector signed long long __a, vector signed long long __b) { + return (vector bool long long)(__a < __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmplt(vector unsigned long long __a, vector unsigned long long __b) { + return (vector bool long long)(__a < __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_cmplt(vector double __a, vector double __b) { + return (vector bool long long)(__a < __b); +} + +/*-- vec_all_eq -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai int +vec_all_eq(vector signed char __a, vector signed char __b) { + int __cc; + __builtin_s390_vceqbs(__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector signed char __a, vector bool char __b) { + int __cc; + __builtin_s390_vceqbs(__a, (vector signed char)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector bool char __a, vector signed char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector unsigned char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector unsigned char __a, vector bool char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector bool char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector bool char __a, vector bool char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector signed short __a, vector signed short __b) { + int __cc; + __builtin_s390_vceqhs(__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector signed short __a, vector bool short __b) { + int __cc; + __builtin_s390_vceqhs(__a, (vector signed short)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector bool short __a, vector signed short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector unsigned short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector unsigned short __a, vector bool short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector bool short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector bool short __a, vector bool short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector signed int __a, vector signed int __b) { + int __cc; + __builtin_s390_vceqfs(__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector signed int __a, vector bool int __b) { + int __cc; + __builtin_s390_vceqfs(__a, (vector signed int)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector bool int __a, vector signed int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector unsigned int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector unsigned int __a, vector bool int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector bool int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector bool int __a, vector bool int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector signed long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vceqgs(__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector signed long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vceqgs(__a, (vector signed long long)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector bool long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector unsigned long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector unsigned long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector bool long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector bool long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_eq(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfcedbs(__a, __b, &__cc); + return __cc == 0; +} + +/*-- vec_all_ne -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai int +vec_all_ne(vector signed char __a, vector signed char __b) { + int __cc; + __builtin_s390_vceqbs(__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector signed char __a, vector bool char __b) { + int __cc; + __builtin_s390_vceqbs(__a, (vector signed char)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector bool char __a, vector signed char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector unsigned char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector unsigned char __a, vector bool char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector bool char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector bool char __a, vector bool char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector signed short __a, vector signed short __b) { + int __cc; + __builtin_s390_vceqhs(__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector signed short __a, vector bool short __b) { + int __cc; + __builtin_s390_vceqhs(__a, (vector signed short)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector bool short __a, vector signed short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector unsigned short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector unsigned short __a, vector bool short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector bool short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector bool short __a, vector bool short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector signed int __a, vector signed int __b) { + int __cc; + __builtin_s390_vceqfs(__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector signed int __a, vector bool int __b) { + int __cc; + __builtin_s390_vceqfs(__a, (vector signed int)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector bool int __a, vector signed int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector unsigned int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector unsigned int __a, vector bool int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector bool int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector bool int __a, vector bool int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector signed long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vceqgs(__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector signed long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vceqgs(__a, (vector signed long long)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector bool long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector unsigned long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector unsigned long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector bool long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector bool long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ne(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfcedbs(__a, __b, &__cc); + return __cc == 3; +} + +/*-- vec_all_ge -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai int +vec_all_ge(vector signed char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs(__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector signed char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchbs((vector signed char)__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector bool char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs(__b, (vector signed char)__a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector unsigned char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs(__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector unsigned char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector bool char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs(__b, (vector unsigned char)__a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector bool char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__b, + (vector unsigned char)__a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector signed short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs(__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector signed short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchhs((vector signed short)__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector bool short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs(__b, (vector signed short)__a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector unsigned short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs(__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector unsigned short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector bool short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs(__b, (vector unsigned short)__a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector bool short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__b, + (vector unsigned short)__a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector signed int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs(__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector signed int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchfs((vector signed int)__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector bool int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs(__b, (vector signed int)__a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector unsigned int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs(__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector unsigned int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector bool int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs(__b, (vector unsigned int)__a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector bool int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__b, + (vector unsigned int)__a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector signed long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs(__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector signed long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchgs((vector signed long long)__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector bool long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs(__b, (vector signed long long)__a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector unsigned long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs(__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector unsigned long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__b, __a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector bool long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs(__b, (vector unsigned long long)__a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector bool long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__b, + (vector unsigned long long)__a, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_ge(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchedbs(__a, __b, &__cc); + return __cc == 0; +} + +/*-- vec_all_gt -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai int +vec_all_gt(vector signed char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs(__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector signed char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchbs(__a, (vector signed char)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector bool char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs((vector signed char)__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector unsigned char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs(__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector unsigned char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs(__a, (vector unsigned char)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector bool char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector bool char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__a, + (vector unsigned char)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector signed short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs(__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector signed short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchhs(__a, (vector signed short)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector bool short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs((vector signed short)__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector unsigned short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs(__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector unsigned short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs(__a, (vector unsigned short)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector bool short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector bool short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__a, + (vector unsigned short)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector signed int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs(__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector signed int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchfs(__a, (vector signed int)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector bool int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs((vector signed int)__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector unsigned int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs(__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector unsigned int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs(__a, (vector unsigned int)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector bool int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector bool int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__a, + (vector unsigned int)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector signed long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs(__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector signed long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchgs(__a, (vector signed long long)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector bool long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs((vector signed long long)__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector unsigned long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs(__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector unsigned long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs(__a, (vector unsigned long long)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector bool long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__a, __b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector bool long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__a, + (vector unsigned long long)__b, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_gt(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchdbs(__a, __b, &__cc); + return __cc == 0; +} + +/*-- vec_all_le -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai int +vec_all_le(vector signed char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs(__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector signed char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchbs(__a, (vector signed char)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector bool char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs((vector signed char)__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector unsigned char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs(__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector unsigned char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs(__a, (vector unsigned char)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector bool char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector bool char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__a, + (vector unsigned char)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector signed short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs(__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector signed short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchhs(__a, (vector signed short)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector bool short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs((vector signed short)__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector unsigned short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs(__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector unsigned short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs(__a, (vector unsigned short)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector bool short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector bool short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__a, + (vector unsigned short)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector signed int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs(__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector signed int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchfs(__a, (vector signed int)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector bool int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs((vector signed int)__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector unsigned int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs(__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector unsigned int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs(__a, (vector unsigned int)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector bool int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector bool int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__a, + (vector unsigned int)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector signed long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs(__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector signed long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchgs(__a, (vector signed long long)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector bool long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs((vector signed long long)__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector unsigned long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs(__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector unsigned long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs(__a, (vector unsigned long long)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector bool long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__a, __b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector bool long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__a, + (vector unsigned long long)__b, &__cc); + return __cc == 3; +} + +static inline __ATTRS_o_ai int +vec_all_le(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchedbs(__b, __a, &__cc); + return __cc == 0; +} + +/*-- vec_all_lt -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai int +vec_all_lt(vector signed char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs(__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector signed char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchbs((vector signed char)__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector bool char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs(__b, (vector signed char)__a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector unsigned char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs(__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector unsigned char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector bool char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs(__b, (vector unsigned char)__a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector bool char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__b, + (vector unsigned char)__a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector signed short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs(__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector signed short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchhs((vector signed short)__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector bool short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs(__b, (vector signed short)__a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector unsigned short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs(__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector unsigned short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector bool short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs(__b, (vector unsigned short)__a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector bool short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__b, + (vector unsigned short)__a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector signed int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs(__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector signed int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchfs((vector signed int)__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector bool int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs(__b, (vector signed int)__a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector unsigned int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs(__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector unsigned int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector bool int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs(__b, (vector unsigned int)__a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector bool int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__b, + (vector unsigned int)__a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector signed long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs(__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector signed long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchgs((vector signed long long)__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector bool long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs(__b, (vector signed long long)__a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector unsigned long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs(__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector unsigned long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__b, __a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector bool long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs(__b, (vector unsigned long long)__a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector bool long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__b, + (vector unsigned long long)__a, &__cc); + return __cc == 0; +} + +static inline __ATTRS_o_ai int +vec_all_lt(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchdbs(__b, __a, &__cc); + return __cc == 0; +} + +/*-- vec_all_nge ------------------------------------------------------------*/ + +static inline __ATTRS_ai int +vec_all_nge(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchedbs(__a, __b, &__cc); + return __cc == 3; +} + +/*-- vec_all_ngt ------------------------------------------------------------*/ + +static inline __ATTRS_ai int +vec_all_ngt(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchdbs(__a, __b, &__cc); + return __cc == 3; +} + +/*-- vec_all_nle ------------------------------------------------------------*/ + +static inline __ATTRS_ai int +vec_all_nle(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchedbs(__b, __a, &__cc); + return __cc == 3; +} + +/*-- vec_all_nlt ------------------------------------------------------------*/ + +static inline __ATTRS_ai int +vec_all_nlt(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchdbs(__b, __a, &__cc); + return __cc == 3; +} + +/*-- vec_all_nan ------------------------------------------------------------*/ + +static inline __ATTRS_ai int +vec_all_nan(vector double __a) { + int __cc; + __builtin_s390_vftcidb(__a, 15, &__cc); + return __cc == 0; +} + +/*-- vec_all_numeric --------------------------------------------------------*/ + +static inline __ATTRS_ai int +vec_all_numeric(vector double __a) { + int __cc; + __builtin_s390_vftcidb(__a, 15, &__cc); + return __cc == 3; +} + +/*-- vec_any_eq -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai int +vec_any_eq(vector signed char __a, vector signed char __b) { + int __cc; + __builtin_s390_vceqbs(__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector signed char __a, vector bool char __b) { + int __cc; + __builtin_s390_vceqbs(__a, (vector signed char)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector bool char __a, vector signed char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector unsigned char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector unsigned char __a, vector bool char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector bool char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector bool char __a, vector bool char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector signed short __a, vector signed short __b) { + int __cc; + __builtin_s390_vceqhs(__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector signed short __a, vector bool short __b) { + int __cc; + __builtin_s390_vceqhs(__a, (vector signed short)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector bool short __a, vector signed short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector unsigned short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector unsigned short __a, vector bool short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector bool short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector bool short __a, vector bool short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector signed int __a, vector signed int __b) { + int __cc; + __builtin_s390_vceqfs(__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector signed int __a, vector bool int __b) { + int __cc; + __builtin_s390_vceqfs(__a, (vector signed int)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector bool int __a, vector signed int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector unsigned int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector unsigned int __a, vector bool int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector bool int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector bool int __a, vector bool int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector signed long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vceqgs(__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector signed long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vceqgs(__a, (vector signed long long)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector bool long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector unsigned long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector unsigned long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector bool long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector bool long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_eq(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfcedbs(__a, __b, &__cc); + return __cc <= 1; +} + +/*-- vec_any_ne -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai int +vec_any_ne(vector signed char __a, vector signed char __b) { + int __cc; + __builtin_s390_vceqbs(__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector signed char __a, vector bool char __b) { + int __cc; + __builtin_s390_vceqbs(__a, (vector signed char)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector bool char __a, vector signed char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector unsigned char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector unsigned char __a, vector bool char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector bool char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector bool char __a, vector bool char __b) { + int __cc; + __builtin_s390_vceqbs((vector signed char)__a, + (vector signed char)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector signed short __a, vector signed short __b) { + int __cc; + __builtin_s390_vceqhs(__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector signed short __a, vector bool short __b) { + int __cc; + __builtin_s390_vceqhs(__a, (vector signed short)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector bool short __a, vector signed short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector unsigned short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector unsigned short __a, vector bool short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector bool short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector bool short __a, vector bool short __b) { + int __cc; + __builtin_s390_vceqhs((vector signed short)__a, + (vector signed short)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector signed int __a, vector signed int __b) { + int __cc; + __builtin_s390_vceqfs(__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector signed int __a, vector bool int __b) { + int __cc; + __builtin_s390_vceqfs(__a, (vector signed int)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector bool int __a, vector signed int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector unsigned int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector unsigned int __a, vector bool int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector bool int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector bool int __a, vector bool int __b) { + int __cc; + __builtin_s390_vceqfs((vector signed int)__a, + (vector signed int)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector signed long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vceqgs(__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector signed long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vceqgs(__a, (vector signed long long)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector bool long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector unsigned long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector unsigned long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector bool long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector bool long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vceqgs((vector signed long long)__a, + (vector signed long long)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ne(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfcedbs(__a, __b, &__cc); + return __cc != 0; +} + +/*-- vec_any_ge -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai int +vec_any_ge(vector signed char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs(__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector signed char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchbs((vector signed char)__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector bool char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs(__b, (vector signed char)__a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector unsigned char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs(__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector unsigned char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector bool char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs(__b, (vector unsigned char)__a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector bool char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__b, + (vector unsigned char)__a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector signed short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs(__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector signed short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchhs((vector signed short)__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector bool short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs(__b, (vector signed short)__a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector unsigned short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs(__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector unsigned short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector bool short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs(__b, (vector unsigned short)__a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector bool short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__b, + (vector unsigned short)__a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector signed int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs(__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector signed int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchfs((vector signed int)__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector bool int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs(__b, (vector signed int)__a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector unsigned int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs(__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector unsigned int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector bool int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs(__b, (vector unsigned int)__a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector bool int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__b, + (vector unsigned int)__a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector signed long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs(__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector signed long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchgs((vector signed long long)__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector bool long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs(__b, (vector signed long long)__a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector unsigned long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs(__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector unsigned long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__b, __a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector bool long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs(__b, (vector unsigned long long)__a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector bool long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__b, + (vector unsigned long long)__a, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_ge(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchedbs(__a, __b, &__cc); + return __cc <= 1; +} + +/*-- vec_any_gt -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai int +vec_any_gt(vector signed char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs(__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector signed char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchbs(__a, (vector signed char)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector bool char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs((vector signed char)__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector unsigned char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs(__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector unsigned char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs(__a, (vector unsigned char)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector bool char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector bool char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__a, + (vector unsigned char)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector signed short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs(__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector signed short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchhs(__a, (vector signed short)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector bool short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs((vector signed short)__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector unsigned short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs(__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector unsigned short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs(__a, (vector unsigned short)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector bool short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector bool short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__a, + (vector unsigned short)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector signed int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs(__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector signed int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchfs(__a, (vector signed int)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector bool int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs((vector signed int)__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector unsigned int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs(__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector unsigned int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs(__a, (vector unsigned int)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector bool int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector bool int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__a, + (vector unsigned int)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector signed long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs(__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector signed long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchgs(__a, (vector signed long long)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector bool long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs((vector signed long long)__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector unsigned long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs(__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector unsigned long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs(__a, (vector unsigned long long)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector bool long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__a, __b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector bool long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__a, + (vector unsigned long long)__b, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_gt(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchdbs(__a, __b, &__cc); + return __cc <= 1; +} + +/*-- vec_any_le -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai int +vec_any_le(vector signed char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs(__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector signed char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchbs(__a, (vector signed char)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector bool char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs((vector signed char)__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector unsigned char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs(__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector unsigned char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs(__a, (vector unsigned char)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector bool char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector bool char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__a, + (vector unsigned char)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector signed short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs(__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector signed short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchhs(__a, (vector signed short)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector bool short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs((vector signed short)__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector unsigned short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs(__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector unsigned short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs(__a, (vector unsigned short)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector bool short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector bool short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__a, + (vector unsigned short)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector signed int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs(__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector signed int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchfs(__a, (vector signed int)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector bool int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs((vector signed int)__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector unsigned int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs(__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector unsigned int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs(__a, (vector unsigned int)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector bool int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector bool int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__a, + (vector unsigned int)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector signed long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs(__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector signed long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchgs(__a, (vector signed long long)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector bool long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs((vector signed long long)__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector unsigned long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs(__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector unsigned long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs(__a, (vector unsigned long long)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector bool long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__a, __b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector bool long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__a, + (vector unsigned long long)__b, &__cc); + return __cc != 0; +} + +static inline __ATTRS_o_ai int +vec_any_le(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchedbs(__b, __a, &__cc); + return __cc <= 1; +} + +/*-- vec_any_lt -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai int +vec_any_lt(vector signed char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs(__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector signed char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchbs((vector signed char)__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector bool char __a, vector signed char __b) { + int __cc; + __builtin_s390_vchbs(__b, (vector signed char)__a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector unsigned char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs(__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector unsigned char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector bool char __a, vector unsigned char __b) { + int __cc; + __builtin_s390_vchlbs(__b, (vector unsigned char)__a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector bool char __a, vector bool char __b) { + int __cc; + __builtin_s390_vchlbs((vector unsigned char)__b, + (vector unsigned char)__a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector signed short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs(__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector signed short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchhs((vector signed short)__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector bool short __a, vector signed short __b) { + int __cc; + __builtin_s390_vchhs(__b, (vector signed short)__a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector unsigned short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs(__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector unsigned short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector bool short __a, vector unsigned short __b) { + int __cc; + __builtin_s390_vchlhs(__b, (vector unsigned short)__a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector bool short __a, vector bool short __b) { + int __cc; + __builtin_s390_vchlhs((vector unsigned short)__b, + (vector unsigned short)__a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector signed int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs(__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector signed int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchfs((vector signed int)__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector bool int __a, vector signed int __b) { + int __cc; + __builtin_s390_vchfs(__b, (vector signed int)__a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector unsigned int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs(__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector unsigned int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector bool int __a, vector unsigned int __b) { + int __cc; + __builtin_s390_vchlfs(__b, (vector unsigned int)__a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector bool int __a, vector bool int __b) { + int __cc; + __builtin_s390_vchlfs((vector unsigned int)__b, + (vector unsigned int)__a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector signed long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs(__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector signed long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchgs((vector signed long long)__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector bool long long __a, vector signed long long __b) { + int __cc; + __builtin_s390_vchgs(__b, (vector signed long long)__a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector unsigned long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs(__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector unsigned long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__b, __a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector bool long long __a, vector unsigned long long __b) { + int __cc; + __builtin_s390_vchlgs(__b, (vector unsigned long long)__a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector bool long long __a, vector bool long long __b) { + int __cc; + __builtin_s390_vchlgs((vector unsigned long long)__b, + (vector unsigned long long)__a, &__cc); + return __cc <= 1; +} + +static inline __ATTRS_o_ai int +vec_any_lt(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchdbs(__b, __a, &__cc); + return __cc <= 1; +} + +/*-- vec_any_nge ------------------------------------------------------------*/ + +static inline __ATTRS_ai int +vec_any_nge(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchedbs(__a, __b, &__cc); + return __cc != 0; +} + +/*-- vec_any_ngt ------------------------------------------------------------*/ + +static inline __ATTRS_ai int +vec_any_ngt(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchdbs(__a, __b, &__cc); + return __cc != 0; +} + +/*-- vec_any_nle ------------------------------------------------------------*/ + +static inline __ATTRS_ai int +vec_any_nle(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchedbs(__b, __a, &__cc); + return __cc != 0; +} + +/*-- vec_any_nlt ------------------------------------------------------------*/ + +static inline __ATTRS_ai int +vec_any_nlt(vector double __a, vector double __b) { + int __cc; + __builtin_s390_vfchdbs(__b, __a, &__cc); + return __cc != 0; +} + +/*-- vec_any_nan ------------------------------------------------------------*/ + +static inline __ATTRS_ai int +vec_any_nan(vector double __a) { + int __cc; + __builtin_s390_vftcidb(__a, 15, &__cc); + return __cc != 3; +} + +/*-- vec_any_numeric --------------------------------------------------------*/ + +static inline __ATTRS_ai int +vec_any_numeric(vector double __a) { + int __cc; + __builtin_s390_vftcidb(__a, 15, &__cc); + return __cc != 0; +} + +/*-- vec_andc ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_andc(vector bool char __a, vector bool char __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector signed char +vec_andc(vector signed char __a, vector signed char __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector signed char +vec_andc(vector bool char __a, vector signed char __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector signed char +vec_andc(vector signed char __a, vector bool char __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector unsigned char +vec_andc(vector unsigned char __a, vector unsigned char __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector unsigned char +vec_andc(vector bool char __a, vector unsigned char __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector unsigned char +vec_andc(vector unsigned char __a, vector bool char __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector bool short +vec_andc(vector bool short __a, vector bool short __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector signed short +vec_andc(vector signed short __a, vector signed short __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector signed short +vec_andc(vector bool short __a, vector signed short __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector signed short +vec_andc(vector signed short __a, vector bool short __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector unsigned short +vec_andc(vector unsigned short __a, vector unsigned short __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector unsigned short +vec_andc(vector bool short __a, vector unsigned short __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector unsigned short +vec_andc(vector unsigned short __a, vector bool short __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector bool int +vec_andc(vector bool int __a, vector bool int __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector signed int +vec_andc(vector signed int __a, vector signed int __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector signed int +vec_andc(vector bool int __a, vector signed int __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector signed int +vec_andc(vector signed int __a, vector bool int __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector unsigned int +vec_andc(vector unsigned int __a, vector unsigned int __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector unsigned int +vec_andc(vector bool int __a, vector unsigned int __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector unsigned int +vec_andc(vector unsigned int __a, vector bool int __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector bool long long +vec_andc(vector bool long long __a, vector bool long long __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector signed long long +vec_andc(vector signed long long __a, vector signed long long __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector signed long long +vec_andc(vector bool long long __a, vector signed long long __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector signed long long +vec_andc(vector signed long long __a, vector bool long long __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_andc(vector unsigned long long __a, vector unsigned long long __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_andc(vector bool long long __a, vector unsigned long long __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_andc(vector unsigned long long __a, vector bool long long __b) { + return __a & ~__b; +} + +static inline __ATTRS_o_ai vector double +vec_andc(vector double __a, vector double __b) { + return (vector double)((vector unsigned long long)__a & + ~(vector unsigned long long)__b); +} + +static inline __ATTRS_o_ai vector double +vec_andc(vector bool long long __a, vector double __b) { + return (vector double)((vector unsigned long long)__a & + ~(vector unsigned long long)__b); +} + +static inline __ATTRS_o_ai vector double +vec_andc(vector double __a, vector bool long long __b) { + return (vector double)((vector unsigned long long)__a & + ~(vector unsigned long long)__b); +} + +/*-- vec_nor ----------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_nor(vector bool char __a, vector bool char __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector signed char +vec_nor(vector signed char __a, vector signed char __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector signed char +vec_nor(vector bool char __a, vector signed char __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector signed char +vec_nor(vector signed char __a, vector bool char __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_nor(vector unsigned char __a, vector unsigned char __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_nor(vector bool char __a, vector unsigned char __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_nor(vector unsigned char __a, vector bool char __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_nor(vector bool short __a, vector bool short __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_nor(vector signed short __a, vector signed short __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_nor(vector bool short __a, vector signed short __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_nor(vector signed short __a, vector bool short __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_nor(vector unsigned short __a, vector unsigned short __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_nor(vector bool short __a, vector unsigned short __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_nor(vector unsigned short __a, vector bool short __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_nor(vector bool int __a, vector bool int __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_nor(vector signed int __a, vector signed int __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_nor(vector bool int __a, vector signed int __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_nor(vector signed int __a, vector bool int __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_nor(vector unsigned int __a, vector unsigned int __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_nor(vector bool int __a, vector unsigned int __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_nor(vector unsigned int __a, vector bool int __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_nor(vector bool long long __a, vector bool long long __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_nor(vector signed long long __a, vector signed long long __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_nor(vector bool long long __a, vector signed long long __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_nor(vector signed long long __a, vector bool long long __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_nor(vector unsigned long long __a, vector unsigned long long __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_nor(vector bool long long __a, vector unsigned long long __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_nor(vector unsigned long long __a, vector bool long long __b) { + return ~(__a | __b); +} + +static inline __ATTRS_o_ai vector double +vec_nor(vector double __a, vector double __b) { + return (vector double)~((vector unsigned long long)__a | + (vector unsigned long long)__b); +} + +static inline __ATTRS_o_ai vector double +vec_nor(vector bool long long __a, vector double __b) { + return (vector double)~((vector unsigned long long)__a | + (vector unsigned long long)__b); +} + +static inline __ATTRS_o_ai vector double +vec_nor(vector double __a, vector bool long long __b) { + return (vector double)~((vector unsigned long long)__a | + (vector unsigned long long)__b); +} + +/*-- vec_cntlz --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_cntlz(vector signed char __a) { + return __builtin_s390_vclzb((vector unsigned char)__a); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cntlz(vector unsigned char __a) { + return __builtin_s390_vclzb(__a); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cntlz(vector signed short __a) { + return __builtin_s390_vclzh((vector unsigned short)__a); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cntlz(vector unsigned short __a) { + return __builtin_s390_vclzh(__a); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cntlz(vector signed int __a) { + return __builtin_s390_vclzf((vector unsigned int)__a); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cntlz(vector unsigned int __a) { + return __builtin_s390_vclzf(__a); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_cntlz(vector signed long long __a) { + return __builtin_s390_vclzg((vector unsigned long long)__a); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_cntlz(vector unsigned long long __a) { + return __builtin_s390_vclzg(__a); +} + +/*-- vec_cnttz --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_cnttz(vector signed char __a) { + return __builtin_s390_vctzb((vector unsigned char)__a); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cnttz(vector unsigned char __a) { + return __builtin_s390_vctzb(__a); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cnttz(vector signed short __a) { + return __builtin_s390_vctzh((vector unsigned short)__a); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cnttz(vector unsigned short __a) { + return __builtin_s390_vctzh(__a); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cnttz(vector signed int __a) { + return __builtin_s390_vctzf((vector unsigned int)__a); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cnttz(vector unsigned int __a) { + return __builtin_s390_vctzf(__a); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_cnttz(vector signed long long __a) { + return __builtin_s390_vctzg((vector unsigned long long)__a); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_cnttz(vector unsigned long long __a) { + return __builtin_s390_vctzg(__a); +} + +/*-- vec_popcnt -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_popcnt(vector signed char __a) { + return __builtin_s390_vpopctb((vector unsigned char)__a); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_popcnt(vector unsigned char __a) { + return __builtin_s390_vpopctb(__a); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_popcnt(vector signed short __a) { + return __builtin_s390_vpopcth((vector unsigned short)__a); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_popcnt(vector unsigned short __a) { + return __builtin_s390_vpopcth(__a); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_popcnt(vector signed int __a) { + return __builtin_s390_vpopctf((vector unsigned int)__a); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_popcnt(vector unsigned int __a) { + return __builtin_s390_vpopctf(__a); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_popcnt(vector signed long long __a) { + return __builtin_s390_vpopctg((vector unsigned long long)__a); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_popcnt(vector unsigned long long __a) { + return __builtin_s390_vpopctg(__a); +} + +/*-- vec_rl -----------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_rl(vector signed char __a, vector unsigned char __b) { + return (vector signed char)__builtin_s390_verllvb( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_rl(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_verllvb(__a, __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_rl(vector signed short __a, vector unsigned short __b) { + return (vector signed short)__builtin_s390_verllvh( + (vector unsigned short)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_rl(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_verllvh(__a, __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_rl(vector signed int __a, vector unsigned int __b) { + return (vector signed int)__builtin_s390_verllvf( + (vector unsigned int)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_rl(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_verllvf(__a, __b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_rl(vector signed long long __a, vector unsigned long long __b) { + return (vector signed long long)__builtin_s390_verllvg( + (vector unsigned long long)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_rl(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_s390_verllvg(__a, __b); +} + +/*-- vec_rli ----------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_rli(vector signed char __a, unsigned long __b) { + return (vector signed char)__builtin_s390_verllb( + (vector unsigned char)__a, (int)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_rli(vector unsigned char __a, unsigned long __b) { + return __builtin_s390_verllb(__a, (int)__b); +} + +static inline __ATTRS_o_ai vector signed short +vec_rli(vector signed short __a, unsigned long __b) { + return (vector signed short)__builtin_s390_verllh( + (vector unsigned short)__a, (int)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_rli(vector unsigned short __a, unsigned long __b) { + return __builtin_s390_verllh(__a, (int)__b); +} + +static inline __ATTRS_o_ai vector signed int +vec_rli(vector signed int __a, unsigned long __b) { + return (vector signed int)__builtin_s390_verllf( + (vector unsigned int)__a, (int)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_rli(vector unsigned int __a, unsigned long __b) { + return __builtin_s390_verllf(__a, (int)__b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_rli(vector signed long long __a, unsigned long __b) { + return (vector signed long long)__builtin_s390_verllg( + (vector unsigned long long)__a, (int)__b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_rli(vector unsigned long long __a, unsigned long __b) { + return __builtin_s390_verllg(__a, (int)__b); +} + +/*-- vec_rl_mask ------------------------------------------------------------*/ + +extern __ATTRS_o vector signed char +vec_rl_mask(vector signed char __a, vector unsigned char __b, + unsigned char __c) __constant(__c); + +extern __ATTRS_o vector unsigned char +vec_rl_mask(vector unsigned char __a, vector unsigned char __b, + unsigned char __c) __constant(__c); + +extern __ATTRS_o vector signed short +vec_rl_mask(vector signed short __a, vector unsigned short __b, + unsigned char __c) __constant(__c); + +extern __ATTRS_o vector unsigned short +vec_rl_mask(vector unsigned short __a, vector unsigned short __b, + unsigned char __c) __constant(__c); + +extern __ATTRS_o vector signed int +vec_rl_mask(vector signed int __a, vector unsigned int __b, + unsigned char __c) __constant(__c); + +extern __ATTRS_o vector unsigned int +vec_rl_mask(vector unsigned int __a, vector unsigned int __b, + unsigned char __c) __constant(__c); + +extern __ATTRS_o vector signed long long +vec_rl_mask(vector signed long long __a, vector unsigned long long __b, + unsigned char __c) __constant(__c); + +extern __ATTRS_o vector unsigned long long +vec_rl_mask(vector unsigned long long __a, vector unsigned long long __b, + unsigned char __c) __constant(__c); + +#define vec_rl_mask(X, Y, Z) ((__typeof__((vec_rl_mask)((X), (Y), (Z)))) \ + __extension__ ({ \ + vector unsigned char __res; \ + vector unsigned char __x = (vector unsigned char)(X); \ + vector unsigned char __y = (vector unsigned char)(Y); \ + switch (sizeof ((X)[0])) { \ + case 1: __res = (vector unsigned char) __builtin_s390_verimb( \ + (vector unsigned char)__x, (vector unsigned char)__x, \ + (vector unsigned char)__y, (Z)); break; \ + case 2: __res = (vector unsigned char) __builtin_s390_verimh( \ + (vector unsigned short)__x, (vector unsigned short)__x, \ + (vector unsigned short)__y, (Z)); break; \ + case 4: __res = (vector unsigned char) __builtin_s390_verimf( \ + (vector unsigned int)__x, (vector unsigned int)__x, \ + (vector unsigned int)__y, (Z)); break; \ + default: __res = (vector unsigned char) __builtin_s390_verimg( \ + (vector unsigned long long)__x, (vector unsigned long long)__x, \ + (vector unsigned long long)__y, (Z)); break; \ + } __res; })) + +/*-- vec_sll ----------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_sll(vector signed char __a, vector unsigned char __b) { + return (vector signed char)__builtin_s390_vsl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector signed char +vec_sll(vector signed char __a, vector unsigned short __b) { + return (vector signed char)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed char +vec_sll(vector signed char __a, vector unsigned int __b) { + return (vector signed char)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool char +vec_sll(vector bool char __a, vector unsigned char __b) { + return (vector bool char)__builtin_s390_vsl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector bool char +vec_sll(vector bool char __a, vector unsigned short __b) { + return (vector bool char)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool char +vec_sll(vector bool char __a, vector unsigned int __b) { + return (vector bool char)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_sll(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vsl(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_sll(vector unsigned char __a, vector unsigned short __b) { + return __builtin_s390_vsl(__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_sll(vector unsigned char __a, vector unsigned int __b) { + return __builtin_s390_vsl(__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed short +vec_sll(vector signed short __a, vector unsigned char __b) { + return (vector signed short)__builtin_s390_vsl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_sll(vector signed short __a, vector unsigned short __b) { + return (vector signed short)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed short +vec_sll(vector signed short __a, vector unsigned int __b) { + return (vector signed short)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool short +vec_sll(vector bool short __a, vector unsigned char __b) { + return (vector bool short)__builtin_s390_vsl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_sll(vector bool short __a, vector unsigned short __b) { + return (vector bool short)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool short +vec_sll(vector bool short __a, vector unsigned int __b) { + return (vector bool short)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_sll(vector unsigned short __a, vector unsigned char __b) { + return (vector unsigned short)__builtin_s390_vsl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_sll(vector unsigned short __a, vector unsigned short __b) { + return (vector unsigned short)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_sll(vector unsigned short __a, vector unsigned int __b) { + return (vector unsigned short)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed int +vec_sll(vector signed int __a, vector unsigned char __b) { + return (vector signed int)__builtin_s390_vsl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_sll(vector signed int __a, vector unsigned short __b) { + return (vector signed int)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed int +vec_sll(vector signed int __a, vector unsigned int __b) { + return (vector signed int)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool int +vec_sll(vector bool int __a, vector unsigned char __b) { + return (vector bool int)__builtin_s390_vsl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_sll(vector bool int __a, vector unsigned short __b) { + return (vector bool int)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool int +vec_sll(vector bool int __a, vector unsigned int __b) { + return (vector bool int)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_sll(vector unsigned int __a, vector unsigned char __b) { + return (vector unsigned int)__builtin_s390_vsl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_sll(vector unsigned int __a, vector unsigned short __b) { + return (vector unsigned int)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_sll(vector unsigned int __a, vector unsigned int __b) { + return (vector unsigned int)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_sll(vector signed long long __a, vector unsigned char __b) { + return (vector signed long long)__builtin_s390_vsl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_sll(vector signed long long __a, vector unsigned short __b) { + return (vector signed long long)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_sll(vector signed long long __a, vector unsigned int __b) { + return (vector signed long long)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_sll(vector bool long long __a, vector unsigned char __b) { + return (vector bool long long)__builtin_s390_vsl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_sll(vector bool long long __a, vector unsigned short __b) { + return (vector bool long long)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_sll(vector bool long long __a, vector unsigned int __b) { + return (vector bool long long)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_sll(vector unsigned long long __a, vector unsigned char __b) { + return (vector unsigned long long)__builtin_s390_vsl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_sll(vector unsigned long long __a, vector unsigned short __b) { + return (vector unsigned long long)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_sll(vector unsigned long long __a, vector unsigned int __b) { + return (vector unsigned long long)__builtin_s390_vsl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +/*-- vec_slb ----------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_slb(vector signed char __a, vector signed char __b) { + return (vector signed char)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed char +vec_slb(vector signed char __a, vector unsigned char __b) { + return (vector signed char)__builtin_s390_vslb( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_slb(vector unsigned char __a, vector signed char __b) { + return __builtin_s390_vslb(__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_slb(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vslb(__a, __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_slb(vector signed short __a, vector signed short __b) { + return (vector signed short)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed short +vec_slb(vector signed short __a, vector unsigned short __b) { + return (vector signed short)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_slb(vector unsigned short __a, vector signed short __b) { + return (vector unsigned short)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_slb(vector unsigned short __a, vector unsigned short __b) { + return (vector unsigned short)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed int +vec_slb(vector signed int __a, vector signed int __b) { + return (vector signed int)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed int +vec_slb(vector signed int __a, vector unsigned int __b) { + return (vector signed int)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_slb(vector unsigned int __a, vector signed int __b) { + return (vector unsigned int)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_slb(vector unsigned int __a, vector unsigned int __b) { + return (vector unsigned int)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_slb(vector signed long long __a, vector signed long long __b) { + return (vector signed long long)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_slb(vector signed long long __a, vector unsigned long long __b) { + return (vector signed long long)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_slb(vector unsigned long long __a, vector signed long long __b) { + return (vector unsigned long long)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_slb(vector unsigned long long __a, vector unsigned long long __b) { + return (vector unsigned long long)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector double +vec_slb(vector double __a, vector signed long long __b) { + return (vector double)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector double +vec_slb(vector double __a, vector unsigned long long __b) { + return (vector double)__builtin_s390_vslb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +/*-- vec_sld ----------------------------------------------------------------*/ + +extern __ATTRS_o vector signed char +vec_sld(vector signed char __a, vector signed char __b, int __c) + __constant_range(__c, 0, 15); + +extern __ATTRS_o vector unsigned char +vec_sld(vector unsigned char __a, vector unsigned char __b, int __c) + __constant_range(__c, 0, 15); + +extern __ATTRS_o vector signed short +vec_sld(vector signed short __a, vector signed short __b, int __c) + __constant_range(__c, 0, 15); + +extern __ATTRS_o vector unsigned short +vec_sld(vector unsigned short __a, vector unsigned short __b, int __c) + __constant_range(__c, 0, 15); + +extern __ATTRS_o vector signed int +vec_sld(vector signed int __a, vector signed int __b, int __c) + __constant_range(__c, 0, 15); + +extern __ATTRS_o vector unsigned int +vec_sld(vector unsigned int __a, vector unsigned int __b, int __c) + __constant_range(__c, 0, 15); + +extern __ATTRS_o vector signed long long +vec_sld(vector signed long long __a, vector signed long long __b, int __c) + __constant_range(__c, 0, 15); + +extern __ATTRS_o vector unsigned long long +vec_sld(vector unsigned long long __a, vector unsigned long long __b, int __c) + __constant_range(__c, 0, 15); + +extern __ATTRS_o vector double +vec_sld(vector double __a, vector double __b, int __c) + __constant_range(__c, 0, 15); + +#define vec_sld(X, Y, Z) ((__typeof__((vec_sld)((X), (Y), (Z)))) \ + __builtin_s390_vsldb((vector unsigned char)(X), \ + (vector unsigned char)(Y), (Z))) + +/*-- vec_sldw ---------------------------------------------------------------*/ + +extern __ATTRS_o vector signed char +vec_sldw(vector signed char __a, vector signed char __b, int __c) + __constant_range(__c, 0, 3); + +extern __ATTRS_o vector unsigned char +vec_sldw(vector unsigned char __a, vector unsigned char __b, int __c) + __constant_range(__c, 0, 3); + +extern __ATTRS_o vector signed short +vec_sldw(vector signed short __a, vector signed short __b, int __c) + __constant_range(__c, 0, 3); + +extern __ATTRS_o vector unsigned short +vec_sldw(vector unsigned short __a, vector unsigned short __b, int __c) + __constant_range(__c, 0, 3); + +extern __ATTRS_o vector signed int +vec_sldw(vector signed int __a, vector signed int __b, int __c) + __constant_range(__c, 0, 3); + +extern __ATTRS_o vector unsigned int +vec_sldw(vector unsigned int __a, vector unsigned int __b, int __c) + __constant_range(__c, 0, 3); + +extern __ATTRS_o vector signed long long +vec_sldw(vector signed long long __a, vector signed long long __b, int __c) + __constant_range(__c, 0, 3); + +extern __ATTRS_o vector unsigned long long +vec_sldw(vector unsigned long long __a, vector unsigned long long __b, int __c) + __constant_range(__c, 0, 3); + +extern __ATTRS_o vector double +vec_sldw(vector double __a, vector double __b, int __c) + __constant_range(__c, 0, 3); + +#define vec_sldw(X, Y, Z) ((__typeof__((vec_sldw)((X), (Y), (Z)))) \ + __builtin_s390_vsldb((vector unsigned char)(X), \ + (vector unsigned char)(Y), (Z) * 4)) + +/*-- vec_sral ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_sral(vector signed char __a, vector unsigned char __b) { + return (vector signed char)__builtin_s390_vsra( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector signed char +vec_sral(vector signed char __a, vector unsigned short __b) { + return (vector signed char)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed char +vec_sral(vector signed char __a, vector unsigned int __b) { + return (vector signed char)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool char +vec_sral(vector bool char __a, vector unsigned char __b) { + return (vector bool char)__builtin_s390_vsra( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector bool char +vec_sral(vector bool char __a, vector unsigned short __b) { + return (vector bool char)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool char +vec_sral(vector bool char __a, vector unsigned int __b) { + return (vector bool char)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_sral(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vsra(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_sral(vector unsigned char __a, vector unsigned short __b) { + return __builtin_s390_vsra(__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_sral(vector unsigned char __a, vector unsigned int __b) { + return __builtin_s390_vsra(__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed short +vec_sral(vector signed short __a, vector unsigned char __b) { + return (vector signed short)__builtin_s390_vsra( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_sral(vector signed short __a, vector unsigned short __b) { + return (vector signed short)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed short +vec_sral(vector signed short __a, vector unsigned int __b) { + return (vector signed short)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool short +vec_sral(vector bool short __a, vector unsigned char __b) { + return (vector bool short)__builtin_s390_vsra( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_sral(vector bool short __a, vector unsigned short __b) { + return (vector bool short)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool short +vec_sral(vector bool short __a, vector unsigned int __b) { + return (vector bool short)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_sral(vector unsigned short __a, vector unsigned char __b) { + return (vector unsigned short)__builtin_s390_vsra( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_sral(vector unsigned short __a, vector unsigned short __b) { + return (vector unsigned short)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_sral(vector unsigned short __a, vector unsigned int __b) { + return (vector unsigned short)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed int +vec_sral(vector signed int __a, vector unsigned char __b) { + return (vector signed int)__builtin_s390_vsra( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_sral(vector signed int __a, vector unsigned short __b) { + return (vector signed int)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed int +vec_sral(vector signed int __a, vector unsigned int __b) { + return (vector signed int)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool int +vec_sral(vector bool int __a, vector unsigned char __b) { + return (vector bool int)__builtin_s390_vsra( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_sral(vector bool int __a, vector unsigned short __b) { + return (vector bool int)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool int +vec_sral(vector bool int __a, vector unsigned int __b) { + return (vector bool int)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_sral(vector unsigned int __a, vector unsigned char __b) { + return (vector unsigned int)__builtin_s390_vsra( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_sral(vector unsigned int __a, vector unsigned short __b) { + return (vector unsigned int)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_sral(vector unsigned int __a, vector unsigned int __b) { + return (vector unsigned int)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_sral(vector signed long long __a, vector unsigned char __b) { + return (vector signed long long)__builtin_s390_vsra( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_sral(vector signed long long __a, vector unsigned short __b) { + return (vector signed long long)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_sral(vector signed long long __a, vector unsigned int __b) { + return (vector signed long long)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_sral(vector bool long long __a, vector unsigned char __b) { + return (vector bool long long)__builtin_s390_vsra( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_sral(vector bool long long __a, vector unsigned short __b) { + return (vector bool long long)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_sral(vector bool long long __a, vector unsigned int __b) { + return (vector bool long long)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_sral(vector unsigned long long __a, vector unsigned char __b) { + return (vector unsigned long long)__builtin_s390_vsra( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_sral(vector unsigned long long __a, vector unsigned short __b) { + return (vector unsigned long long)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_sral(vector unsigned long long __a, vector unsigned int __b) { + return (vector unsigned long long)__builtin_s390_vsra( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +/*-- vec_srab ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_srab(vector signed char __a, vector signed char __b) { + return (vector signed char)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed char +vec_srab(vector signed char __a, vector unsigned char __b) { + return (vector signed char)__builtin_s390_vsrab( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_srab(vector unsigned char __a, vector signed char __b) { + return __builtin_s390_vsrab(__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_srab(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vsrab(__a, __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_srab(vector signed short __a, vector signed short __b) { + return (vector signed short)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed short +vec_srab(vector signed short __a, vector unsigned short __b) { + return (vector signed short)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_srab(vector unsigned short __a, vector signed short __b) { + return (vector unsigned short)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_srab(vector unsigned short __a, vector unsigned short __b) { + return (vector unsigned short)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed int +vec_srab(vector signed int __a, vector signed int __b) { + return (vector signed int)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed int +vec_srab(vector signed int __a, vector unsigned int __b) { + return (vector signed int)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_srab(vector unsigned int __a, vector signed int __b) { + return (vector unsigned int)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_srab(vector unsigned int __a, vector unsigned int __b) { + return (vector unsigned int)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_srab(vector signed long long __a, vector signed long long __b) { + return (vector signed long long)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_srab(vector signed long long __a, vector unsigned long long __b) { + return (vector signed long long)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_srab(vector unsigned long long __a, vector signed long long __b) { + return (vector unsigned long long)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_srab(vector unsigned long long __a, vector unsigned long long __b) { + return (vector unsigned long long)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector double +vec_srab(vector double __a, vector signed long long __b) { + return (vector double)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector double +vec_srab(vector double __a, vector unsigned long long __b) { + return (vector double)__builtin_s390_vsrab( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +/*-- vec_srl ----------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_srl(vector signed char __a, vector unsigned char __b) { + return (vector signed char)__builtin_s390_vsrl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector signed char +vec_srl(vector signed char __a, vector unsigned short __b) { + return (vector signed char)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed char +vec_srl(vector signed char __a, vector unsigned int __b) { + return (vector signed char)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool char +vec_srl(vector bool char __a, vector unsigned char __b) { + return (vector bool char)__builtin_s390_vsrl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector bool char +vec_srl(vector bool char __a, vector unsigned short __b) { + return (vector bool char)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool char +vec_srl(vector bool char __a, vector unsigned int __b) { + return (vector bool char)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_srl(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vsrl(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_srl(vector unsigned char __a, vector unsigned short __b) { + return __builtin_s390_vsrl(__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_srl(vector unsigned char __a, vector unsigned int __b) { + return __builtin_s390_vsrl(__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed short +vec_srl(vector signed short __a, vector unsigned char __b) { + return (vector signed short)__builtin_s390_vsrl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_srl(vector signed short __a, vector unsigned short __b) { + return (vector signed short)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed short +vec_srl(vector signed short __a, vector unsigned int __b) { + return (vector signed short)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool short +vec_srl(vector bool short __a, vector unsigned char __b) { + return (vector bool short)__builtin_s390_vsrl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector bool short +vec_srl(vector bool short __a, vector unsigned short __b) { + return (vector bool short)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool short +vec_srl(vector bool short __a, vector unsigned int __b) { + return (vector bool short)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_srl(vector unsigned short __a, vector unsigned char __b) { + return (vector unsigned short)__builtin_s390_vsrl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_srl(vector unsigned short __a, vector unsigned short __b) { + return (vector unsigned short)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_srl(vector unsigned short __a, vector unsigned int __b) { + return (vector unsigned short)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed int +vec_srl(vector signed int __a, vector unsigned char __b) { + return (vector signed int)__builtin_s390_vsrl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_srl(vector signed int __a, vector unsigned short __b) { + return (vector signed int)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed int +vec_srl(vector signed int __a, vector unsigned int __b) { + return (vector signed int)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool int +vec_srl(vector bool int __a, vector unsigned char __b) { + return (vector bool int)__builtin_s390_vsrl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector bool int +vec_srl(vector bool int __a, vector unsigned short __b) { + return (vector bool int)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool int +vec_srl(vector bool int __a, vector unsigned int __b) { + return (vector bool int)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_srl(vector unsigned int __a, vector unsigned char __b) { + return (vector unsigned int)__builtin_s390_vsrl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_srl(vector unsigned int __a, vector unsigned short __b) { + return (vector unsigned int)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_srl(vector unsigned int __a, vector unsigned int __b) { + return (vector unsigned int)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_srl(vector signed long long __a, vector unsigned char __b) { + return (vector signed long long)__builtin_s390_vsrl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_srl(vector signed long long __a, vector unsigned short __b) { + return (vector signed long long)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_srl(vector signed long long __a, vector unsigned int __b) { + return (vector signed long long)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_srl(vector bool long long __a, vector unsigned char __b) { + return (vector bool long long)__builtin_s390_vsrl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_srl(vector bool long long __a, vector unsigned short __b) { + return (vector bool long long)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector bool long long +vec_srl(vector bool long long __a, vector unsigned int __b) { + return (vector bool long long)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_srl(vector unsigned long long __a, vector unsigned char __b) { + return (vector unsigned long long)__builtin_s390_vsrl( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_srl(vector unsigned long long __a, vector unsigned short __b) { + return (vector unsigned long long)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_srl(vector unsigned long long __a, vector unsigned int __b) { + return (vector unsigned long long)__builtin_s390_vsrl( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +/*-- vec_srb ----------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_srb(vector signed char __a, vector signed char __b) { + return (vector signed char)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed char +vec_srb(vector signed char __a, vector unsigned char __b) { + return (vector signed char)__builtin_s390_vsrlb( + (vector unsigned char)__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_srb(vector unsigned char __a, vector signed char __b) { + return __builtin_s390_vsrlb(__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_srb(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vsrlb(__a, __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_srb(vector signed short __a, vector signed short __b) { + return (vector signed short)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed short +vec_srb(vector signed short __a, vector unsigned short __b) { + return (vector signed short)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_srb(vector unsigned short __a, vector signed short __b) { + return (vector unsigned short)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_srb(vector unsigned short __a, vector unsigned short __b) { + return (vector unsigned short)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed int +vec_srb(vector signed int __a, vector signed int __b) { + return (vector signed int)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed int +vec_srb(vector signed int __a, vector unsigned int __b) { + return (vector signed int)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_srb(vector unsigned int __a, vector signed int __b) { + return (vector unsigned int)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_srb(vector unsigned int __a, vector unsigned int __b) { + return (vector unsigned int)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_srb(vector signed long long __a, vector signed long long __b) { + return (vector signed long long)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_srb(vector signed long long __a, vector unsigned long long __b) { + return (vector signed long long)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_srb(vector unsigned long long __a, vector signed long long __b) { + return (vector unsigned long long)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_srb(vector unsigned long long __a, vector unsigned long long __b) { + return (vector unsigned long long)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector double +vec_srb(vector double __a, vector signed long long __b) { + return (vector double)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector double +vec_srb(vector double __a, vector unsigned long long __b) { + return (vector double)__builtin_s390_vsrlb( + (vector unsigned char)__a, (vector unsigned char)__b); +} + +/*-- vec_abs ----------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_abs(vector signed char __a) { + return vec_sel(__a, -__a, vec_cmplt(__a, (vector signed char)0)); +} + +static inline __ATTRS_o_ai vector signed short +vec_abs(vector signed short __a) { + return vec_sel(__a, -__a, vec_cmplt(__a, (vector signed short)0)); +} + +static inline __ATTRS_o_ai vector signed int +vec_abs(vector signed int __a) { + return vec_sel(__a, -__a, vec_cmplt(__a, (vector signed int)0)); +} + +static inline __ATTRS_o_ai vector signed long long +vec_abs(vector signed long long __a) { + return vec_sel(__a, -__a, vec_cmplt(__a, (vector signed long long)0)); +} + +static inline __ATTRS_o_ai vector double +vec_abs(vector double __a) { + return __builtin_s390_vflpdb(__a); +} + +/*-- vec_nabs ---------------------------------------------------------------*/ + +static inline __ATTRS_ai vector double +vec_nabs(vector double __a) { + return __builtin_s390_vflndb(__a); +} + +/*-- vec_max ----------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_max(vector signed char __a, vector signed char __b) { + return vec_sel(__b, __a, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector signed char +vec_max(vector signed char __a, vector bool char __b) { + vector signed char __bc = (vector signed char)__b; + return vec_sel(__bc, __a, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector signed char +vec_max(vector bool char __a, vector signed char __b) { + vector signed char __ac = (vector signed char)__a; + return vec_sel(__b, __ac, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_max(vector unsigned char __a, vector unsigned char __b) { + return vec_sel(__b, __a, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_max(vector unsigned char __a, vector bool char __b) { + vector unsigned char __bc = (vector unsigned char)__b; + return vec_sel(__bc, __a, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_max(vector bool char __a, vector unsigned char __b) { + vector unsigned char __ac = (vector unsigned char)__a; + return vec_sel(__b, __ac, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector signed short +vec_max(vector signed short __a, vector signed short __b) { + return vec_sel(__b, __a, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector signed short +vec_max(vector signed short __a, vector bool short __b) { + vector signed short __bc = (vector signed short)__b; + return vec_sel(__bc, __a, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector signed short +vec_max(vector bool short __a, vector signed short __b) { + vector signed short __ac = (vector signed short)__a; + return vec_sel(__b, __ac, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_max(vector unsigned short __a, vector unsigned short __b) { + return vec_sel(__b, __a, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_max(vector unsigned short __a, vector bool short __b) { + vector unsigned short __bc = (vector unsigned short)__b; + return vec_sel(__bc, __a, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_max(vector bool short __a, vector unsigned short __b) { + vector unsigned short __ac = (vector unsigned short)__a; + return vec_sel(__b, __ac, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector signed int +vec_max(vector signed int __a, vector signed int __b) { + return vec_sel(__b, __a, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector signed int +vec_max(vector signed int __a, vector bool int __b) { + vector signed int __bc = (vector signed int)__b; + return vec_sel(__bc, __a, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector signed int +vec_max(vector bool int __a, vector signed int __b) { + vector signed int __ac = (vector signed int)__a; + return vec_sel(__b, __ac, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_max(vector unsigned int __a, vector unsigned int __b) { + return vec_sel(__b, __a, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_max(vector unsigned int __a, vector bool int __b) { + vector unsigned int __bc = (vector unsigned int)__b; + return vec_sel(__bc, __a, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_max(vector bool int __a, vector unsigned int __b) { + vector unsigned int __ac = (vector unsigned int)__a; + return vec_sel(__b, __ac, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector signed long long +vec_max(vector signed long long __a, vector signed long long __b) { + return vec_sel(__b, __a, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector signed long long +vec_max(vector signed long long __a, vector bool long long __b) { + vector signed long long __bc = (vector signed long long)__b; + return vec_sel(__bc, __a, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector signed long long +vec_max(vector bool long long __a, vector signed long long __b) { + vector signed long long __ac = (vector signed long long)__a; + return vec_sel(__b, __ac, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_max(vector unsigned long long __a, vector unsigned long long __b) { + return vec_sel(__b, __a, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_max(vector unsigned long long __a, vector bool long long __b) { + vector unsigned long long __bc = (vector unsigned long long)__b; + return vec_sel(__bc, __a, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_max(vector bool long long __a, vector unsigned long long __b) { + vector unsigned long long __ac = (vector unsigned long long)__a; + return vec_sel(__b, __ac, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector double +vec_max(vector double __a, vector double __b) { + return vec_sel(__b, __a, vec_cmpgt(__a, __b)); +} + +/*-- vec_min ----------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_min(vector signed char __a, vector signed char __b) { + return vec_sel(__a, __b, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector signed char +vec_min(vector signed char __a, vector bool char __b) { + vector signed char __bc = (vector signed char)__b; + return vec_sel(__a, __bc, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector signed char +vec_min(vector bool char __a, vector signed char __b) { + vector signed char __ac = (vector signed char)__a; + return vec_sel(__ac, __b, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_min(vector unsigned char __a, vector unsigned char __b) { + return vec_sel(__a, __b, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_min(vector unsigned char __a, vector bool char __b) { + vector unsigned char __bc = (vector unsigned char)__b; + return vec_sel(__a, __bc, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_min(vector bool char __a, vector unsigned char __b) { + vector unsigned char __ac = (vector unsigned char)__a; + return vec_sel(__ac, __b, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector signed short +vec_min(vector signed short __a, vector signed short __b) { + return vec_sel(__a, __b, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector signed short +vec_min(vector signed short __a, vector bool short __b) { + vector signed short __bc = (vector signed short)__b; + return vec_sel(__a, __bc, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector signed short +vec_min(vector bool short __a, vector signed short __b) { + vector signed short __ac = (vector signed short)__a; + return vec_sel(__ac, __b, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_min(vector unsigned short __a, vector unsigned short __b) { + return vec_sel(__a, __b, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_min(vector unsigned short __a, vector bool short __b) { + vector unsigned short __bc = (vector unsigned short)__b; + return vec_sel(__a, __bc, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_min(vector bool short __a, vector unsigned short __b) { + vector unsigned short __ac = (vector unsigned short)__a; + return vec_sel(__ac, __b, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector signed int +vec_min(vector signed int __a, vector signed int __b) { + return vec_sel(__a, __b, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector signed int +vec_min(vector signed int __a, vector bool int __b) { + vector signed int __bc = (vector signed int)__b; + return vec_sel(__a, __bc, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector signed int +vec_min(vector bool int __a, vector signed int __b) { + vector signed int __ac = (vector signed int)__a; + return vec_sel(__ac, __b, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_min(vector unsigned int __a, vector unsigned int __b) { + return vec_sel(__a, __b, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_min(vector unsigned int __a, vector bool int __b) { + vector unsigned int __bc = (vector unsigned int)__b; + return vec_sel(__a, __bc, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_min(vector bool int __a, vector unsigned int __b) { + vector unsigned int __ac = (vector unsigned int)__a; + return vec_sel(__ac, __b, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector signed long long +vec_min(vector signed long long __a, vector signed long long __b) { + return vec_sel(__a, __b, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector signed long long +vec_min(vector signed long long __a, vector bool long long __b) { + vector signed long long __bc = (vector signed long long)__b; + return vec_sel(__a, __bc, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector signed long long +vec_min(vector bool long long __a, vector signed long long __b) { + vector signed long long __ac = (vector signed long long)__a; + return vec_sel(__ac, __b, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_min(vector unsigned long long __a, vector unsigned long long __b) { + return vec_sel(__a, __b, vec_cmpgt(__a, __b)); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_min(vector unsigned long long __a, vector bool long long __b) { + vector unsigned long long __bc = (vector unsigned long long)__b; + return vec_sel(__a, __bc, vec_cmpgt(__a, __bc)); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_min(vector bool long long __a, vector unsigned long long __b) { + vector unsigned long long __ac = (vector unsigned long long)__a; + return vec_sel(__ac, __b, vec_cmpgt(__ac, __b)); +} + +static inline __ATTRS_o_ai vector double +vec_min(vector double __a, vector double __b) { + return vec_sel(__a, __b, vec_cmpgt(__a, __b)); +} + +/*-- vec_add_u128 -----------------------------------------------------------*/ + +static inline __ATTRS_ai vector unsigned char +vec_add_u128(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vaq(__a, __b); +} + +/*-- vec_addc ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_addc(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vaccb(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_addc(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vacch(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_addc(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vaccf(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_addc(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_s390_vaccg(__a, __b); +} + +/*-- vec_addc_u128 ----------------------------------------------------------*/ + +static inline __ATTRS_ai vector unsigned char +vec_addc_u128(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vaccq(__a, __b); +} + +/*-- vec_adde_u128 ----------------------------------------------------------*/ + +static inline __ATTRS_ai vector unsigned char +vec_adde_u128(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return __builtin_s390_vacq(__a, __b, __c); +} + +/*-- vec_addec_u128 ---------------------------------------------------------*/ + +static inline __ATTRS_ai vector unsigned char +vec_addec_u128(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return __builtin_s390_vacccq(__a, __b, __c); +} + +/*-- vec_avg ----------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_avg(vector signed char __a, vector signed char __b) { + return __builtin_s390_vavgb(__a, __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_avg(vector signed short __a, vector signed short __b) { + return __builtin_s390_vavgh(__a, __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_avg(vector signed int __a, vector signed int __b) { + return __builtin_s390_vavgf(__a, __b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_avg(vector signed long long __a, vector signed long long __b) { + return __builtin_s390_vavgg(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_avg(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vavglb(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_avg(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vavglh(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_avg(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vavglf(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_avg(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_s390_vavglg(__a, __b); +} + +/*-- vec_checksum -----------------------------------------------------------*/ + +static inline __ATTRS_ai vector unsigned int +vec_checksum(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vcksm(__a, __b); +} + +/*-- vec_gfmsum -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned short +vec_gfmsum(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vgfmb(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_gfmsum(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vgfmh(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_gfmsum(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vgfmf(__a, __b); +} + +/*-- vec_gfmsum_128 ---------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_gfmsum_128(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_s390_vgfmg(__a, __b); +} + +/*-- vec_gfmsum_accum -------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned short +vec_gfmsum_accum(vector unsigned char __a, vector unsigned char __b, + vector unsigned short __c) { + return __builtin_s390_vgfmab(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_gfmsum_accum(vector unsigned short __a, vector unsigned short __b, + vector unsigned int __c) { + return __builtin_s390_vgfmah(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_gfmsum_accum(vector unsigned int __a, vector unsigned int __b, + vector unsigned long long __c) { + return __builtin_s390_vgfmaf(__a, __b, __c); +} + +/*-- vec_gfmsum_accum_128 ---------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_gfmsum_accum_128(vector unsigned long long __a, + vector unsigned long long __b, + vector unsigned char __c) { + return __builtin_s390_vgfmag(__a, __b, __c); +} + +/*-- vec_mladd --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_mladd(vector signed char __a, vector signed char __b, + vector signed char __c) { + return __a * __b + __c; +} + +static inline __ATTRS_o_ai vector signed char +vec_mladd(vector unsigned char __a, vector signed char __b, + vector signed char __c) { + return (vector signed char)__a * __b + __c; +} + +static inline __ATTRS_o_ai vector signed char +vec_mladd(vector signed char __a, vector unsigned char __b, + vector unsigned char __c) { + return __a * (vector signed char)__b + (vector signed char)__c; +} + +static inline __ATTRS_o_ai vector unsigned char +vec_mladd(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return __a * __b + __c; +} + +static inline __ATTRS_o_ai vector signed short +vec_mladd(vector signed short __a, vector signed short __b, + vector signed short __c) { + return __a * __b + __c; +} + +static inline __ATTRS_o_ai vector signed short +vec_mladd(vector unsigned short __a, vector signed short __b, + vector signed short __c) { + return (vector signed short)__a * __b + __c; +} + +static inline __ATTRS_o_ai vector signed short +vec_mladd(vector signed short __a, vector unsigned short __b, + vector unsigned short __c) { + return __a * (vector signed short)__b + (vector signed short)__c; +} + +static inline __ATTRS_o_ai vector unsigned short +vec_mladd(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c) { + return __a * __b + __c; +} + +static inline __ATTRS_o_ai vector signed int +vec_mladd(vector signed int __a, vector signed int __b, + vector signed int __c) { + return __a * __b + __c; +} + +static inline __ATTRS_o_ai vector signed int +vec_mladd(vector unsigned int __a, vector signed int __b, + vector signed int __c) { + return (vector signed int)__a * __b + __c; +} + +static inline __ATTRS_o_ai vector signed int +vec_mladd(vector signed int __a, vector unsigned int __b, + vector unsigned int __c) { + return __a * (vector signed int)__b + (vector signed int)__c; +} + +static inline __ATTRS_o_ai vector unsigned int +vec_mladd(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c) { + return __a * __b + __c; +} + +/*-- vec_mhadd --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_mhadd(vector signed char __a, vector signed char __b, + vector signed char __c) { + return __builtin_s390_vmahb(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_mhadd(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return __builtin_s390_vmalhb(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector signed short +vec_mhadd(vector signed short __a, vector signed short __b, + vector signed short __c) { + return __builtin_s390_vmahh(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_mhadd(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c) { + return __builtin_s390_vmalhh(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector signed int +vec_mhadd(vector signed int __a, vector signed int __b, + vector signed int __c) { + return __builtin_s390_vmahf(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_mhadd(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c) { + return __builtin_s390_vmalhf(__a, __b, __c); +} + +/*-- vec_meadd --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed short +vec_meadd(vector signed char __a, vector signed char __b, + vector signed short __c) { + return __builtin_s390_vmaeb(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_meadd(vector unsigned char __a, vector unsigned char __b, + vector unsigned short __c) { + return __builtin_s390_vmaleb(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector signed int +vec_meadd(vector signed short __a, vector signed short __b, + vector signed int __c) { + return __builtin_s390_vmaeh(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_meadd(vector unsigned short __a, vector unsigned short __b, + vector unsigned int __c) { + return __builtin_s390_vmaleh(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector signed long long +vec_meadd(vector signed int __a, vector signed int __b, + vector signed long long __c) { + return __builtin_s390_vmaef(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_meadd(vector unsigned int __a, vector unsigned int __b, + vector unsigned long long __c) { + return __builtin_s390_vmalef(__a, __b, __c); +} + +/*-- vec_moadd --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed short +vec_moadd(vector signed char __a, vector signed char __b, + vector signed short __c) { + return __builtin_s390_vmaob(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_moadd(vector unsigned char __a, vector unsigned char __b, + vector unsigned short __c) { + return __builtin_s390_vmalob(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector signed int +vec_moadd(vector signed short __a, vector signed short __b, + vector signed int __c) { + return __builtin_s390_vmaoh(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_moadd(vector unsigned short __a, vector unsigned short __b, + vector unsigned int __c) { + return __builtin_s390_vmaloh(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector signed long long +vec_moadd(vector signed int __a, vector signed int __b, + vector signed long long __c) { + return __builtin_s390_vmaof(__a, __b, __c); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_moadd(vector unsigned int __a, vector unsigned int __b, + vector unsigned long long __c) { + return __builtin_s390_vmalof(__a, __b, __c); +} + +/*-- vec_mulh ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_mulh(vector signed char __a, vector signed char __b) { + return __builtin_s390_vmhb(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_mulh(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vmlhb(__a, __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_mulh(vector signed short __a, vector signed short __b) { + return __builtin_s390_vmhh(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_mulh(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vmlhh(__a, __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_mulh(vector signed int __a, vector signed int __b) { + return __builtin_s390_vmhf(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_mulh(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vmlhf(__a, __b); +} + +/*-- vec_mule ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed short +vec_mule(vector signed char __a, vector signed char __b) { + return __builtin_s390_vmeb(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_mule(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vmleb(__a, __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_mule(vector signed short __a, vector signed short __b) { + return __builtin_s390_vmeh(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_mule(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vmleh(__a, __b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_mule(vector signed int __a, vector signed int __b) { + return __builtin_s390_vmef(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_mule(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vmlef(__a, __b); +} + +/*-- vec_mulo ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed short +vec_mulo(vector signed char __a, vector signed char __b) { + return __builtin_s390_vmob(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_mulo(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vmlob(__a, __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_mulo(vector signed short __a, vector signed short __b) { + return __builtin_s390_vmoh(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_mulo(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vmloh(__a, __b); +} + +static inline __ATTRS_o_ai vector signed long long +vec_mulo(vector signed int __a, vector signed int __b) { + return __builtin_s390_vmof(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_mulo(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vmlof(__a, __b); +} + +/*-- vec_sub_u128 -----------------------------------------------------------*/ + +static inline __ATTRS_ai vector unsigned char +vec_sub_u128(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vsq(__a, __b); +} + +/*-- vec_subc ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_subc(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vscbib(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_subc(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vscbih(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_subc(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vscbif(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_subc(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_s390_vscbig(__a, __b); +} + +/*-- vec_subc_u128 ----------------------------------------------------------*/ + +static inline __ATTRS_ai vector unsigned char +vec_subc_u128(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vscbiq(__a, __b); +} + +/*-- vec_sube_u128 ----------------------------------------------------------*/ + +static inline __ATTRS_ai vector unsigned char +vec_sube_u128(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return __builtin_s390_vsbiq(__a, __b, __c); +} + +/*-- vec_subec_u128 ---------------------------------------------------------*/ + +static inline __ATTRS_ai vector unsigned char +vec_subec_u128(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return __builtin_s390_vsbcbiq(__a, __b, __c); +} + +/*-- vec_sum2 ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned long long +vec_sum2(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vsumgh(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned long long +vec_sum2(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vsumgf(__a, __b); +} + +/*-- vec_sum_u128 -----------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_sum_u128(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vsumqf(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_sum_u128(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_s390_vsumqg(__a, __b); +} + +/*-- vec_sum4 ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned int +vec_sum4(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vsumb(__a, __b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_sum4(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vsumh(__a, __b); +} + +/*-- vec_test_mask ----------------------------------------------------------*/ + +static inline __ATTRS_o_ai int +vec_test_mask(vector signed char __a, vector unsigned char __b) { + return __builtin_s390_vtm((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai int +vec_test_mask(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vtm(__a, __b); +} + +static inline __ATTRS_o_ai int +vec_test_mask(vector signed short __a, vector unsigned short __b) { + return __builtin_s390_vtm((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai int +vec_test_mask(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vtm((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai int +vec_test_mask(vector signed int __a, vector unsigned int __b) { + return __builtin_s390_vtm((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai int +vec_test_mask(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vtm((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai int +vec_test_mask(vector signed long long __a, vector unsigned long long __b) { + return __builtin_s390_vtm((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai int +vec_test_mask(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_s390_vtm((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai int +vec_test_mask(vector double __a, vector unsigned long long __b) { + return __builtin_s390_vtm((vector unsigned char)__a, + (vector unsigned char)__b); +} + +/*-- vec_madd ---------------------------------------------------------------*/ + +static inline __ATTRS_ai vector double +vec_madd(vector double __a, vector double __b, vector double __c) { + return __builtin_s390_vfmadb(__a, __b, __c); +} + +/*-- vec_msub ---------------------------------------------------------------*/ + +static inline __ATTRS_ai vector double +vec_msub(vector double __a, vector double __b, vector double __c) { + return __builtin_s390_vfmsdb(__a, __b, __c); +} + +/*-- vec_sqrt ---------------------------------------------------------------*/ + +static inline __ATTRS_ai vector double +vec_sqrt(vector double __a) { + return __builtin_s390_vfsqdb(__a); +} + +/*-- vec_ld2f ---------------------------------------------------------------*/ + +static inline __ATTRS_ai vector double +vec_ld2f(const float *__ptr) { + typedef float __v2f32 __attribute__((__vector_size__(8))); + return __builtin_convertvector(*(const __v2f32 *)__ptr, vector double); +} + +/*-- vec_st2f ---------------------------------------------------------------*/ + +static inline __ATTRS_ai void +vec_st2f(vector double __a, float *__ptr) { + typedef float __v2f32 __attribute__((__vector_size__(8))); + *(__v2f32 *)__ptr = __builtin_convertvector(__a, __v2f32); +} + +/*-- vec_ctd ----------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector double +vec_ctd(vector signed long long __a, int __b) + __constant_range(__b, 0, 31) { + vector double __conv = __builtin_convertvector(__a, vector double); + __conv *= (vector double)(vector unsigned long long)((0x3ffULL - __b) << 52); + return __conv; +} + +static inline __ATTRS_o_ai vector double +vec_ctd(vector unsigned long long __a, int __b) + __constant_range(__b, 0, 31) { + vector double __conv = __builtin_convertvector(__a, vector double); + __conv *= (vector double)(vector unsigned long long)((0x3ffULL - __b) << 52); + return __conv; +} + +/*-- vec_ctsl ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed long long +vec_ctsl(vector double __a, int __b) + __constant_range(__b, 0, 31) { + __a *= (vector double)(vector unsigned long long)((0x3ffULL + __b) << 52); + return __builtin_convertvector(__a, vector signed long long); +} + +/*-- vec_ctul ---------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned long long +vec_ctul(vector double __a, int __b) + __constant_range(__b, 0, 31) { + __a *= (vector double)(vector unsigned long long)((0x3ffULL + __b) << 52); + return __builtin_convertvector(__a, vector unsigned long long); +} + +/*-- vec_roundp -------------------------------------------------------------*/ + +static inline __ATTRS_ai vector double +vec_roundp(vector double __a) { + return __builtin_s390_vfidb(__a, 4, 6); +} + +/*-- vec_ceil ---------------------------------------------------------------*/ + +static inline __ATTRS_ai vector double +vec_ceil(vector double __a) { + // On this platform, vec_ceil never triggers the IEEE-inexact exception. + return __builtin_s390_vfidb(__a, 4, 6); +} + +/*-- vec_roundm -------------------------------------------------------------*/ + +static inline __ATTRS_ai vector double +vec_roundm(vector double __a) { + return __builtin_s390_vfidb(__a, 4, 7); +} + +/*-- vec_floor --------------------------------------------------------------*/ + +static inline __ATTRS_ai vector double +vec_floor(vector double __a) { + // On this platform, vec_floor never triggers the IEEE-inexact exception. + return __builtin_s390_vfidb(__a, 4, 7); +} + +/*-- vec_roundz -------------------------------------------------------------*/ + +static inline __ATTRS_ai vector double +vec_roundz(vector double __a) { + return __builtin_s390_vfidb(__a, 4, 5); +} + +/*-- vec_trunc --------------------------------------------------------------*/ + +static inline __ATTRS_ai vector double +vec_trunc(vector double __a) { + // On this platform, vec_trunc never triggers the IEEE-inexact exception. + return __builtin_s390_vfidb(__a, 4, 5); +} + +/*-- vec_roundc -------------------------------------------------------------*/ + +static inline __ATTRS_ai vector double +vec_roundc(vector double __a) { + return __builtin_s390_vfidb(__a, 4, 0); +} + +/*-- vec_round --------------------------------------------------------------*/ + +static inline __ATTRS_ai vector double +vec_round(vector double __a) { + return __builtin_s390_vfidb(__a, 4, 4); +} + +/*-- vec_fp_test_data_class -------------------------------------------------*/ + +#define vec_fp_test_data_class(X, Y, Z) \ + ((vector bool long long)__builtin_s390_vftcidb((X), (Y), (Z))) + +/*-- vec_cp_until_zero ------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_cp_until_zero(vector signed char __a) { + return (vector signed char)__builtin_s390_vistrb((vector unsigned char)__a); +} + +static inline __ATTRS_o_ai vector bool char +vec_cp_until_zero(vector bool char __a) { + return (vector bool char)__builtin_s390_vistrb((vector unsigned char)__a); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cp_until_zero(vector unsigned char __a) { + return __builtin_s390_vistrb(__a); +} + +static inline __ATTRS_o_ai vector signed short +vec_cp_until_zero(vector signed short __a) { + return (vector signed short)__builtin_s390_vistrh((vector unsigned short)__a); +} + +static inline __ATTRS_o_ai vector bool short +vec_cp_until_zero(vector bool short __a) { + return (vector bool short)__builtin_s390_vistrh((vector unsigned short)__a); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cp_until_zero(vector unsigned short __a) { + return __builtin_s390_vistrh(__a); +} + +static inline __ATTRS_o_ai vector signed int +vec_cp_until_zero(vector signed int __a) { + return (vector signed int)__builtin_s390_vistrf((vector unsigned int)__a); +} + +static inline __ATTRS_o_ai vector bool int +vec_cp_until_zero(vector bool int __a) { + return (vector bool int)__builtin_s390_vistrf((vector unsigned int)__a); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cp_until_zero(vector unsigned int __a) { + return __builtin_s390_vistrf(__a); +} + +/*-- vec_cp_until_zero_cc ---------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_cp_until_zero_cc(vector signed char __a, int *__cc) { + return (vector signed char) + __builtin_s390_vistrbs((vector unsigned char)__a, __cc); +} + +static inline __ATTRS_o_ai vector bool char +vec_cp_until_zero_cc(vector bool char __a, int *__cc) { + return (vector bool char) + __builtin_s390_vistrbs((vector unsigned char)__a, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cp_until_zero_cc(vector unsigned char __a, int *__cc) { + return __builtin_s390_vistrbs(__a, __cc); +} + +static inline __ATTRS_o_ai vector signed short +vec_cp_until_zero_cc(vector signed short __a, int *__cc) { + return (vector signed short) + __builtin_s390_vistrhs((vector unsigned short)__a, __cc); +} + +static inline __ATTRS_o_ai vector bool short +vec_cp_until_zero_cc(vector bool short __a, int *__cc) { + return (vector bool short) + __builtin_s390_vistrhs((vector unsigned short)__a, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cp_until_zero_cc(vector unsigned short __a, int *__cc) { + return __builtin_s390_vistrhs(__a, __cc); +} + +static inline __ATTRS_o_ai vector signed int +vec_cp_until_zero_cc(vector signed int __a, int *__cc) { + return (vector signed int) + __builtin_s390_vistrfs((vector unsigned int)__a, __cc); +} + +static inline __ATTRS_o_ai vector bool int +vec_cp_until_zero_cc(vector bool int __a, int *__cc) { + return (vector bool int)__builtin_s390_vistrfs((vector unsigned int)__a, + __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cp_until_zero_cc(vector unsigned int __a, int *__cc) { + return __builtin_s390_vistrfs(__a, __cc); +} + +/*-- vec_cmpeq_idx ----------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_cmpeq_idx(vector signed char __a, vector signed char __b) { + return (vector signed char) + __builtin_s390_vfeeb((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpeq_idx(vector bool char __a, vector bool char __b) { + return __builtin_s390_vfeeb((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpeq_idx(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vfeeb(__a, __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_cmpeq_idx(vector signed short __a, vector signed short __b) { + return (vector signed short) + __builtin_s390_vfeeh((vector unsigned short)__a, + (vector unsigned short)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpeq_idx(vector bool short __a, vector bool short __b) { + return __builtin_s390_vfeeh((vector unsigned short)__a, + (vector unsigned short)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpeq_idx(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vfeeh(__a, __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_cmpeq_idx(vector signed int __a, vector signed int __b) { + return (vector signed int) + __builtin_s390_vfeef((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpeq_idx(vector bool int __a, vector bool int __b) { + return __builtin_s390_vfeef((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpeq_idx(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vfeef(__a, __b); +} + +/*-- vec_cmpeq_idx_cc -------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_cmpeq_idx_cc(vector signed char __a, vector signed char __b, int *__cc) { + return (vector signed char) + __builtin_s390_vfeebs((vector unsigned char)__a, + (vector unsigned char)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpeq_idx_cc(vector bool char __a, vector bool char __b, int *__cc) { + return __builtin_s390_vfeebs((vector unsigned char)__a, + (vector unsigned char)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpeq_idx_cc(vector unsigned char __a, vector unsigned char __b, + int *__cc) { + return __builtin_s390_vfeebs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector signed short +vec_cmpeq_idx_cc(vector signed short __a, vector signed short __b, int *__cc) { + return (vector signed short) + __builtin_s390_vfeehs((vector unsigned short)__a, + (vector unsigned short)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpeq_idx_cc(vector bool short __a, vector bool short __b, int *__cc) { + return __builtin_s390_vfeehs((vector unsigned short)__a, + (vector unsigned short)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpeq_idx_cc(vector unsigned short __a, vector unsigned short __b, + int *__cc) { + return __builtin_s390_vfeehs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector signed int +vec_cmpeq_idx_cc(vector signed int __a, vector signed int __b, int *__cc) { + return (vector signed int) + __builtin_s390_vfeefs((vector unsigned int)__a, + (vector unsigned int)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpeq_idx_cc(vector bool int __a, vector bool int __b, int *__cc) { + return __builtin_s390_vfeefs((vector unsigned int)__a, + (vector unsigned int)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpeq_idx_cc(vector unsigned int __a, vector unsigned int __b, int *__cc) { + return __builtin_s390_vfeefs(__a, __b, __cc); +} + +/*-- vec_cmpeq_or_0_idx -----------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_cmpeq_or_0_idx(vector signed char __a, vector signed char __b) { + return (vector signed char) + __builtin_s390_vfeezb((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpeq_or_0_idx(vector bool char __a, vector bool char __b) { + return __builtin_s390_vfeezb((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpeq_or_0_idx(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vfeezb(__a, __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_cmpeq_or_0_idx(vector signed short __a, vector signed short __b) { + return (vector signed short) + __builtin_s390_vfeezh((vector unsigned short)__a, + (vector unsigned short)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpeq_or_0_idx(vector bool short __a, vector bool short __b) { + return __builtin_s390_vfeezh((vector unsigned short)__a, + (vector unsigned short)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpeq_or_0_idx(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vfeezh(__a, __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_cmpeq_or_0_idx(vector signed int __a, vector signed int __b) { + return (vector signed int) + __builtin_s390_vfeezf((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpeq_or_0_idx(vector bool int __a, vector bool int __b) { + return __builtin_s390_vfeezf((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpeq_or_0_idx(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vfeezf(__a, __b); +} + +/*-- vec_cmpeq_or_0_idx_cc --------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_cmpeq_or_0_idx_cc(vector signed char __a, vector signed char __b, + int *__cc) { + return (vector signed char) + __builtin_s390_vfeezbs((vector unsigned char)__a, + (vector unsigned char)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpeq_or_0_idx_cc(vector bool char __a, vector bool char __b, int *__cc) { + return __builtin_s390_vfeezbs((vector unsigned char)__a, + (vector unsigned char)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpeq_or_0_idx_cc(vector unsigned char __a, vector unsigned char __b, + int *__cc) { + return __builtin_s390_vfeezbs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector signed short +vec_cmpeq_or_0_idx_cc(vector signed short __a, vector signed short __b, + int *__cc) { + return (vector signed short) + __builtin_s390_vfeezhs((vector unsigned short)__a, + (vector unsigned short)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpeq_or_0_idx_cc(vector bool short __a, vector bool short __b, int *__cc) { + return __builtin_s390_vfeezhs((vector unsigned short)__a, + (vector unsigned short)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpeq_or_0_idx_cc(vector unsigned short __a, vector unsigned short __b, + int *__cc) { + return __builtin_s390_vfeezhs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector signed int +vec_cmpeq_or_0_idx_cc(vector signed int __a, vector signed int __b, int *__cc) { + return (vector signed int) + __builtin_s390_vfeezfs((vector unsigned int)__a, + (vector unsigned int)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpeq_or_0_idx_cc(vector bool int __a, vector bool int __b, int *__cc) { + return __builtin_s390_vfeezfs((vector unsigned int)__a, + (vector unsigned int)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpeq_or_0_idx_cc(vector unsigned int __a, vector unsigned int __b, + int *__cc) { + return __builtin_s390_vfeezfs(__a, __b, __cc); +} + +/*-- vec_cmpne_idx ----------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_cmpne_idx(vector signed char __a, vector signed char __b) { + return (vector signed char) + __builtin_s390_vfeneb((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpne_idx(vector bool char __a, vector bool char __b) { + return __builtin_s390_vfeneb((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpne_idx(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vfeneb(__a, __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_cmpne_idx(vector signed short __a, vector signed short __b) { + return (vector signed short) + __builtin_s390_vfeneh((vector unsigned short)__a, + (vector unsigned short)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpne_idx(vector bool short __a, vector bool short __b) { + return __builtin_s390_vfeneh((vector unsigned short)__a, + (vector unsigned short)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpne_idx(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vfeneh(__a, __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_cmpne_idx(vector signed int __a, vector signed int __b) { + return (vector signed int) + __builtin_s390_vfenef((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpne_idx(vector bool int __a, vector bool int __b) { + return __builtin_s390_vfenef((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpne_idx(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vfenef(__a, __b); +} + +/*-- vec_cmpne_idx_cc -------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_cmpne_idx_cc(vector signed char __a, vector signed char __b, int *__cc) { + return (vector signed char) + __builtin_s390_vfenebs((vector unsigned char)__a, + (vector unsigned char)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpne_idx_cc(vector bool char __a, vector bool char __b, int *__cc) { + return __builtin_s390_vfenebs((vector unsigned char)__a, + (vector unsigned char)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpne_idx_cc(vector unsigned char __a, vector unsigned char __b, + int *__cc) { + return __builtin_s390_vfenebs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector signed short +vec_cmpne_idx_cc(vector signed short __a, vector signed short __b, int *__cc) { + return (vector signed short) + __builtin_s390_vfenehs((vector unsigned short)__a, + (vector unsigned short)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpne_idx_cc(vector bool short __a, vector bool short __b, int *__cc) { + return __builtin_s390_vfenehs((vector unsigned short)__a, + (vector unsigned short)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpne_idx_cc(vector unsigned short __a, vector unsigned short __b, + int *__cc) { + return __builtin_s390_vfenehs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector signed int +vec_cmpne_idx_cc(vector signed int __a, vector signed int __b, int *__cc) { + return (vector signed int) + __builtin_s390_vfenefs((vector unsigned int)__a, + (vector unsigned int)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpne_idx_cc(vector bool int __a, vector bool int __b, int *__cc) { + return __builtin_s390_vfenefs((vector unsigned int)__a, + (vector unsigned int)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpne_idx_cc(vector unsigned int __a, vector unsigned int __b, int *__cc) { + return __builtin_s390_vfenefs(__a, __b, __cc); +} + +/*-- vec_cmpne_or_0_idx -----------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_cmpne_or_0_idx(vector signed char __a, vector signed char __b) { + return (vector signed char) + __builtin_s390_vfenezb((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpne_or_0_idx(vector bool char __a, vector bool char __b) { + return __builtin_s390_vfenezb((vector unsigned char)__a, + (vector unsigned char)__b); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpne_or_0_idx(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vfenezb(__a, __b); +} + +static inline __ATTRS_o_ai vector signed short +vec_cmpne_or_0_idx(vector signed short __a, vector signed short __b) { + return (vector signed short) + __builtin_s390_vfenezh((vector unsigned short)__a, + (vector unsigned short)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpne_or_0_idx(vector bool short __a, vector bool short __b) { + return __builtin_s390_vfenezh((vector unsigned short)__a, + (vector unsigned short)__b); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpne_or_0_idx(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vfenezh(__a, __b); +} + +static inline __ATTRS_o_ai vector signed int +vec_cmpne_or_0_idx(vector signed int __a, vector signed int __b) { + return (vector signed int) + __builtin_s390_vfenezf((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpne_or_0_idx(vector bool int __a, vector bool int __b) { + return __builtin_s390_vfenezf((vector unsigned int)__a, + (vector unsigned int)__b); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpne_or_0_idx(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vfenezf(__a, __b); +} + +/*-- vec_cmpne_or_0_idx_cc --------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_cmpne_or_0_idx_cc(vector signed char __a, vector signed char __b, + int *__cc) { + return (vector signed char) + __builtin_s390_vfenezbs((vector unsigned char)__a, + (vector unsigned char)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpne_or_0_idx_cc(vector bool char __a, vector bool char __b, int *__cc) { + return __builtin_s390_vfenezbs((vector unsigned char)__a, + (vector unsigned char)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpne_or_0_idx_cc(vector unsigned char __a, vector unsigned char __b, + int *__cc) { + return __builtin_s390_vfenezbs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector signed short +vec_cmpne_or_0_idx_cc(vector signed short __a, vector signed short __b, + int *__cc) { + return (vector signed short) + __builtin_s390_vfenezhs((vector unsigned short)__a, + (vector unsigned short)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpne_or_0_idx_cc(vector bool short __a, vector bool short __b, int *__cc) { + return __builtin_s390_vfenezhs((vector unsigned short)__a, + (vector unsigned short)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpne_or_0_idx_cc(vector unsigned short __a, vector unsigned short __b, + int *__cc) { + return __builtin_s390_vfenezhs(__a, __b, __cc); +} + +static inline __ATTRS_o_ai vector signed int +vec_cmpne_or_0_idx_cc(vector signed int __a, vector signed int __b, int *__cc) { + return (vector signed int) + __builtin_s390_vfenezfs((vector unsigned int)__a, + (vector unsigned int)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpne_or_0_idx_cc(vector bool int __a, vector bool int __b, int *__cc) { + return __builtin_s390_vfenezfs((vector unsigned int)__a, + (vector unsigned int)__b, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpne_or_0_idx_cc(vector unsigned int __a, vector unsigned int __b, + int *__cc) { + return __builtin_s390_vfenezfs(__a, __b, __cc); +} + +/*-- vec_cmprg --------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_cmprg(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return (vector bool char)__builtin_s390_vstrcb(__a, __b, __c, 4); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmprg(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c) { + return (vector bool short)__builtin_s390_vstrch(__a, __b, __c, 4); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmprg(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c) { + return (vector bool int)__builtin_s390_vstrcf(__a, __b, __c, 4); +} + +/*-- vec_cmprg_cc -----------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_cmprg_cc(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c, int *__cc) { + return (vector bool char)__builtin_s390_vstrcbs(__a, __b, __c, 4, __cc); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmprg_cc(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c, int *__cc) { + return (vector bool short)__builtin_s390_vstrchs(__a, __b, __c, 4, __cc); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmprg_cc(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c, int *__cc) { + return (vector bool int)__builtin_s390_vstrcfs(__a, __b, __c, 4, __cc); +} + +/*-- vec_cmprg_idx ----------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_cmprg_idx(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return __builtin_s390_vstrcb(__a, __b, __c, 0); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmprg_idx(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c) { + return __builtin_s390_vstrch(__a, __b, __c, 0); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmprg_idx(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c) { + return __builtin_s390_vstrcf(__a, __b, __c, 0); +} + +/*-- vec_cmprg_idx_cc -------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_cmprg_idx_cc(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c, int *__cc) { + return __builtin_s390_vstrcbs(__a, __b, __c, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmprg_idx_cc(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c, int *__cc) { + return __builtin_s390_vstrchs(__a, __b, __c, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmprg_idx_cc(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c, int *__cc) { + return __builtin_s390_vstrcfs(__a, __b, __c, 0, __cc); +} + +/*-- vec_cmprg_or_0_idx -----------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_cmprg_or_0_idx(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return __builtin_s390_vstrczb(__a, __b, __c, 0); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmprg_or_0_idx(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c) { + return __builtin_s390_vstrczh(__a, __b, __c, 0); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmprg_or_0_idx(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c) { + return __builtin_s390_vstrczf(__a, __b, __c, 0); +} + +/*-- vec_cmprg_or_0_idx_cc --------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_cmprg_or_0_idx_cc(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c, int *__cc) { + return __builtin_s390_vstrczbs(__a, __b, __c, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmprg_or_0_idx_cc(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c, int *__cc) { + return __builtin_s390_vstrczhs(__a, __b, __c, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmprg_or_0_idx_cc(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c, int *__cc) { + return __builtin_s390_vstrczfs(__a, __b, __c, 0, __cc); +} + +/*-- vec_cmpnrg -------------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_cmpnrg(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return (vector bool char)__builtin_s390_vstrcb(__a, __b, __c, 12); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmpnrg(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c) { + return (vector bool short)__builtin_s390_vstrch(__a, __b, __c, 12); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmpnrg(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c) { + return (vector bool int)__builtin_s390_vstrcf(__a, __b, __c, 12); +} + +/*-- vec_cmpnrg_cc ----------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_cmpnrg_cc(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c, int *__cc) { + return (vector bool char)__builtin_s390_vstrcbs(__a, __b, __c, 12, __cc); +} + +static inline __ATTRS_o_ai vector bool short +vec_cmpnrg_cc(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c, int *__cc) { + return (vector bool short)__builtin_s390_vstrchs(__a, __b, __c, 12, __cc); +} + +static inline __ATTRS_o_ai vector bool int +vec_cmpnrg_cc(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c, int *__cc) { + return (vector bool int)__builtin_s390_vstrcfs(__a, __b, __c, 12, __cc); +} + +/*-- vec_cmpnrg_idx ---------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpnrg_idx(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return __builtin_s390_vstrcb(__a, __b, __c, 8); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpnrg_idx(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c) { + return __builtin_s390_vstrch(__a, __b, __c, 8); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpnrg_idx(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c) { + return __builtin_s390_vstrcf(__a, __b, __c, 8); +} + +/*-- vec_cmpnrg_idx_cc ------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpnrg_idx_cc(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c, int *__cc) { + return __builtin_s390_vstrcbs(__a, __b, __c, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpnrg_idx_cc(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c, int *__cc) { + return __builtin_s390_vstrchs(__a, __b, __c, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpnrg_idx_cc(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c, int *__cc) { + return __builtin_s390_vstrcfs(__a, __b, __c, 8, __cc); +} + +/*-- vec_cmpnrg_or_0_idx ----------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpnrg_or_0_idx(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return __builtin_s390_vstrczb(__a, __b, __c, 8); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpnrg_or_0_idx(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c) { + return __builtin_s390_vstrczh(__a, __b, __c, 8); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpnrg_or_0_idx(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c) { + return __builtin_s390_vstrczf(__a, __b, __c, 8); +} + +/*-- vec_cmpnrg_or_0_idx_cc -------------------------------------------------*/ + +static inline __ATTRS_o_ai vector unsigned char +vec_cmpnrg_or_0_idx_cc(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c, int *__cc) { + return __builtin_s390_vstrczbs(__a, __b, __c, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_cmpnrg_or_0_idx_cc(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c, int *__cc) { + return __builtin_s390_vstrczhs(__a, __b, __c, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_cmpnrg_or_0_idx_cc(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c, int *__cc) { + return __builtin_s390_vstrczfs(__a, __b, __c, 8, __cc); +} + +/*-- vec_find_any_eq --------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_find_any_eq(vector signed char __a, vector signed char __b) { + return (vector bool char) + __builtin_s390_vfaeb((vector unsigned char)__a, + (vector unsigned char)__b, 4); +} + +static inline __ATTRS_o_ai vector bool char +vec_find_any_eq(vector bool char __a, vector bool char __b) { + return (vector bool char) + __builtin_s390_vfaeb((vector unsigned char)__a, + (vector unsigned char)__b, 4); +} + +static inline __ATTRS_o_ai vector bool char +vec_find_any_eq(vector unsigned char __a, vector unsigned char __b) { + return (vector bool char)__builtin_s390_vfaeb(__a, __b, 4); +} + +static inline __ATTRS_o_ai vector bool short +vec_find_any_eq(vector signed short __a, vector signed short __b) { + return (vector bool short) + __builtin_s390_vfaeh((vector unsigned short)__a, + (vector unsigned short)__b, 4); +} + +static inline __ATTRS_o_ai vector bool short +vec_find_any_eq(vector bool short __a, vector bool short __b) { + return (vector bool short) + __builtin_s390_vfaeh((vector unsigned short)__a, + (vector unsigned short)__b, 4); +} + +static inline __ATTRS_o_ai vector bool short +vec_find_any_eq(vector unsigned short __a, vector unsigned short __b) { + return (vector bool short)__builtin_s390_vfaeh(__a, __b, 4); +} + +static inline __ATTRS_o_ai vector bool int +vec_find_any_eq(vector signed int __a, vector signed int __b) { + return (vector bool int) + __builtin_s390_vfaef((vector unsigned int)__a, + (vector unsigned int)__b, 4); +} + +static inline __ATTRS_o_ai vector bool int +vec_find_any_eq(vector bool int __a, vector bool int __b) { + return (vector bool int) + __builtin_s390_vfaef((vector unsigned int)__a, + (vector unsigned int)__b, 4); +} + +static inline __ATTRS_o_ai vector bool int +vec_find_any_eq(vector unsigned int __a, vector unsigned int __b) { + return (vector bool int)__builtin_s390_vfaef(__a, __b, 4); +} + +/*-- vec_find_any_eq_cc -----------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_find_any_eq_cc(vector signed char __a, vector signed char __b, int *__cc) { + return (vector bool char) + __builtin_s390_vfaebs((vector unsigned char)__a, + (vector unsigned char)__b, 4, __cc); +} + +static inline __ATTRS_o_ai vector bool char +vec_find_any_eq_cc(vector bool char __a, vector bool char __b, int *__cc) { + return (vector bool char) + __builtin_s390_vfaebs((vector unsigned char)__a, + (vector unsigned char)__b, 4, __cc); +} + +static inline __ATTRS_o_ai vector bool char +vec_find_any_eq_cc(vector unsigned char __a, vector unsigned char __b, + int *__cc) { + return (vector bool char)__builtin_s390_vfaebs(__a, __b, 4, __cc); +} + +static inline __ATTRS_o_ai vector bool short +vec_find_any_eq_cc(vector signed short __a, vector signed short __b, + int *__cc) { + return (vector bool short) + __builtin_s390_vfaehs((vector unsigned short)__a, + (vector unsigned short)__b, 4, __cc); +} + +static inline __ATTRS_o_ai vector bool short +vec_find_any_eq_cc(vector bool short __a, vector bool short __b, int *__cc) { + return (vector bool short) + __builtin_s390_vfaehs((vector unsigned short)__a, + (vector unsigned short)__b, 4, __cc); +} + +static inline __ATTRS_o_ai vector bool short +vec_find_any_eq_cc(vector unsigned short __a, vector unsigned short __b, + int *__cc) { + return (vector bool short)__builtin_s390_vfaehs(__a, __b, 4, __cc); +} + +static inline __ATTRS_o_ai vector bool int +vec_find_any_eq_cc(vector signed int __a, vector signed int __b, int *__cc) { + return (vector bool int) + __builtin_s390_vfaefs((vector unsigned int)__a, + (vector unsigned int)__b, 4, __cc); +} + +static inline __ATTRS_o_ai vector bool int +vec_find_any_eq_cc(vector bool int __a, vector bool int __b, int *__cc) { + return (vector bool int) + __builtin_s390_vfaefs((vector unsigned int)__a, + (vector unsigned int)__b, 4, __cc); +} + +static inline __ATTRS_o_ai vector bool int +vec_find_any_eq_cc(vector unsigned int __a, vector unsigned int __b, + int *__cc) { + return (vector bool int)__builtin_s390_vfaefs(__a, __b, 4, __cc); +} + +/*-- vec_find_any_eq_idx ----------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_find_any_eq_idx(vector signed char __a, vector signed char __b) { + return (vector signed char) + __builtin_s390_vfaeb((vector unsigned char)__a, + (vector unsigned char)__b, 0); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_eq_idx(vector bool char __a, vector bool char __b) { + return __builtin_s390_vfaeb((vector unsigned char)__a, + (vector unsigned char)__b, 0); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_eq_idx(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vfaeb(__a, __b, 0); +} + +static inline __ATTRS_o_ai vector signed short +vec_find_any_eq_idx(vector signed short __a, vector signed short __b) { + return (vector signed short) + __builtin_s390_vfaeh((vector unsigned short)__a, + (vector unsigned short)__b, 0); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_eq_idx(vector bool short __a, vector bool short __b) { + return __builtin_s390_vfaeh((vector unsigned short)__a, + (vector unsigned short)__b, 0); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_eq_idx(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vfaeh(__a, __b, 0); +} + +static inline __ATTRS_o_ai vector signed int +vec_find_any_eq_idx(vector signed int __a, vector signed int __b) { + return (vector signed int) + __builtin_s390_vfaef((vector unsigned int)__a, + (vector unsigned int)__b, 0); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_eq_idx(vector bool int __a, vector bool int __b) { + return __builtin_s390_vfaef((vector unsigned int)__a, + (vector unsigned int)__b, 0); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_eq_idx(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vfaef(__a, __b, 0); +} + +/*-- vec_find_any_eq_idx_cc -------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_find_any_eq_idx_cc(vector signed char __a, vector signed char __b, + int *__cc) { + return (vector signed char) + __builtin_s390_vfaebs((vector unsigned char)__a, + (vector unsigned char)__b, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_eq_idx_cc(vector bool char __a, vector bool char __b, int *__cc) { + return __builtin_s390_vfaebs((vector unsigned char)__a, + (vector unsigned char)__b, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_eq_idx_cc(vector unsigned char __a, vector unsigned char __b, + int *__cc) { + return __builtin_s390_vfaebs(__a, __b, 0, __cc); +} + +static inline __ATTRS_o_ai vector signed short +vec_find_any_eq_idx_cc(vector signed short __a, vector signed short __b, + int *__cc) { + return (vector signed short) + __builtin_s390_vfaehs((vector unsigned short)__a, + (vector unsigned short)__b, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_eq_idx_cc(vector bool short __a, vector bool short __b, + int *__cc) { + return __builtin_s390_vfaehs((vector unsigned short)__a, + (vector unsigned short)__b, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_eq_idx_cc(vector unsigned short __a, vector unsigned short __b, + int *__cc) { + return __builtin_s390_vfaehs(__a, __b, 0, __cc); +} + +static inline __ATTRS_o_ai vector signed int +vec_find_any_eq_idx_cc(vector signed int __a, vector signed int __b, + int *__cc) { + return (vector signed int) + __builtin_s390_vfaefs((vector unsigned int)__a, + (vector unsigned int)__b, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_eq_idx_cc(vector bool int __a, vector bool int __b, int *__cc) { + return __builtin_s390_vfaefs((vector unsigned int)__a, + (vector unsigned int)__b, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_eq_idx_cc(vector unsigned int __a, vector unsigned int __b, + int *__cc) { + return __builtin_s390_vfaefs(__a, __b, 0, __cc); +} + +/*-- vec_find_any_eq_or_0_idx -----------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_find_any_eq_or_0_idx(vector signed char __a, vector signed char __b) { + return (vector signed char) + __builtin_s390_vfaezb((vector unsigned char)__a, + (vector unsigned char)__b, 0); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_eq_or_0_idx(vector bool char __a, vector bool char __b) { + return __builtin_s390_vfaezb((vector unsigned char)__a, + (vector unsigned char)__b, 0); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_eq_or_0_idx(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vfaezb(__a, __b, 0); +} + +static inline __ATTRS_o_ai vector signed short +vec_find_any_eq_or_0_idx(vector signed short __a, vector signed short __b) { + return (vector signed short) + __builtin_s390_vfaezh((vector unsigned short)__a, + (vector unsigned short)__b, 0); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_eq_or_0_idx(vector bool short __a, vector bool short __b) { + return __builtin_s390_vfaezh((vector unsigned short)__a, + (vector unsigned short)__b, 0); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_eq_or_0_idx(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vfaezh(__a, __b, 0); +} + +static inline __ATTRS_o_ai vector signed int +vec_find_any_eq_or_0_idx(vector signed int __a, vector signed int __b) { + return (vector signed int) + __builtin_s390_vfaezf((vector unsigned int)__a, + (vector unsigned int)__b, 0); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_eq_or_0_idx(vector bool int __a, vector bool int __b) { + return __builtin_s390_vfaezf((vector unsigned int)__a, + (vector unsigned int)__b, 0); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_eq_or_0_idx(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vfaezf(__a, __b, 0); +} + +/*-- vec_find_any_eq_or_0_idx_cc --------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_find_any_eq_or_0_idx_cc(vector signed char __a, vector signed char __b, + int *__cc) { + return (vector signed char) + __builtin_s390_vfaezbs((vector unsigned char)__a, + (vector unsigned char)__b, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_eq_or_0_idx_cc(vector bool char __a, vector bool char __b, + int *__cc) { + return __builtin_s390_vfaezbs((vector unsigned char)__a, + (vector unsigned char)__b, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_eq_or_0_idx_cc(vector unsigned char __a, vector unsigned char __b, + int *__cc) { + return __builtin_s390_vfaezbs(__a, __b, 0, __cc); +} + +static inline __ATTRS_o_ai vector signed short +vec_find_any_eq_or_0_idx_cc(vector signed short __a, vector signed short __b, + int *__cc) { + return (vector signed short) + __builtin_s390_vfaezhs((vector unsigned short)__a, + (vector unsigned short)__b, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_eq_or_0_idx_cc(vector bool short __a, vector bool short __b, + int *__cc) { + return __builtin_s390_vfaezhs((vector unsigned short)__a, + (vector unsigned short)__b, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_eq_or_0_idx_cc(vector unsigned short __a, + vector unsigned short __b, int *__cc) { + return __builtin_s390_vfaezhs(__a, __b, 0, __cc); +} + +static inline __ATTRS_o_ai vector signed int +vec_find_any_eq_or_0_idx_cc(vector signed int __a, vector signed int __b, + int *__cc) { + return (vector signed int) + __builtin_s390_vfaezfs((vector unsigned int)__a, + (vector unsigned int)__b, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_eq_or_0_idx_cc(vector bool int __a, vector bool int __b, + int *__cc) { + return __builtin_s390_vfaezfs((vector unsigned int)__a, + (vector unsigned int)__b, 0, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_eq_or_0_idx_cc(vector unsigned int __a, vector unsigned int __b, + int *__cc) { + return __builtin_s390_vfaezfs(__a, __b, 0, __cc); +} + +/*-- vec_find_any_ne --------------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_find_any_ne(vector signed char __a, vector signed char __b) { + return (vector bool char) + __builtin_s390_vfaeb((vector unsigned char)__a, + (vector unsigned char)__b, 12); +} + +static inline __ATTRS_o_ai vector bool char +vec_find_any_ne(vector bool char __a, vector bool char __b) { + return (vector bool char) + __builtin_s390_vfaeb((vector unsigned char)__a, + (vector unsigned char)__b, 12); +} + +static inline __ATTRS_o_ai vector bool char +vec_find_any_ne(vector unsigned char __a, vector unsigned char __b) { + return (vector bool char)__builtin_s390_vfaeb(__a, __b, 12); +} + +static inline __ATTRS_o_ai vector bool short +vec_find_any_ne(vector signed short __a, vector signed short __b) { + return (vector bool short) + __builtin_s390_vfaeh((vector unsigned short)__a, + (vector unsigned short)__b, 12); +} + +static inline __ATTRS_o_ai vector bool short +vec_find_any_ne(vector bool short __a, vector bool short __b) { + return (vector bool short) + __builtin_s390_vfaeh((vector unsigned short)__a, + (vector unsigned short)__b, 12); +} + +static inline __ATTRS_o_ai vector bool short +vec_find_any_ne(vector unsigned short __a, vector unsigned short __b) { + return (vector bool short)__builtin_s390_vfaeh(__a, __b, 12); +} + +static inline __ATTRS_o_ai vector bool int +vec_find_any_ne(vector signed int __a, vector signed int __b) { + return (vector bool int) + __builtin_s390_vfaef((vector unsigned int)__a, + (vector unsigned int)__b, 12); +} + +static inline __ATTRS_o_ai vector bool int +vec_find_any_ne(vector bool int __a, vector bool int __b) { + return (vector bool int) + __builtin_s390_vfaef((vector unsigned int)__a, + (vector unsigned int)__b, 12); +} + +static inline __ATTRS_o_ai vector bool int +vec_find_any_ne(vector unsigned int __a, vector unsigned int __b) { + return (vector bool int)__builtin_s390_vfaef(__a, __b, 12); +} + +/*-- vec_find_any_ne_cc -----------------------------------------------------*/ + +static inline __ATTRS_o_ai vector bool char +vec_find_any_ne_cc(vector signed char __a, vector signed char __b, int *__cc) { + return (vector bool char) + __builtin_s390_vfaebs((vector unsigned char)__a, + (vector unsigned char)__b, 12, __cc); +} + +static inline __ATTRS_o_ai vector bool char +vec_find_any_ne_cc(vector bool char __a, vector bool char __b, int *__cc) { + return (vector bool char) + __builtin_s390_vfaebs((vector unsigned char)__a, + (vector unsigned char)__b, 12, __cc); +} + +static inline __ATTRS_o_ai vector bool char +vec_find_any_ne_cc(vector unsigned char __a, vector unsigned char __b, + int *__cc) { + return (vector bool char)__builtin_s390_vfaebs(__a, __b, 12, __cc); +} + +static inline __ATTRS_o_ai vector bool short +vec_find_any_ne_cc(vector signed short __a, vector signed short __b, + int *__cc) { + return (vector bool short) + __builtin_s390_vfaehs((vector unsigned short)__a, + (vector unsigned short)__b, 12, __cc); +} + +static inline __ATTRS_o_ai vector bool short +vec_find_any_ne_cc(vector bool short __a, vector bool short __b, int *__cc) { + return (vector bool short) + __builtin_s390_vfaehs((vector unsigned short)__a, + (vector unsigned short)__b, 12, __cc); +} + +static inline __ATTRS_o_ai vector bool short +vec_find_any_ne_cc(vector unsigned short __a, vector unsigned short __b, + int *__cc) { + return (vector bool short)__builtin_s390_vfaehs(__a, __b, 12, __cc); +} + +static inline __ATTRS_o_ai vector bool int +vec_find_any_ne_cc(vector signed int __a, vector signed int __b, int *__cc) { + return (vector bool int) + __builtin_s390_vfaefs((vector unsigned int)__a, + (vector unsigned int)__b, 12, __cc); +} + +static inline __ATTRS_o_ai vector bool int +vec_find_any_ne_cc(vector bool int __a, vector bool int __b, int *__cc) { + return (vector bool int) + __builtin_s390_vfaefs((vector unsigned int)__a, + (vector unsigned int)__b, 12, __cc); +} + +static inline __ATTRS_o_ai vector bool int +vec_find_any_ne_cc(vector unsigned int __a, vector unsigned int __b, + int *__cc) { + return (vector bool int)__builtin_s390_vfaefs(__a, __b, 12, __cc); +} + +/*-- vec_find_any_ne_idx ----------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_find_any_ne_idx(vector signed char __a, vector signed char __b) { + return (vector signed char) + __builtin_s390_vfaeb((vector unsigned char)__a, + (vector unsigned char)__b, 8); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_ne_idx(vector bool char __a, vector bool char __b) { + return __builtin_s390_vfaeb((vector unsigned char)__a, + (vector unsigned char)__b, 8); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_ne_idx(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vfaeb(__a, __b, 8); +} + +static inline __ATTRS_o_ai vector signed short +vec_find_any_ne_idx(vector signed short __a, vector signed short __b) { + return (vector signed short) + __builtin_s390_vfaeh((vector unsigned short)__a, + (vector unsigned short)__b, 8); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_ne_idx(vector bool short __a, vector bool short __b) { + return __builtin_s390_vfaeh((vector unsigned short)__a, + (vector unsigned short)__b, 8); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_ne_idx(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vfaeh(__a, __b, 8); +} + +static inline __ATTRS_o_ai vector signed int +vec_find_any_ne_idx(vector signed int __a, vector signed int __b) { + return (vector signed int) + __builtin_s390_vfaef((vector unsigned int)__a, + (vector unsigned int)__b, 8); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_ne_idx(vector bool int __a, vector bool int __b) { + return __builtin_s390_vfaef((vector unsigned int)__a, + (vector unsigned int)__b, 8); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_ne_idx(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vfaef(__a, __b, 8); +} + +/*-- vec_find_any_ne_idx_cc -------------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_find_any_ne_idx_cc(vector signed char __a, vector signed char __b, + int *__cc) { + return (vector signed char) + __builtin_s390_vfaebs((vector unsigned char)__a, + (vector unsigned char)__b, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_ne_idx_cc(vector bool char __a, vector bool char __b, int *__cc) { + return __builtin_s390_vfaebs((vector unsigned char)__a, + (vector unsigned char)__b, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_ne_idx_cc(vector unsigned char __a, vector unsigned char __b, + int *__cc) { + return __builtin_s390_vfaebs(__a, __b, 8, __cc); +} + +static inline __ATTRS_o_ai vector signed short +vec_find_any_ne_idx_cc(vector signed short __a, vector signed short __b, + int *__cc) { + return (vector signed short) + __builtin_s390_vfaehs((vector unsigned short)__a, + (vector unsigned short)__b, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_ne_idx_cc(vector bool short __a, vector bool short __b, + int *__cc) { + return __builtin_s390_vfaehs((vector unsigned short)__a, + (vector unsigned short)__b, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_ne_idx_cc(vector unsigned short __a, vector unsigned short __b, + int *__cc) { + return __builtin_s390_vfaehs(__a, __b, 8, __cc); +} + +static inline __ATTRS_o_ai vector signed int +vec_find_any_ne_idx_cc(vector signed int __a, vector signed int __b, + int *__cc) { + return (vector signed int) + __builtin_s390_vfaefs((vector unsigned int)__a, + (vector unsigned int)__b, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_ne_idx_cc(vector bool int __a, vector bool int __b, int *__cc) { + return __builtin_s390_vfaefs((vector unsigned int)__a, + (vector unsigned int)__b, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_ne_idx_cc(vector unsigned int __a, vector unsigned int __b, + int *__cc) { + return __builtin_s390_vfaefs(__a, __b, 8, __cc); +} + +/*-- vec_find_any_ne_or_0_idx -----------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_find_any_ne_or_0_idx(vector signed char __a, vector signed char __b) { + return (vector signed char) + __builtin_s390_vfaezb((vector unsigned char)__a, + (vector unsigned char)__b, 8); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_ne_or_0_idx(vector bool char __a, vector bool char __b) { + return __builtin_s390_vfaezb((vector unsigned char)__a, + (vector unsigned char)__b, 8); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_ne_or_0_idx(vector unsigned char __a, vector unsigned char __b) { + return __builtin_s390_vfaezb(__a, __b, 8); +} + +static inline __ATTRS_o_ai vector signed short +vec_find_any_ne_or_0_idx(vector signed short __a, vector signed short __b) { + return (vector signed short) + __builtin_s390_vfaezh((vector unsigned short)__a, + (vector unsigned short)__b, 8); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_ne_or_0_idx(vector bool short __a, vector bool short __b) { + return __builtin_s390_vfaezh((vector unsigned short)__a, + (vector unsigned short)__b, 8); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_ne_or_0_idx(vector unsigned short __a, vector unsigned short __b) { + return __builtin_s390_vfaezh(__a, __b, 8); +} + +static inline __ATTRS_o_ai vector signed int +vec_find_any_ne_or_0_idx(vector signed int __a, vector signed int __b) { + return (vector signed int) + __builtin_s390_vfaezf((vector unsigned int)__a, + (vector unsigned int)__b, 8); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_ne_or_0_idx(vector bool int __a, vector bool int __b) { + return __builtin_s390_vfaezf((vector unsigned int)__a, + (vector unsigned int)__b, 8); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_ne_or_0_idx(vector unsigned int __a, vector unsigned int __b) { + return __builtin_s390_vfaezf(__a, __b, 8); +} + +/*-- vec_find_any_ne_or_0_idx_cc --------------------------------------------*/ + +static inline __ATTRS_o_ai vector signed char +vec_find_any_ne_or_0_idx_cc(vector signed char __a, vector signed char __b, + int *__cc) { + return (vector signed char) + __builtin_s390_vfaezbs((vector unsigned char)__a, + (vector unsigned char)__b, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_ne_or_0_idx_cc(vector bool char __a, vector bool char __b, + int *__cc) { + return __builtin_s390_vfaezbs((vector unsigned char)__a, + (vector unsigned char)__b, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned char +vec_find_any_ne_or_0_idx_cc(vector unsigned char __a, vector unsigned char __b, + int *__cc) { + return __builtin_s390_vfaezbs(__a, __b, 8, __cc); +} + +static inline __ATTRS_o_ai vector signed short +vec_find_any_ne_or_0_idx_cc(vector signed short __a, vector signed short __b, + int *__cc) { + return (vector signed short) + __builtin_s390_vfaezhs((vector unsigned short)__a, + (vector unsigned short)__b, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_ne_or_0_idx_cc(vector bool short __a, vector bool short __b, + int *__cc) { + return __builtin_s390_vfaezhs((vector unsigned short)__a, + (vector unsigned short)__b, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned short +vec_find_any_ne_or_0_idx_cc(vector unsigned short __a, + vector unsigned short __b, int *__cc) { + return __builtin_s390_vfaezhs(__a, __b, 8, __cc); +} + +static inline __ATTRS_o_ai vector signed int +vec_find_any_ne_or_0_idx_cc(vector signed int __a, vector signed int __b, + int *__cc) { + return (vector signed int) + __builtin_s390_vfaezfs((vector unsigned int)__a, + (vector unsigned int)__b, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_ne_or_0_idx_cc(vector bool int __a, vector bool int __b, + int *__cc) { + return __builtin_s390_vfaezfs((vector unsigned int)__a, + (vector unsigned int)__b, 8, __cc); +} + +static inline __ATTRS_o_ai vector unsigned int +vec_find_any_ne_or_0_idx_cc(vector unsigned int __a, vector unsigned int __b, + int *__cc) { + return __builtin_s390_vfaezfs(__a, __b, 8, __cc); +} + +#undef __constant_pow2_range +#undef __constant_range +#undef __constant +#undef __ATTRS_o +#undef __ATTRS_o_ai +#undef __ATTRS_ai + +#else + +#error "Use -fzvector to enable vector extensions" + +#endif diff --git a/headers/clang/wmmintrin.h b/headers/clang/wmmintrin.h new file mode 100644 index 0000000000..a2d931010a --- /dev/null +++ b/headers/clang/wmmintrin.h @@ -0,0 +1,33 @@ +/*===---- wmmintrin.h - AES intrinsics ------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef _WMMINTRIN_H +#define _WMMINTRIN_H + +#include + +#include <__wmmintrin_aes.h> + +#include <__wmmintrin_pclmul.h> + +#endif /* _WMMINTRIN_H */ diff --git a/headers/clang/x86intrin.h b/headers/clang/x86intrin.h new file mode 100644 index 0000000000..4d8077e382 --- /dev/null +++ b/headers/clang/x86intrin.h @@ -0,0 +1,57 @@ +/*===---- x86intrin.h - X86 intrinsics -------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __X86INTRIN_H +#define __X86INTRIN_H + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +/* FIXME: LWP */ + +#endif /* __X86INTRIN_H */ diff --git a/headers/clang/xmmintrin.h b/headers/clang/xmmintrin.h new file mode 100644 index 0000000000..06c2e245a1 --- /dev/null +++ b/headers/clang/xmmintrin.h @@ -0,0 +1,1013 @@ +/*===---- xmmintrin.h - SSE intrinsics -------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __XMMINTRIN_H +#define __XMMINTRIN_H + +#include + +typedef int __v4si __attribute__((__vector_size__(16))); +typedef float __v4sf __attribute__((__vector_size__(16))); +typedef float __m128 __attribute__((__vector_size__(16))); + +/* This header should only be included in a hosted environment as it depends on + * a standard library to provide allocation routines. */ +#if __STDC_HOSTED__ +#include +#endif + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("sse"))) + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_add_ss(__m128 __a, __m128 __b) +{ + __a[0] += __b[0]; + return __a; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_add_ps(__m128 __a, __m128 __b) +{ + return __a + __b; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_sub_ss(__m128 __a, __m128 __b) +{ + __a[0] -= __b[0]; + return __a; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_sub_ps(__m128 __a, __m128 __b) +{ + return __a - __b; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mul_ss(__m128 __a, __m128 __b) +{ + __a[0] *= __b[0]; + return __a; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_mul_ps(__m128 __a, __m128 __b) +{ + return __a * __b; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_div_ss(__m128 __a, __m128 __b) +{ + __a[0] /= __b[0]; + return __a; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_div_ps(__m128 __a, __m128 __b) +{ + return __a / __b; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_sqrt_ss(__m128 __a) +{ + __m128 __c = __builtin_ia32_sqrtss(__a); + return (__m128) { __c[0], __a[1], __a[2], __a[3] }; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_sqrt_ps(__m128 __a) +{ + return __builtin_ia32_sqrtps(__a); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_rcp_ss(__m128 __a) +{ + __m128 __c = __builtin_ia32_rcpss(__a); + return (__m128) { __c[0], __a[1], __a[2], __a[3] }; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_rcp_ps(__m128 __a) +{ + return __builtin_ia32_rcpps(__a); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_rsqrt_ss(__m128 __a) +{ + __m128 __c = __builtin_ia32_rsqrtss(__a); + return (__m128) { __c[0], __a[1], __a[2], __a[3] }; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_rsqrt_ps(__m128 __a) +{ + return __builtin_ia32_rsqrtps(__a); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_min_ss(__m128 __a, __m128 __b) +{ + return __builtin_ia32_minss(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_min_ps(__m128 __a, __m128 __b) +{ + return __builtin_ia32_minps(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_max_ss(__m128 __a, __m128 __b) +{ + return __builtin_ia32_maxss(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_max_ps(__m128 __a, __m128 __b) +{ + return __builtin_ia32_maxps(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_and_ps(__m128 __a, __m128 __b) +{ + return (__m128)((__v4si)__a & (__v4si)__b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_andnot_ps(__m128 __a, __m128 __b) +{ + return (__m128)(~(__v4si)__a & (__v4si)__b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_or_ps(__m128 __a, __m128 __b) +{ + return (__m128)((__v4si)__a | (__v4si)__b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_xor_ps(__m128 __a, __m128 __b) +{ + return (__m128)((__v4si)__a ^ (__v4si)__b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpeq_ss(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpeqss(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpeq_ps(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpeqps(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmplt_ss(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpltss(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmplt_ps(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpltps(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmple_ss(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpless(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmple_ps(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpleps(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpgt_ss(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_shufflevector(__a, + __builtin_ia32_cmpltss(__b, __a), + 4, 1, 2, 3); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpgt_ps(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpltps(__b, __a); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpge_ss(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_shufflevector(__a, + __builtin_ia32_cmpless(__b, __a), + 4, 1, 2, 3); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpge_ps(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpleps(__b, __a); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpneq_ss(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpneqss(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpneq_ps(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpneqps(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpnlt_ss(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpnltss(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpnlt_ps(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpnltps(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpnle_ss(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpnless(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpnle_ps(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpnleps(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpngt_ss(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_shufflevector(__a, + __builtin_ia32_cmpnltss(__b, __a), + 4, 1, 2, 3); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpngt_ps(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpnltps(__b, __a); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpnge_ss(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_shufflevector(__a, + __builtin_ia32_cmpnless(__b, __a), + 4, 1, 2, 3); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpnge_ps(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpnleps(__b, __a); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpord_ss(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpordss(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpord_ps(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpordps(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpunord_ss(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpunordss(__a, __b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cmpunord_ps(__m128 __a, __m128 __b) +{ + return (__m128)__builtin_ia32_cmpunordps(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_comieq_ss(__m128 __a, __m128 __b) +{ + return __builtin_ia32_comieq(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_comilt_ss(__m128 __a, __m128 __b) +{ + return __builtin_ia32_comilt(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_comile_ss(__m128 __a, __m128 __b) +{ + return __builtin_ia32_comile(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_comigt_ss(__m128 __a, __m128 __b) +{ + return __builtin_ia32_comigt(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_comige_ss(__m128 __a, __m128 __b) +{ + return __builtin_ia32_comige(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_comineq_ss(__m128 __a, __m128 __b) +{ + return __builtin_ia32_comineq(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_ucomieq_ss(__m128 __a, __m128 __b) +{ + return __builtin_ia32_ucomieq(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_ucomilt_ss(__m128 __a, __m128 __b) +{ + return __builtin_ia32_ucomilt(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_ucomile_ss(__m128 __a, __m128 __b) +{ + return __builtin_ia32_ucomile(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_ucomigt_ss(__m128 __a, __m128 __b) +{ + return __builtin_ia32_ucomigt(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_ucomige_ss(__m128 __a, __m128 __b) +{ + return __builtin_ia32_ucomige(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_ucomineq_ss(__m128 __a, __m128 __b) +{ + return __builtin_ia32_ucomineq(__a, __b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_cvtss_si32(__m128 __a) +{ + return __builtin_ia32_cvtss2si(__a); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_cvt_ss2si(__m128 __a) +{ + return _mm_cvtss_si32(__a); +} + +#ifdef __x86_64__ + +static __inline__ long long __DEFAULT_FN_ATTRS +_mm_cvtss_si64(__m128 __a) +{ + return __builtin_ia32_cvtss2si64(__a); +} + +#endif + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cvtps_pi32(__m128 __a) +{ + return (__m64)__builtin_ia32_cvtps2pi(__a); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cvt_ps2pi(__m128 __a) +{ + return _mm_cvtps_pi32(__a); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_cvttss_si32(__m128 __a) +{ + return __a[0]; +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_cvtt_ss2si(__m128 __a) +{ + return _mm_cvttss_si32(__a); +} + +static __inline__ long long __DEFAULT_FN_ATTRS +_mm_cvttss_si64(__m128 __a) +{ + return __a[0]; +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cvttps_pi32(__m128 __a) +{ + return (__m64)__builtin_ia32_cvttps2pi(__a); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cvtt_ps2pi(__m128 __a) +{ + return _mm_cvttps_pi32(__a); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvtsi32_ss(__m128 __a, int __b) +{ + __a[0] = __b; + return __a; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvt_si2ss(__m128 __a, int __b) +{ + return _mm_cvtsi32_ss(__a, __b); +} + +#ifdef __x86_64__ + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvtsi64_ss(__m128 __a, long long __b) +{ + __a[0] = __b; + return __a; +} + +#endif + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvtpi32_ps(__m128 __a, __m64 __b) +{ + return __builtin_ia32_cvtpi2ps(__a, (__v2si)__b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvt_pi2ps(__m128 __a, __m64 __b) +{ + return _mm_cvtpi32_ps(__a, __b); +} + +static __inline__ float __DEFAULT_FN_ATTRS +_mm_cvtss_f32(__m128 __a) +{ + return __a[0]; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_loadh_pi(__m128 __a, const __m64 *__p) +{ + typedef float __mm_loadh_pi_v2f32 __attribute__((__vector_size__(8))); + struct __mm_loadh_pi_struct { + __mm_loadh_pi_v2f32 __u; + } __attribute__((__packed__, __may_alias__)); + __mm_loadh_pi_v2f32 __b = ((struct __mm_loadh_pi_struct*)__p)->__u; + __m128 __bb = __builtin_shufflevector(__b, __b, 0, 1, 0, 1); + return __builtin_shufflevector(__a, __bb, 0, 1, 4, 5); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_loadl_pi(__m128 __a, const __m64 *__p) +{ + typedef float __mm_loadl_pi_v2f32 __attribute__((__vector_size__(8))); + struct __mm_loadl_pi_struct { + __mm_loadl_pi_v2f32 __u; + } __attribute__((__packed__, __may_alias__)); + __mm_loadl_pi_v2f32 __b = ((struct __mm_loadl_pi_struct*)__p)->__u; + __m128 __bb = __builtin_shufflevector(__b, __b, 0, 1, 0, 1); + return __builtin_shufflevector(__a, __bb, 4, 5, 2, 3); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_load_ss(const float *__p) +{ + struct __mm_load_ss_struct { + float __u; + } __attribute__((__packed__, __may_alias__)); + float __u = ((struct __mm_load_ss_struct*)__p)->__u; + return (__m128){ __u, 0, 0, 0 }; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_load1_ps(const float *__p) +{ + struct __mm_load1_ps_struct { + float __u; + } __attribute__((__packed__, __may_alias__)); + float __u = ((struct __mm_load1_ps_struct*)__p)->__u; + return (__m128){ __u, __u, __u, __u }; +} + +#define _mm_load_ps1(p) _mm_load1_ps(p) + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_load_ps(const float *__p) +{ + return *(__m128*)__p; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_loadu_ps(const float *__p) +{ + struct __loadu_ps { + __m128 __v; + } __attribute__((__packed__, __may_alias__)); + return ((struct __loadu_ps*)__p)->__v; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_loadr_ps(const float *__p) +{ + __m128 __a = _mm_load_ps(__p); + return __builtin_shufflevector(__a, __a, 3, 2, 1, 0); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_undefined_ps() +{ + return (__m128)__builtin_ia32_undef128(); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_set_ss(float __w) +{ + return (__m128){ __w, 0, 0, 0 }; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_set1_ps(float __w) +{ + return (__m128){ __w, __w, __w, __w }; +} + +/* Microsoft specific. */ +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_set_ps1(float __w) +{ + return _mm_set1_ps(__w); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_set_ps(float __z, float __y, float __x, float __w) +{ + return (__m128){ __w, __x, __y, __z }; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_setr_ps(float __z, float __y, float __x, float __w) +{ + return (__m128){ __z, __y, __x, __w }; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_setzero_ps(void) +{ + return (__m128){ 0, 0, 0, 0 }; +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_storeh_pi(__m64 *__p, __m128 __a) +{ + __builtin_ia32_storehps((__v2si *)__p, __a); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_storel_pi(__m64 *__p, __m128 __a) +{ + __builtin_ia32_storelps((__v2si *)__p, __a); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_store_ss(float *__p, __m128 __a) +{ + struct __mm_store_ss_struct { + float __u; + } __attribute__((__packed__, __may_alias__)); + ((struct __mm_store_ss_struct*)__p)->__u = __a[0]; +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_storeu_ps(float *__p, __m128 __a) +{ + __builtin_ia32_storeups(__p, __a); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_store1_ps(float *__p, __m128 __a) +{ + __a = __builtin_shufflevector(__a, __a, 0, 0, 0, 0); + _mm_storeu_ps(__p, __a); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_store_ps1(float *__p, __m128 __a) +{ + return _mm_store1_ps(__p, __a); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_store_ps(float *__p, __m128 __a) +{ + *(__m128 *)__p = __a; +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_storer_ps(float *__p, __m128 __a) +{ + __a = __builtin_shufflevector(__a, __a, 3, 2, 1, 0); + _mm_store_ps(__p, __a); +} + +#define _MM_HINT_T0 3 +#define _MM_HINT_T1 2 +#define _MM_HINT_T2 1 +#define _MM_HINT_NTA 0 + +#ifndef _MSC_VER +/* FIXME: We have to #define this because "sel" must be a constant integer, and + Sema doesn't do any form of constant propagation yet. */ + +#define _mm_prefetch(a, sel) (__builtin_prefetch((void *)(a), 0, (sel))) +#endif + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_stream_pi(__m64 *__p, __m64 __a) +{ + __builtin_ia32_movntq(__p, __a); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_stream_ps(float *__p, __m128 __a) +{ + __builtin_ia32_movntps(__p, __a); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_sfence(void) +{ + __builtin_ia32_sfence(); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_extract_pi16(__m64 __a, int __n) +{ + __v4hi __b = (__v4hi)__a; + return (unsigned short)__b[__n & 3]; +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_insert_pi16(__m64 __a, int __d, int __n) +{ + __v4hi __b = (__v4hi)__a; + __b[__n & 3] = __d; + return (__m64)__b; +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_max_pi16(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_pmaxsw((__v4hi)__a, (__v4hi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_max_pu8(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_pmaxub((__v8qi)__a, (__v8qi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_min_pi16(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_pminsw((__v4hi)__a, (__v4hi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_min_pu8(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_pminub((__v8qi)__a, (__v8qi)__b); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_movemask_pi8(__m64 __a) +{ + return __builtin_ia32_pmovmskb((__v8qi)__a); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_mulhi_pu16(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_pmulhuw((__v4hi)__a, (__v4hi)__b); +} + +#define _mm_shuffle_pi16(a, n) __extension__ ({ \ + __m64 __a = (a); \ + (__m64)__builtin_ia32_pshufw((__v4hi)__a, (n)); }) + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_maskmove_si64(__m64 __d, __m64 __n, char *__p) +{ + __builtin_ia32_maskmovq((__v8qi)__d, (__v8qi)__n, __p); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_avg_pu8(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_pavgb((__v8qi)__a, (__v8qi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_avg_pu16(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_pavgw((__v4hi)__a, (__v4hi)__b); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_sad_pu8(__m64 __a, __m64 __b) +{ + return (__m64)__builtin_ia32_psadbw((__v8qi)__a, (__v8qi)__b); +} + +static __inline__ unsigned int __DEFAULT_FN_ATTRS +_mm_getcsr(void) +{ + return __builtin_ia32_stmxcsr(); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_mm_setcsr(unsigned int __i) +{ + __builtin_ia32_ldmxcsr(__i); +} + +#define _mm_shuffle_ps(a, b, mask) __extension__ ({ \ + __m128 __a = (a); \ + __m128 __b = (b); \ + (__m128)__builtin_shufflevector((__v4sf)__a, (__v4sf)__b, \ + (mask) & 0x3, ((mask) & 0xc) >> 2, \ + (((mask) & 0x30) >> 4) + 4, \ + (((mask) & 0xc0) >> 6) + 4); }) + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_unpackhi_ps(__m128 __a, __m128 __b) +{ + return __builtin_shufflevector(__a, __b, 2, 6, 3, 7); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_unpacklo_ps(__m128 __a, __m128 __b) +{ + return __builtin_shufflevector(__a, __b, 0, 4, 1, 5); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_move_ss(__m128 __a, __m128 __b) +{ + return __builtin_shufflevector(__a, __b, 4, 1, 2, 3); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_movehl_ps(__m128 __a, __m128 __b) +{ + return __builtin_shufflevector(__a, __b, 6, 7, 2, 3); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_movelh_ps(__m128 __a, __m128 __b) +{ + return __builtin_shufflevector(__a, __b, 0, 1, 4, 5); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvtpi16_ps(__m64 __a) +{ + __m64 __b, __c; + __m128 __r; + + __b = _mm_setzero_si64(); + __b = _mm_cmpgt_pi16(__b, __a); + __c = _mm_unpackhi_pi16(__a, __b); + __r = _mm_setzero_ps(); + __r = _mm_cvtpi32_ps(__r, __c); + __r = _mm_movelh_ps(__r, __r); + __c = _mm_unpacklo_pi16(__a, __b); + __r = _mm_cvtpi32_ps(__r, __c); + + return __r; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvtpu16_ps(__m64 __a) +{ + __m64 __b, __c; + __m128 __r; + + __b = _mm_setzero_si64(); + __c = _mm_unpackhi_pi16(__a, __b); + __r = _mm_setzero_ps(); + __r = _mm_cvtpi32_ps(__r, __c); + __r = _mm_movelh_ps(__r, __r); + __c = _mm_unpacklo_pi16(__a, __b); + __r = _mm_cvtpi32_ps(__r, __c); + + return __r; +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvtpi8_ps(__m64 __a) +{ + __m64 __b; + + __b = _mm_setzero_si64(); + __b = _mm_cmpgt_pi8(__b, __a); + __b = _mm_unpacklo_pi8(__a, __b); + + return _mm_cvtpi16_ps(__b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvtpu8_ps(__m64 __a) +{ + __m64 __b; + + __b = _mm_setzero_si64(); + __b = _mm_unpacklo_pi8(__a, __b); + + return _mm_cvtpi16_ps(__b); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_cvtpi32x2_ps(__m64 __a, __m64 __b) +{ + __m128 __c; + + __c = _mm_setzero_ps(); + __c = _mm_cvtpi32_ps(__c, __b); + __c = _mm_movelh_ps(__c, __c); + + return _mm_cvtpi32_ps(__c, __a); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cvtps_pi16(__m128 __a) +{ + __m64 __b, __c; + + __b = _mm_cvtps_pi32(__a); + __a = _mm_movehl_ps(__a, __a); + __c = _mm_cvtps_pi32(__a); + + return _mm_packs_pi32(__b, __c); +} + +static __inline__ __m64 __DEFAULT_FN_ATTRS +_mm_cvtps_pi8(__m128 __a) +{ + __m64 __b, __c; + + __b = _mm_cvtps_pi16(__a); + __c = _mm_setzero_si64(); + + return _mm_packs_pi16(__b, __c); +} + +static __inline__ int __DEFAULT_FN_ATTRS +_mm_movemask_ps(__m128 __a) +{ + return __builtin_ia32_movmskps(__a); +} + + +#ifdef _MSC_VER +#define _MM_ALIGN16 __declspec(align(16)) +#endif + +#define _MM_SHUFFLE(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w)) + +#define _MM_EXCEPT_INVALID (0x0001) +#define _MM_EXCEPT_DENORM (0x0002) +#define _MM_EXCEPT_DIV_ZERO (0x0004) +#define _MM_EXCEPT_OVERFLOW (0x0008) +#define _MM_EXCEPT_UNDERFLOW (0x0010) +#define _MM_EXCEPT_INEXACT (0x0020) +#define _MM_EXCEPT_MASK (0x003f) + +#define _MM_MASK_INVALID (0x0080) +#define _MM_MASK_DENORM (0x0100) +#define _MM_MASK_DIV_ZERO (0x0200) +#define _MM_MASK_OVERFLOW (0x0400) +#define _MM_MASK_UNDERFLOW (0x0800) +#define _MM_MASK_INEXACT (0x1000) +#define _MM_MASK_MASK (0x1f80) + +#define _MM_ROUND_NEAREST (0x0000) +#define _MM_ROUND_DOWN (0x2000) +#define _MM_ROUND_UP (0x4000) +#define _MM_ROUND_TOWARD_ZERO (0x6000) +#define _MM_ROUND_MASK (0x6000) + +#define _MM_FLUSH_ZERO_MASK (0x8000) +#define _MM_FLUSH_ZERO_ON (0x8000) +#define _MM_FLUSH_ZERO_OFF (0x0000) + +#define _MM_GET_EXCEPTION_MASK() (_mm_getcsr() & _MM_MASK_MASK) +#define _MM_GET_EXCEPTION_STATE() (_mm_getcsr() & _MM_EXCEPT_MASK) +#define _MM_GET_FLUSH_ZERO_MODE() (_mm_getcsr() & _MM_FLUSH_ZERO_MASK) +#define _MM_GET_ROUNDING_MODE() (_mm_getcsr() & _MM_ROUND_MASK) + +#define _MM_SET_EXCEPTION_MASK(x) (_mm_setcsr((_mm_getcsr() & ~_MM_MASK_MASK) | (x))) +#define _MM_SET_EXCEPTION_STATE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_EXCEPT_MASK) | (x))) +#define _MM_SET_FLUSH_ZERO_MODE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_FLUSH_ZERO_MASK) | (x))) +#define _MM_SET_ROUNDING_MODE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_ROUND_MASK) | (x))) + +#define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ +do { \ + __m128 tmp3, tmp2, tmp1, tmp0; \ + tmp0 = _mm_unpacklo_ps((row0), (row1)); \ + tmp2 = _mm_unpacklo_ps((row2), (row3)); \ + tmp1 = _mm_unpackhi_ps((row0), (row1)); \ + tmp3 = _mm_unpackhi_ps((row2), (row3)); \ + (row0) = _mm_movelh_ps(tmp0, tmp2); \ + (row1) = _mm_movehl_ps(tmp2, tmp0); \ + (row2) = _mm_movelh_ps(tmp1, tmp3); \ + (row3) = _mm_movehl_ps(tmp3, tmp1); \ +} while (0) + +/* Aliases for compatibility. */ +#define _m_pextrw _mm_extract_pi16 +#define _m_pinsrw _mm_insert_pi16 +#define _m_pmaxsw _mm_max_pi16 +#define _m_pmaxub _mm_max_pu8 +#define _m_pminsw _mm_min_pi16 +#define _m_pminub _mm_min_pu8 +#define _m_pmovmskb _mm_movemask_pi8 +#define _m_pmulhuw _mm_mulhi_pu16 +#define _m_pshufw _mm_shuffle_pi16 +#define _m_maskmovq _mm_maskmove_si64 +#define _m_pavgb _mm_avg_pu8 +#define _m_pavgw _mm_avg_pu16 +#define _m_psadbw _mm_sad_pu8 +#define _m_ _mm_ +#define _m_ _mm_ + +#undef __DEFAULT_FN_ATTRS + +/* Ugly hack for backwards-compatibility (compatible with gcc) */ +#if defined(__SSE2__) && !__has_feature(modules) +#include +#endif + +#endif /* __XMMINTRIN_H */ diff --git a/headers/clang/xopintrin.h b/headers/clang/xopintrin.h new file mode 100644 index 0000000000..86188bb29f --- /dev/null +++ b/headers/clang/xopintrin.h @@ -0,0 +1,803 @@ +/*===---- xopintrin.h - XOP intrinsics -------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __X86INTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __XOPINTRIN_H +#define __XOPINTRIN_H + +#include + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("xop"))) + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maccs_epi16(__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i)__builtin_ia32_vpmacssww((__v8hi)__A, (__v8hi)__B, (__v8hi)__C); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_macc_epi16(__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i)__builtin_ia32_vpmacsww((__v8hi)__A, (__v8hi)__B, (__v8hi)__C); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maccsd_epi16(__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i)__builtin_ia32_vpmacsswd((__v8hi)__A, (__v8hi)__B, (__v4si)__C); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maccd_epi16(__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i)__builtin_ia32_vpmacswd((__v8hi)__A, (__v8hi)__B, (__v4si)__C); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maccs_epi32(__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i)__builtin_ia32_vpmacssdd((__v4si)__A, (__v4si)__B, (__v4si)__C); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_macc_epi32(__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i)__builtin_ia32_vpmacsdd((__v4si)__A, (__v4si)__B, (__v4si)__C); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maccslo_epi32(__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i)__builtin_ia32_vpmacssdql((__v4si)__A, (__v4si)__B, (__v2di)__C); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_macclo_epi32(__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i)__builtin_ia32_vpmacsdql((__v4si)__A, (__v4si)__B, (__v2di)__C); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maccshi_epi32(__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i)__builtin_ia32_vpmacssdqh((__v4si)__A, (__v4si)__B, (__v2di)__C); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_macchi_epi32(__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i)__builtin_ia32_vpmacsdqh((__v4si)__A, (__v4si)__B, (__v2di)__C); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maddsd_epi16(__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i)__builtin_ia32_vpmadcsswd((__v8hi)__A, (__v8hi)__B, (__v4si)__C); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_maddd_epi16(__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i)__builtin_ia32_vpmadcswd((__v8hi)__A, (__v8hi)__B, (__v4si)__C); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_haddw_epi8(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphaddbw((__v16qi)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_haddd_epi8(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphaddbd((__v16qi)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_haddq_epi8(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphaddbq((__v16qi)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_haddd_epi16(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphaddwd((__v8hi)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_haddq_epi16(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphaddwq((__v8hi)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_haddq_epi32(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphadddq((__v4si)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_haddw_epu8(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphaddubw((__v16qi)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_haddd_epu8(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphaddubd((__v16qi)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_haddq_epu8(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphaddubq((__v16qi)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_haddd_epu16(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphadduwd((__v8hi)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_haddq_epu16(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphadduwq((__v8hi)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_haddq_epu32(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphaddudq((__v4si)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_hsubw_epi8(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphsubbw((__v16qi)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_hsubd_epi16(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphsubwd((__v8hi)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_hsubq_epi32(__m128i __A) +{ + return (__m128i)__builtin_ia32_vphsubdq((__v4si)__A); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_cmov_si128(__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i)__builtin_ia32_vpcmov(__A, __B, __C); +} + +static __inline__ __m256i __DEFAULT_FN_ATTRS +_mm256_cmov_si256(__m256i __A, __m256i __B, __m256i __C) +{ + return (__m256i)__builtin_ia32_vpcmov_256(__A, __B, __C); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_perm_epi8(__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i)__builtin_ia32_vpperm((__v16qi)__A, (__v16qi)__B, (__v16qi)__C); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_rot_epi8(__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_vprotb((__v16qi)__A, (__v16qi)__B); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_rot_epi16(__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_vprotw((__v8hi)__A, (__v8hi)__B); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_rot_epi32(__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_vprotd((__v4si)__A, (__v4si)__B); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_rot_epi64(__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_vprotq((__v2di)__A, (__v2di)__B); +} + +#define _mm_roti_epi8(A, N) __extension__ ({ \ + __m128i __A = (A); \ + (__m128i)__builtin_ia32_vprotbi((__v16qi)__A, (N)); }) + +#define _mm_roti_epi16(A, N) __extension__ ({ \ + __m128i __A = (A); \ + (__m128i)__builtin_ia32_vprotwi((__v8hi)__A, (N)); }) + +#define _mm_roti_epi32(A, N) __extension__ ({ \ + __m128i __A = (A); \ + (__m128i)__builtin_ia32_vprotdi((__v4si)__A, (N)); }) + +#define _mm_roti_epi64(A, N) __extension__ ({ \ + __m128i __A = (A); \ + (__m128i)__builtin_ia32_vprotqi((__v2di)__A, (N)); }) + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_shl_epi8(__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_vpshlb((__v16qi)__A, (__v16qi)__B); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_shl_epi16(__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_vpshlw((__v8hi)__A, (__v8hi)__B); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_shl_epi32(__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_vpshld((__v4si)__A, (__v4si)__B); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_shl_epi64(__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_vpshlq((__v2di)__A, (__v2di)__B); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sha_epi8(__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_vpshab((__v16qi)__A, (__v16qi)__B); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sha_epi16(__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_vpshaw((__v8hi)__A, (__v8hi)__B); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sha_epi32(__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_vpshad((__v4si)__A, (__v4si)__B); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_sha_epi64(__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_vpshaq((__v2di)__A, (__v2di)__B); +} + +#define _mm_com_epu8(A, B, N) __extension__ ({ \ + __m128i __A = (A); \ + __m128i __B = (B); \ + (__m128i)__builtin_ia32_vpcomub((__v16qi)__A, (__v16qi)__B, (N)); }) + +#define _mm_com_epu16(A, B, N) __extension__ ({ \ + __m128i __A = (A); \ + __m128i __B = (B); \ + (__m128i)__builtin_ia32_vpcomuw((__v8hi)__A, (__v8hi)__B, (N)); }) + +#define _mm_com_epu32(A, B, N) __extension__ ({ \ + __m128i __A = (A); \ + __m128i __B = (B); \ + (__m128i)__builtin_ia32_vpcomud((__v4si)__A, (__v4si)__B, (N)); }) + +#define _mm_com_epu64(A, B, N) __extension__ ({ \ + __m128i __A = (A); \ + __m128i __B = (B); \ + (__m128i)__builtin_ia32_vpcomuq((__v2di)__A, (__v2di)__B, (N)); }) + +#define _mm_com_epi8(A, B, N) __extension__ ({ \ + __m128i __A = (A); \ + __m128i __B = (B); \ + (__m128i)__builtin_ia32_vpcomb((__v16qi)__A, (__v16qi)__B, (N)); }) + +#define _mm_com_epi16(A, B, N) __extension__ ({ \ + __m128i __A = (A); \ + __m128i __B = (B); \ + (__m128i)__builtin_ia32_vpcomw((__v8hi)__A, (__v8hi)__B, (N)); }) + +#define _mm_com_epi32(A, B, N) __extension__ ({ \ + __m128i __A = (A); \ + __m128i __B = (B); \ + (__m128i)__builtin_ia32_vpcomd((__v4si)__A, (__v4si)__B, (N)); }) + +#define _mm_com_epi64(A, B, N) __extension__ ({ \ + __m128i __A = (A); \ + __m128i __B = (B); \ + (__m128i)__builtin_ia32_vpcomq((__v2di)__A, (__v2di)__B, (N)); }) + +#define _MM_PCOMCTRL_LT 0 +#define _MM_PCOMCTRL_LE 1 +#define _MM_PCOMCTRL_GT 2 +#define _MM_PCOMCTRL_GE 3 +#define _MM_PCOMCTRL_EQ 4 +#define _MM_PCOMCTRL_NEQ 5 +#define _MM_PCOMCTRL_FALSE 6 +#define _MM_PCOMCTRL_TRUE 7 + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comlt_epu8(__m128i __A, __m128i __B) +{ + return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_LT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comle_epu8(__m128i __A, __m128i __B) +{ + return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_LE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comgt_epu8(__m128i __A, __m128i __B) +{ + return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_GT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comge_epu8(__m128i __A, __m128i __B) +{ + return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_GE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comeq_epu8(__m128i __A, __m128i __B) +{ + return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_EQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comneq_epu8(__m128i __A, __m128i __B) +{ + return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_NEQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comfalse_epu8(__m128i __A, __m128i __B) +{ + return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_FALSE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comtrue_epu8(__m128i __A, __m128i __B) +{ + return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_TRUE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comlt_epu16(__m128i __A, __m128i __B) +{ + return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_LT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comle_epu16(__m128i __A, __m128i __B) +{ + return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_LE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comgt_epu16(__m128i __A, __m128i __B) +{ + return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_GT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comge_epu16(__m128i __A, __m128i __B) +{ + return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_GE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comeq_epu16(__m128i __A, __m128i __B) +{ + return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_EQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comneq_epu16(__m128i __A, __m128i __B) +{ + return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_NEQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comfalse_epu16(__m128i __A, __m128i __B) +{ + return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_FALSE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comtrue_epu16(__m128i __A, __m128i __B) +{ + return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_TRUE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comlt_epu32(__m128i __A, __m128i __B) +{ + return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_LT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comle_epu32(__m128i __A, __m128i __B) +{ + return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_LE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comgt_epu32(__m128i __A, __m128i __B) +{ + return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_GT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comge_epu32(__m128i __A, __m128i __B) +{ + return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_GE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comeq_epu32(__m128i __A, __m128i __B) +{ + return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_EQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comneq_epu32(__m128i __A, __m128i __B) +{ + return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_NEQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comfalse_epu32(__m128i __A, __m128i __B) +{ + return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_FALSE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comtrue_epu32(__m128i __A, __m128i __B) +{ + return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_TRUE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comlt_epu64(__m128i __A, __m128i __B) +{ + return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_LT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comle_epu64(__m128i __A, __m128i __B) +{ + return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_LE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comgt_epu64(__m128i __A, __m128i __B) +{ + return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_GT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comge_epu64(__m128i __A, __m128i __B) +{ + return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_GE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comeq_epu64(__m128i __A, __m128i __B) +{ + return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_EQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comneq_epu64(__m128i __A, __m128i __B) +{ + return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_NEQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comfalse_epu64(__m128i __A, __m128i __B) +{ + return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_FALSE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comtrue_epu64(__m128i __A, __m128i __B) +{ + return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_TRUE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comlt_epi8(__m128i __A, __m128i __B) +{ + return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_LT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comle_epi8(__m128i __A, __m128i __B) +{ + return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_LE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comgt_epi8(__m128i __A, __m128i __B) +{ + return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_GT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comge_epi8(__m128i __A, __m128i __B) +{ + return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_GE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comeq_epi8(__m128i __A, __m128i __B) +{ + return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_EQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comneq_epi8(__m128i __A, __m128i __B) +{ + return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_NEQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comfalse_epi8(__m128i __A, __m128i __B) +{ + return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_FALSE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comtrue_epi8(__m128i __A, __m128i __B) +{ + return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_TRUE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comlt_epi16(__m128i __A, __m128i __B) +{ + return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_LT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comle_epi16(__m128i __A, __m128i __B) +{ + return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_LE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comgt_epi16(__m128i __A, __m128i __B) +{ + return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_GT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comge_epi16(__m128i __A, __m128i __B) +{ + return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_GE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comeq_epi16(__m128i __A, __m128i __B) +{ + return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_EQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comneq_epi16(__m128i __A, __m128i __B) +{ + return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_NEQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comfalse_epi16(__m128i __A, __m128i __B) +{ + return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_FALSE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comtrue_epi16(__m128i __A, __m128i __B) +{ + return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_TRUE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comlt_epi32(__m128i __A, __m128i __B) +{ + return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_LT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comle_epi32(__m128i __A, __m128i __B) +{ + return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_LE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comgt_epi32(__m128i __A, __m128i __B) +{ + return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_GT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comge_epi32(__m128i __A, __m128i __B) +{ + return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_GE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comeq_epi32(__m128i __A, __m128i __B) +{ + return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_EQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comneq_epi32(__m128i __A, __m128i __B) +{ + return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_NEQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comfalse_epi32(__m128i __A, __m128i __B) +{ + return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_FALSE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comtrue_epi32(__m128i __A, __m128i __B) +{ + return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_TRUE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comlt_epi64(__m128i __A, __m128i __B) +{ + return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_LT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comle_epi64(__m128i __A, __m128i __B) +{ + return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_LE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comgt_epi64(__m128i __A, __m128i __B) +{ + return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_GT); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comge_epi64(__m128i __A, __m128i __B) +{ + return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_GE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comeq_epi64(__m128i __A, __m128i __B) +{ + return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_EQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comneq_epi64(__m128i __A, __m128i __B) +{ + return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_NEQ); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comfalse_epi64(__m128i __A, __m128i __B) +{ + return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_FALSE); +} + +static __inline__ __m128i __DEFAULT_FN_ATTRS +_mm_comtrue_epi64(__m128i __A, __m128i __B) +{ + return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_TRUE); +} + +#define _mm_permute2_pd(X, Y, C, I) __extension__ ({ \ + __m128d __X = (X); \ + __m128d __Y = (Y); \ + __m128i __C = (C); \ + (__m128d)__builtin_ia32_vpermil2pd((__v2df)__X, (__v2df)__Y, \ + (__v2di)__C, (I)); }) + +#define _mm256_permute2_pd(X, Y, C, I) __extension__ ({ \ + __m256d __X = (X); \ + __m256d __Y = (Y); \ + __m256i __C = (C); \ + (__m256d)__builtin_ia32_vpermil2pd256((__v4df)__X, (__v4df)__Y, \ + (__v4di)__C, (I)); }) + +#define _mm_permute2_ps(X, Y, C, I) __extension__ ({ \ + __m128 __X = (X); \ + __m128 __Y = (Y); \ + __m128i __C = (C); \ + (__m128)__builtin_ia32_vpermil2ps((__v4sf)__X, (__v4sf)__Y, \ + (__v4si)__C, (I)); }) + +#define _mm256_permute2_ps(X, Y, C, I) __extension__ ({ \ + __m256 __X = (X); \ + __m256 __Y = (Y); \ + __m256i __C = (C); \ + (__m256)__builtin_ia32_vpermil2ps256((__v8sf)__X, (__v8sf)__Y, \ + (__v8si)__C, (I)); }) + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_frcz_ss(__m128 __A) +{ + return (__m128)__builtin_ia32_vfrczss((__v4sf)__A); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_frcz_sd(__m128d __A) +{ + return (__m128d)__builtin_ia32_vfrczsd((__v2df)__A); +} + +static __inline__ __m128 __DEFAULT_FN_ATTRS +_mm_frcz_ps(__m128 __A) +{ + return (__m128)__builtin_ia32_vfrczps((__v4sf)__A); +} + +static __inline__ __m128d __DEFAULT_FN_ATTRS +_mm_frcz_pd(__m128d __A) +{ + return (__m128d)__builtin_ia32_vfrczpd((__v2df)__A); +} + +static __inline__ __m256 __DEFAULT_FN_ATTRS +_mm256_frcz_ps(__m256 __A) +{ + return (__m256)__builtin_ia32_vfrczps256((__v8sf)__A); +} + +static __inline__ __m256d __DEFAULT_FN_ATTRS +_mm256_frcz_pd(__m256d __A) +{ + return (__m256d)__builtin_ia32_vfrczpd256((__v4df)__A); +} + +#undef __DEFAULT_FN_ATTRS + +#endif /* __XOPINTRIN_H */ diff --git a/headers/clang/xsavecintrin.h b/headers/clang/xsavecintrin.h new file mode 100644 index 0000000000..598470a682 --- /dev/null +++ b/headers/clang/xsavecintrin.h @@ -0,0 +1,48 @@ +/*===---- xsavecintrin.h - XSAVEC intrinsic ------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __XSAVECINTRIN_H +#define __XSAVECINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("xsavec"))) + +static __inline__ void __DEFAULT_FN_ATTRS +_xsavec(void *__p, unsigned long long __m) { + __builtin_ia32_xsavec(__p, __m); +} + +#ifdef __x86_64__ +static __inline__ void __DEFAULT_FN_ATTRS +_xsavec64(void *__p, unsigned long long __m) { + __builtin_ia32_xsavec64(__p, __m); +} +#endif + +#undef __DEFAULT_FN_ATTRS + +#endif diff --git a/headers/clang/xsaveintrin.h b/headers/clang/xsaveintrin.h new file mode 100644 index 0000000000..a2e6b2e742 --- /dev/null +++ b/headers/clang/xsaveintrin.h @@ -0,0 +1,58 @@ +/*===---- xsaveintrin.h - XSAVE intrinsic ------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __XSAVEINTRIN_H +#define __XSAVEINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("xsave"))) + +static __inline__ void __DEFAULT_FN_ATTRS +_xsave(void *__p, unsigned long long __m) { + return __builtin_ia32_xsave(__p, __m); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_xrstor(void *__p, unsigned long long __m) { + return __builtin_ia32_xrstor(__p, __m); +} + +#ifdef __x86_64__ +static __inline__ void __DEFAULT_FN_ATTRS +_xsave64(void *__p, unsigned long long __m) { + return __builtin_ia32_xsave64(__p, __m); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_xrstor64(void *__p, unsigned long long __m) { + return __builtin_ia32_xrstor64(__p, __m); +} +#endif + +#undef __DEFAULT_FN_ATTRS + +#endif diff --git a/headers/clang/xsaveoptintrin.h b/headers/clang/xsaveoptintrin.h new file mode 100644 index 0000000000..d3faae78be --- /dev/null +++ b/headers/clang/xsaveoptintrin.h @@ -0,0 +1,48 @@ +/*===---- xsaveoptintrin.h - XSAVEOPT intrinsic ------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __XSAVEOPTINTRIN_H +#define __XSAVEOPTINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("xsaveopt"))) + +static __inline__ void __DEFAULT_FN_ATTRS +_xsaveopt(void *__p, unsigned long long __m) { + return __builtin_ia32_xsaveopt(__p, __m); +} + +#ifdef __x86_64__ +static __inline__ void __DEFAULT_FN_ATTRS +_xsaveopt64(void *__p, unsigned long long __m) { + return __builtin_ia32_xsaveopt64(__p, __m); +} +#endif + +#undef __DEFAULT_FN_ATTRS + +#endif diff --git a/headers/clang/xsavesintrin.h b/headers/clang/xsavesintrin.h new file mode 100644 index 0000000000..c5e540a86e --- /dev/null +++ b/headers/clang/xsavesintrin.h @@ -0,0 +1,58 @@ +/*===---- xsavesintrin.h - XSAVES intrinsic ------------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __XSAVESINTRIN_H +#define __XSAVESINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("xsaves"))) + +static __inline__ void __DEFAULT_FN_ATTRS +_xsaves(void *__p, unsigned long long __m) { + __builtin_ia32_xsaves(__p, __m); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_xrstors(void *__p, unsigned long long __m) { + __builtin_ia32_xrstors(__p, __m); +} + +#ifdef __x86_64__ +static __inline__ void __DEFAULT_FN_ATTRS +_xrstors64(void *__p, unsigned long long __m) { + __builtin_ia32_xrstors64(__p, __m); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_xsaves64(void *__p, unsigned long long __m) { + __builtin_ia32_xsaves64(__p, __m); +} +#endif + +#undef __DEFAULT_FN_ATTRS + +#endif diff --git a/headers/clang/xtestintrin.h b/headers/clang/xtestintrin.h new file mode 100644 index 0000000000..9d3378fd1e --- /dev/null +++ b/headers/clang/xtestintrin.h @@ -0,0 +1,41 @@ +/*===---- xtestintrin.h - XTEST intrinsic ---------------------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __XTESTINTRIN_H +#define __XTESTINTRIN_H + +/* xtest returns non-zero if the instruction is executed within an RTM or active + * HLE region. */ +/* FIXME: This can be an either or for RTM/HLE. Deal with this when HLE is + * supported. */ +static __inline__ int + __attribute__((__always_inline__, __nodebug__, __target__("rtm"))) + _xtest(void) { + return __builtin_ia32_xtest(); +} + +#endif From d77787f2a4d09e2950e412cdd4d80f164ca9088a Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Mon, 9 Nov 2015 14:28:07 +0100 Subject: [PATCH 151/370] Import libunwind --- headers/libs/libunwind/compiler.h | 74 ++ headers/libs/libunwind/dwarf-eh.h | 128 ++ headers/libs/libunwind/dwarf.h | 444 +++++++ headers/libs/libunwind/dwarf_i.h | 490 +++++++ headers/libs/libunwind/libunwind-aarch64.h | 187 +++ headers/libs/libunwind/libunwind-arm.h | 302 +++++ headers/libs/libunwind/libunwind-common.h | 257 ++++ headers/libs/libunwind/libunwind-coredump.h | 73 ++ headers/libs/libunwind/libunwind-dynamic.h | 210 +++ headers/libs/libunwind/libunwind-hppa.h | 125 ++ headers/libs/libunwind/libunwind-ia64.h | 194 +++ headers/libs/libunwind/libunwind-mips.h | 157 +++ headers/libs/libunwind/libunwind-ppc32.h | 207 +++ headers/libs/libunwind/libunwind-ppc64.h | 271 ++++ headers/libs/libunwind/libunwind-ptrace.h | 63 + headers/libs/libunwind/libunwind-sh.h | 114 ++ headers/libs/libunwind/libunwind-tilegx.h | 161 +++ headers/libs/libunwind/libunwind-x86.h | 187 +++ headers/libs/libunwind/libunwind-x86_64.h | 141 ++ headers/libs/libunwind/libunwind.h | 37 + headers/libs/libunwind/libunwind_i.h | 359 ++++++ headers/libs/libunwind/mempool.h | 89 ++ headers/libs/libunwind/remote.h | 127 ++ .../libunwind/tdep-aarch64/dwarf-config.h | 52 + headers/libs/libunwind/tdep-aarch64/jmpbuf.h | 33 + .../libs/libunwind/tdep-aarch64/libunwind_i.h | 318 +++++ .../libs/libunwind/tdep-arm/dwarf-config.h | 51 + headers/libs/libunwind/tdep-arm/ex_tables.h | 55 + headers/libs/libunwind/tdep-arm/jmpbuf.h | 32 + headers/libs/libunwind/tdep-arm/libunwind_i.h | 321 +++++ .../libs/libunwind/tdep-hppa/dwarf-config.h | 54 + headers/libs/libunwind/tdep-hppa/jmpbuf.h | 33 + .../libs/libunwind/tdep-hppa/libunwind_i.h | 277 ++++ headers/libs/libunwind/tdep-ia64/jmpbuf.h | 32 + .../libs/libunwind/tdep-ia64/libunwind_i.h | 279 ++++ headers/libs/libunwind/tdep-ia64/rse.h | 67 + headers/libs/libunwind/tdep-ia64/script.h | 85 ++ .../libs/libunwind/tdep-mips/dwarf-config.h | 54 + headers/libs/libunwind/tdep-mips/jmpbuf.h | 32 + .../libs/libunwind/tdep-mips/libunwind_i.h | 329 +++++ .../libs/libunwind/tdep-ppc32/dwarf-config.h | 56 + headers/libs/libunwind/tdep-ppc32/jmpbuf.h | 37 + .../libs/libunwind/tdep-ppc32/libunwind_i.h | 312 +++++ .../libs/libunwind/tdep-ppc64/dwarf-config.h | 56 + headers/libs/libunwind/tdep-ppc64/jmpbuf.h | 37 + .../libs/libunwind/tdep-ppc64/libunwind_i.h | 367 ++++++ headers/libs/libunwind/tdep-sh/dwarf-config.h | 49 + headers/libs/libunwind/tdep-sh/jmpbuf.h | 48 + headers/libs/libunwind/tdep-sh/libunwind_i.h | 278 ++++ .../libs/libunwind/tdep-tilegx/dwarf-config.h | 50 + headers/libs/libunwind/tdep-tilegx/jmpbuf.h | 33 + .../libs/libunwind/tdep-tilegx/libunwind_i.h | 265 ++++ .../libs/libunwind/tdep-x86/dwarf-config.h | 52 + headers/libs/libunwind/tdep-x86/jmpbuf.h | 42 + headers/libs/libunwind/tdep-x86/libunwind_i.h | 291 +++++ .../libs/libunwind/tdep-x86_64/dwarf-config.h | 57 + headers/libs/libunwind/tdep-x86_64/jmpbuf.h | 43 + .../libs/libunwind/tdep-x86_64/libunwind_i.h | 262 ++++ headers/libs/libunwind/tdep/dwarf-config.h | 28 + headers/libs/libunwind/tdep/jmpbuf.h | 30 + headers/libs/libunwind/tdep/libunwind_i.h | 38 + headers/libs/libunwind/unwind.h | 154 +++ headers/libs/libunwind/x86/jmpbuf.h | 31 + src/libs/libunwind/.gitignore | 69 + src/libs/libunwind/AUTHORS | 1 + src/libs/libunwind/COPYING | 20 + src/libs/libunwind/ChangeLog | 55 + src/libs/libunwind/LICENSE | 18 + src/libs/libunwind/Makefile.am | 715 +++++++++++ src/libs/libunwind/NEWS | 229 ++++ src/libs/libunwind/README | 214 ++++ src/libs/libunwind/TODO | 97 ++ .../libunwind/aarch64/Gcreate_addr_space.c | 60 + src/libs/libunwind/aarch64/Gget_proc_info.c | 39 + src/libs/libunwind/aarch64/Gget_save_loc.c | 100 ++ src/libs/libunwind/aarch64/Gglobal.c | 57 + src/libs/libunwind/aarch64/Ginit.c | 190 +++ src/libs/libunwind/aarch64/Ginit_local.c | 55 + src/libs/libunwind/aarch64/Ginit_remote.c | 45 + src/libs/libunwind/aarch64/Gis_signal_frame.c | 64 + src/libs/libunwind/aarch64/Gregs.c | 116 ++ src/libs/libunwind/aarch64/Gresume.c | 198 +++ src/libs/libunwind/aarch64/Gstash_frame.c | 89 ++ src/libs/libunwind/aarch64/Gstep.c | 131 ++ src/libs/libunwind/aarch64/Gtrace.c | 548 ++++++++ .../libunwind/aarch64/Lcreate_addr_space.c | 5 + src/libs/libunwind/aarch64/Lget_proc_info.c | 5 + src/libs/libunwind/aarch64/Lget_save_loc.c | 5 + src/libs/libunwind/aarch64/Lglobal.c | 5 + src/libs/libunwind/aarch64/Linit.c | 5 + src/libs/libunwind/aarch64/Linit_local.c | 5 + src/libs/libunwind/aarch64/Linit_remote.c | 5 + src/libs/libunwind/aarch64/Lis_signal_frame.c | 5 + src/libs/libunwind/aarch64/Lregs.c | 5 + src/libs/libunwind/aarch64/Lresume.c | 5 + src/libs/libunwind/aarch64/Lstash_frame.c | 5 + src/libs/libunwind/aarch64/Lstep.c | 5 + src/libs/libunwind/aarch64/Ltrace.c | 5 + src/libs/libunwind/aarch64/gen-offsets.c | 68 + src/libs/libunwind/aarch64/getcontext.S | 52 + src/libs/libunwind/aarch64/init.h | 127 ++ src/libs/libunwind/aarch64/is_fpreg.c | 32 + src/libs/libunwind/aarch64/offsets.h | 49 + src/libs/libunwind/aarch64/regname.c | 106 ++ src/libs/libunwind/aarch64/siglongjmp.S | 12 + src/libs/libunwind/aarch64/unwind_i.h | 64 + src/libs/libunwind/arm/Gcreate_addr_space.c | 60 + src/libs/libunwind/arm/Gex_tables.c | 569 +++++++++ src/libs/libunwind/arm/Gget_proc_info.c | 41 + src/libs/libunwind/arm/Gget_save_loc.c | 81 ++ src/libs/libunwind/arm/Gglobal.c | 65 + src/libs/libunwind/arm/Ginit.c | 235 ++++ src/libs/libunwind/arm/Ginit_local.c | 55 + src/libs/libunwind/arm/Ginit_remote.c | 45 + src/libs/libunwind/arm/Gis_signal_frame.c | 87 ++ src/libs/libunwind/arm/Gregs.c | 81 ++ src/libs/libunwind/arm/Gresume.c | 154 +++ src/libs/libunwind/arm/Gstash_frame.c | 90 ++ src/libs/libunwind/arm/Gstep.c | 272 ++++ src/libs/libunwind/arm/Gtrace.c | 550 ++++++++ src/libs/libunwind/arm/Lcreate_addr_space.c | 5 + src/libs/libunwind/arm/Lex_tables.c | 5 + src/libs/libunwind/arm/Lget_proc_info.c | 5 + src/libs/libunwind/arm/Lget_save_loc.c | 5 + src/libs/libunwind/arm/Lglobal.c | 5 + src/libs/libunwind/arm/Linit.c | 5 + src/libs/libunwind/arm/Linit_local.c | 5 + src/libs/libunwind/arm/Linit_remote.c | 5 + src/libs/libunwind/arm/Lis_signal_frame.c | 5 + src/libs/libunwind/arm/Lregs.c | 5 + src/libs/libunwind/arm/Lresume.c | 5 + src/libs/libunwind/arm/Lstash_frame.c | 5 + src/libs/libunwind/arm/Lstep.c | 5 + src/libs/libunwind/arm/Ltrace.c | 6 + src/libs/libunwind/arm/gen-offsets.c | 54 + src/libs/libunwind/arm/getcontext.S | 56 + src/libs/libunwind/arm/init.h | 78 ++ src/libs/libunwind/arm/is_fpreg.c | 39 + src/libs/libunwind/arm/offsets.h | 36 + src/libs/libunwind/arm/regname.c | 90 ++ src/libs/libunwind/arm/siglongjmp.S | 12 + src/libs/libunwind/arm/unwind_i.h | 59 + src/libs/libunwind/coredump/README | 8 + src/libs/libunwind/coredump/_UCD_access_mem.c | 98 ++ .../coredump/_UCD_access_reg_freebsd.c | 118 ++ .../coredump/_UCD_access_reg_linux.c | 143 +++ src/libs/libunwind/coredump/_UCD_accessors.c | 36 + src/libs/libunwind/coredump/_UCD_create.c | 417 ++++++ src/libs/libunwind/coredump/_UCD_destroy.c | 50 + .../libunwind/coredump/_UCD_elf_map_image.c | 98 ++ .../libunwind/coredump/_UCD_find_proc_info.c | 163 +++ .../libunwind/coredump/_UCD_get_proc_name.c | 70 + src/libs/libunwind/coredump/_UCD_internal.h | 105 ++ src/libs/libunwind/coredump/_UCD_lib.h | 57 + .../libunwind/coredump/_UPT_access_fpreg.c | 34 + src/libs/libunwind/coredump/_UPT_elf.c | 5 + .../coredump/_UPT_get_dyn_info_list_addr.c | 108 ++ .../libunwind/coredump/_UPT_put_unwind_info.c | 36 + src/libs/libunwind/coredump/_UPT_resume.c | 35 + src/libs/libunwind/dwarf/Gexpr.c | 648 ++++++++++ src/libs/libunwind/dwarf/Gfde.c | 366 ++++++ .../libunwind/dwarf/Gfind_proc_info-lsb.c | 1084 ++++++++++++++++ src/libs/libunwind/dwarf/Gfind_unwind_table.c | 219 ++++ src/libs/libunwind/dwarf/Gparser.c | 931 ++++++++++++++ src/libs/libunwind/dwarf/Gpe.c | 40 + src/libs/libunwind/dwarf/Gstep.c | 41 + src/libs/libunwind/dwarf/Lexpr.c | 5 + src/libs/libunwind/dwarf/Lfde.c | 5 + .../libunwind/dwarf/Lfind_proc_info-lsb.c | 5 + src/libs/libunwind/dwarf/Lfind_unwind_table.c | 5 + src/libs/libunwind/dwarf/Lparser.c | 5 + src/libs/libunwind/dwarf/Lpe.c | 5 + src/libs/libunwind/dwarf/Lstep.c | 5 + src/libs/libunwind/dwarf/global.c | 37 + src/libs/libunwind/elf32.c | 4 + src/libs/libunwind/elf32.h | 9 + src/libs/libunwind/elf64.c | 4 + src/libs/libunwind/elf64.h | 9 + src/libs/libunwind/elfxx.c | 359 ++++++ src/libs/libunwind/elfxx.h | 98 ++ src/libs/libunwind/hppa/Gcreate_addr_space.c | 54 + src/libs/libunwind/hppa/Gget_proc_info.c | 46 + src/libs/libunwind/hppa/Gget_save_loc.c | 59 + src/libs/libunwind/hppa/Gglobal.c | 55 + src/libs/libunwind/hppa/Ginit.c | 194 +++ src/libs/libunwind/hppa/Ginit_local.c | 54 + src/libs/libunwind/hppa/Ginit_remote.c | 46 + src/libs/libunwind/hppa/Gis_signal_frame.c | 74 ++ src/libs/libunwind/hppa/Gregs.c | 87 ++ src/libs/libunwind/hppa/Gresume.c | 145 +++ src/libs/libunwind/hppa/Gstep.c | 96 ++ src/libs/libunwind/hppa/Lcreate_addr_space.c | 5 + src/libs/libunwind/hppa/Lget_proc_info.c | 5 + src/libs/libunwind/hppa/Lget_save_loc.c | 5 + src/libs/libunwind/hppa/Lglobal.c | 5 + src/libs/libunwind/hppa/Linit.c | 5 + src/libs/libunwind/hppa/Linit_local.c | 5 + src/libs/libunwind/hppa/Linit_remote.c | 5 + src/libs/libunwind/hppa/Lis_signal_frame.c | 5 + src/libs/libunwind/hppa/Lregs.c | 5 + src/libs/libunwind/hppa/Lresume.c | 5 + src/libs/libunwind/hppa/Lstep.c | 5 + src/libs/libunwind/hppa/get_accessors.c | 35 + src/libs/libunwind/hppa/getcontext.S | 74 ++ src/libs/libunwind/hppa/init.h | 47 + src/libs/libunwind/hppa/offsets.h | 17 + src/libs/libunwind/hppa/regname.c | 50 + src/libs/libunwind/hppa/setcontext.S | 77 ++ src/libs/libunwind/hppa/siglongjmp.S | 16 + src/libs/libunwind/hppa/tables.c | 43 + src/libs/libunwind/hppa/unwind_i.h | 47 + src/libs/libunwind/ia64/Gcreate_addr_space.c | 63 + src/libs/libunwind/ia64/Gfind_unwind_table.c | 143 +++ src/libs/libunwind/ia64/Gget_proc_info.c | 38 + src/libs/libunwind/ia64/Gget_save_loc.c | 168 +++ src/libs/libunwind/ia64/Gglobal.c | 122 ++ src/libs/libunwind/ia64/Ginit.c | 505 ++++++++ src/libs/libunwind/ia64/Ginit_local.c | 110 ++ src/libs/libunwind/ia64/Ginit_remote.c | 61 + src/libs/libunwind/ia64/Ginstall_cursor.S | 348 +++++ src/libs/libunwind/ia64/Gis_signal_frame.c | 54 + src/libs/libunwind/ia64/Gparser.c | 1131 +++++++++++++++++ src/libs/libunwind/ia64/Grbs.c | 319 +++++ src/libs/libunwind/ia64/Gregs.c | 612 +++++++++ src/libs/libunwind/ia64/Gresume.c | 274 ++++ src/libs/libunwind/ia64/Gscript.c | 765 +++++++++++ src/libs/libunwind/ia64/Gstep.c | 359 ++++++ src/libs/libunwind/ia64/Gtables.c | 731 +++++++++++ src/libs/libunwind/ia64/Lcreate_addr_space.c | 5 + src/libs/libunwind/ia64/Lfind_unwind_table.c | 5 + src/libs/libunwind/ia64/Lget_proc_info.c | 5 + src/libs/libunwind/ia64/Lget_save_loc.c | 5 + src/libs/libunwind/ia64/Lglobal.c | 5 + src/libs/libunwind/ia64/Linit.c | 5 + src/libs/libunwind/ia64/Linit_local.c | 5 + src/libs/libunwind/ia64/Linit_remote.c | 5 + src/libs/libunwind/ia64/Linstall_cursor.S | 6 + src/libs/libunwind/ia64/Lis_signal_frame.c | 5 + src/libs/libunwind/ia64/Lparser.c | 5 + src/libs/libunwind/ia64/Lrbs.c | 5 + src/libs/libunwind/ia64/Lregs.c | 5 + src/libs/libunwind/ia64/Lresume.c | 5 + src/libs/libunwind/ia64/Lscript.c | 5 + src/libs/libunwind/ia64/Lstep.c | 5 + src/libs/libunwind/ia64/Ltables.c | 5 + src/libs/libunwind/ia64/NOTES | 65 + src/libs/libunwind/ia64/dyn_info_list.S | 26 + src/libs/libunwind/ia64/getcontext.S | 177 +++ src/libs/libunwind/ia64/init.h | 132 ++ src/libs/libunwind/ia64/longjmp.S | 42 + src/libs/libunwind/ia64/mk_Gcursor_i.c | 65 + src/libs/libunwind/ia64/mk_Lcursor_i.c | 2 + src/libs/libunwind/ia64/mk_cursor_i | 7 + src/libs/libunwind/ia64/offsets.h | 137 ++ src/libs/libunwind/ia64/regname.c | 189 +++ src/libs/libunwind/ia64/regs.h | 73 ++ src/libs/libunwind/ia64/setjmp.S | 51 + src/libs/libunwind/ia64/siglongjmp.S | 69 + src/libs/libunwind/ia64/sigsetjmp.S | 69 + src/libs/libunwind/ia64/ucontext_i.h | 68 + src/libs/libunwind/ia64/unwind_decoder.h | 477 +++++++ src/libs/libunwind/ia64/unwind_i.h | 633 +++++++++ src/libs/libunwind/mi/Gdestroy_addr_space.c | 37 + src/libs/libunwind/mi/Gdyn-extract.c | 62 + src/libs/libunwind/mi/Gdyn-remote.c | 326 +++++ .../libunwind/mi/Gfind_dynamic_proc_info.c | 91 ++ src/libs/libunwind/mi/Gget_accessors.c | 34 + src/libs/libunwind/mi/Gget_fpreg.c | 34 + src/libs/libunwind/mi/Gget_proc_info_by_ip.c | 39 + src/libs/libunwind/mi/Gget_proc_name.c | 114 ++ src/libs/libunwind/mi/Gget_reg.c | 41 + .../libunwind/mi/Gput_dynamic_unwind_info.c | 55 + src/libs/libunwind/mi/Gset_caching_policy.c | 46 + src/libs/libunwind/mi/Gset_fpreg.c | 34 + src/libs/libunwind/mi/Gset_reg.c | 34 + src/libs/libunwind/mi/Ldestroy_addr_space.c | 5 + src/libs/libunwind/mi/Ldyn-extract.c | 5 + src/libs/libunwind/mi/Ldyn-remote.c | 5 + .../libunwind/mi/Lfind_dynamic_proc_info.c | 5 + src/libs/libunwind/mi/Lget_accessors.c | 5 + src/libs/libunwind/mi/Lget_fpreg.c | 5 + src/libs/libunwind/mi/Lget_proc_info_by_ip.c | 5 + src/libs/libunwind/mi/Lget_proc_name.c | 5 + src/libs/libunwind/mi/Lget_reg.c | 5 + .../libunwind/mi/Lput_dynamic_unwind_info.c | 5 + src/libs/libunwind/mi/Lset_caching_policy.c | 5 + src/libs/libunwind/mi/Lset_fpreg.c | 5 + src/libs/libunwind/mi/Lset_reg.c | 5 + src/libs/libunwind/mi/_ReadSLEB.c | 25 + src/libs/libunwind/mi/_ReadULEB.c | 20 + src/libs/libunwind/mi/backtrace.c | 81 ++ src/libs/libunwind/mi/dyn-cancel.c | 46 + src/libs/libunwind/mi/dyn-info-list.c | 34 + src/libs/libunwind/mi/dyn-register.c | 44 + src/libs/libunwind/mi/flush_cache.c | 59 + src/libs/libunwind/mi/init.c | 60 + src/libs/libunwind/mi/mempool.c | 184 +++ src/libs/libunwind/mi/strerror.c | 51 + src/libs/libunwind/mips/Gcreate_addr_space.c | 66 + src/libs/libunwind/mips/Gget_proc_info.c | 41 + src/libs/libunwind/mips/Gget_save_loc.c | 100 ++ src/libs/libunwind/mips/Gglobal.c | 55 + src/libs/libunwind/mips/Ginit.c | 210 +++ src/libs/libunwind/mips/Ginit_local.c | 53 + src/libs/libunwind/mips/Ginit_remote.c | 45 + src/libs/libunwind/mips/Gis_signal_frame.c | 78 ++ src/libs/libunwind/mips/Gregs.c | 103 ++ src/libs/libunwind/mips/Gresume.c | 45 + src/libs/libunwind/mips/Gstep.c | 132 ++ src/libs/libunwind/mips/Lcreate_addr_space.c | 5 + src/libs/libunwind/mips/Lget_proc_info.c | 5 + src/libs/libunwind/mips/Lget_save_loc.c | 5 + src/libs/libunwind/mips/Lglobal.c | 5 + src/libs/libunwind/mips/Linit.c | 5 + src/libs/libunwind/mips/Linit_local.c | 5 + src/libs/libunwind/mips/Linit_remote.c | 5 + src/libs/libunwind/mips/Lis_signal_frame.c | 5 + src/libs/libunwind/mips/Lregs.c | 5 + src/libs/libunwind/mips/Lresume.c | 5 + src/libs/libunwind/mips/Lstep.c | 5 + src/libs/libunwind/mips/elfxx.c | 27 + src/libs/libunwind/mips/gen-offsets.c | 30 + src/libs/libunwind/mips/getcontext.S | 93 ++ src/libs/libunwind/mips/init.h | 60 + src/libs/libunwind/mips/is_fpreg.c | 35 + src/libs/libunwind/mips/offsets.h | 86 ++ src/libs/libunwind/mips/regname.c | 48 + src/libs/libunwind/mips/siglongjmp.S | 8 + src/libs/libunwind/mips/unwind_i.h | 43 + src/libs/libunwind/os-freebsd.c | 145 +++ src/libs/libunwind/os-hpux.c | 67 + src/libs/libunwind/os-linux.c | 63 + src/libs/libunwind/os-linux.h | 297 +++++ src/libs/libunwind/os-qnx.c | 107 ++ src/libs/libunwind/ppc/Gget_proc_info.c | 41 + src/libs/libunwind/ppc/Gget_save_loc.c | 34 + src/libs/libunwind/ppc/Ginit_local.c | 65 + src/libs/libunwind/ppc/Ginit_remote.c | 60 + src/libs/libunwind/ppc/Gis_signal_frame.c | 78 ++ src/libs/libunwind/ppc/Lget_proc_info.c | 5 + src/libs/libunwind/ppc/Lget_save_loc.c | 5 + src/libs/libunwind/ppc/Linit_local.c | 5 + src/libs/libunwind/ppc/Linit_remote.c | 5 + src/libs/libunwind/ppc/Lis_signal_frame.c | 5 + src/libs/libunwind/ppc/longjmp.S | 36 + src/libs/libunwind/ppc/siglongjmp.S | 31 + src/libs/libunwind/ppc32/Gcreate_addr_space.c | 56 + src/libs/libunwind/ppc32/Gglobal.c | 135 ++ src/libs/libunwind/ppc32/Ginit.c | 216 ++++ src/libs/libunwind/ppc32/Gregs.c | 90 ++ src/libs/libunwind/ppc32/Gresume.c | 77 ++ src/libs/libunwind/ppc32/Gstep.c | 309 +++++ src/libs/libunwind/ppc32/Lcreate_addr_space.c | 5 + src/libs/libunwind/ppc32/Lglobal.c | 5 + src/libs/libunwind/ppc32/Linit.c | 5 + src/libs/libunwind/ppc32/Lregs.c | 5 + src/libs/libunwind/ppc32/Lresume.c | 5 + src/libs/libunwind/ppc32/Lstep.c | 5 + src/libs/libunwind/ppc32/get_func_addr.c | 36 + src/libs/libunwind/ppc32/init.h | 73 ++ src/libs/libunwind/ppc32/is_fpreg.c | 34 + src/libs/libunwind/ppc32/regname.c | 112 ++ src/libs/libunwind/ppc32/setcontext.S | 9 + src/libs/libunwind/ppc32/ucontext_i.h | 128 ++ src/libs/libunwind/ppc32/unwind_i.h | 46 + src/libs/libunwind/ppc64/Gcreate_addr_space.c | 71 ++ src/libs/libunwind/ppc64/Gglobal.c | 182 +++ src/libs/libunwind/ppc64/Ginit.c | 231 ++++ src/libs/libunwind/ppc64/Gregs.c | 141 ++ src/libs/libunwind/ppc64/Gresume.c | 111 ++ src/libs/libunwind/ppc64/Gstep.c | 450 +++++++ src/libs/libunwind/ppc64/Lcreate_addr_space.c | 5 + src/libs/libunwind/ppc64/Lglobal.c | 5 + src/libs/libunwind/ppc64/Linit.c | 5 + src/libs/libunwind/ppc64/Lregs.c | 5 + src/libs/libunwind/ppc64/Lresume.c | 5 + src/libs/libunwind/ppc64/Lstep.c | 5 + src/libs/libunwind/ppc64/get_func_addr.c | 51 + src/libs/libunwind/ppc64/init.h | 83 ++ src/libs/libunwind/ppc64/is_fpreg.c | 34 + src/libs/libunwind/ppc64/regname.c | 164 +++ src/libs/libunwind/ppc64/setcontext.S | 9 + src/libs/libunwind/ppc64/ucontext_i.h | 173 +++ src/libs/libunwind/ppc64/unwind_i.h | 52 + src/libs/libunwind/ptrace/_UPT_access_fpreg.c | 105 ++ src/libs/libunwind/ptrace/_UPT_access_mem.c | 90 ++ src/libs/libunwind/ptrace/_UPT_access_reg.c | 309 +++++ src/libs/libunwind/ptrace/_UPT_accessors.c | 38 + src/libs/libunwind/ptrace/_UPT_create.c | 46 + src/libs/libunwind/ptrace/_UPT_destroy.c | 34 + src/libs/libunwind/ptrace/_UPT_elf.c | 5 + .../libunwind/ptrace/_UPT_find_proc_info.c | 145 +++ .../ptrace/_UPT_get_dyn_info_list_addr.c | 105 ++ .../libunwind/ptrace/_UPT_get_proc_name.c | 42 + src/libs/libunwind/ptrace/_UPT_internal.h | 59 + .../libunwind/ptrace/_UPT_put_unwind_info.c | 35 + src/libs/libunwind/ptrace/_UPT_reg_offset.c | 601 +++++++++ src/libs/libunwind/ptrace/_UPT_resume.c | 40 + src/libs/libunwind/setjmp/longjmp.c | 115 ++ src/libs/libunwind/setjmp/setjmp.c | 49 + src/libs/libunwind/setjmp/setjmp_i.h | 118 ++ src/libs/libunwind/setjmp/siglongjmp.c | 127 ++ src/libs/libunwind/setjmp/sigsetjmp.c | 50 + src/libs/libunwind/sh/Gcreate_addr_space.c | 59 + src/libs/libunwind/sh/Gget_proc_info.c | 39 + src/libs/libunwind/sh/Gget_save_loc.c | 83 ++ src/libs/libunwind/sh/Gglobal.c | 56 + src/libs/libunwind/sh/Ginit.c | 186 +++ src/libs/libunwind/sh/Ginit_local.c | 55 + src/libs/libunwind/sh/Ginit_remote.c | 45 + src/libs/libunwind/sh/Gis_signal_frame.c | 119 ++ src/libs/libunwind/sh/Gregs.c | 79 ++ src/libs/libunwind/sh/Gresume.c | 165 +++ src/libs/libunwind/sh/Gstep.c | 117 ++ src/libs/libunwind/sh/Lcreate_addr_space.c | 5 + src/libs/libunwind/sh/Lget_proc_info.c | 5 + src/libs/libunwind/sh/Lget_save_loc.c | 5 + src/libs/libunwind/sh/Lglobal.c | 5 + src/libs/libunwind/sh/Linit.c | 5 + src/libs/libunwind/sh/Linit_local.c | 5 + src/libs/libunwind/sh/Linit_remote.c | 5 + src/libs/libunwind/sh/Lis_signal_frame.c | 5 + src/libs/libunwind/sh/Lregs.c | 5 + src/libs/libunwind/sh/Lresume.c | 5 + src/libs/libunwind/sh/Lstep.c | 5 + src/libs/libunwind/sh/gen-offsets.c | 51 + src/libs/libunwind/sh/init.h | 74 ++ src/libs/libunwind/sh/is_fpreg.c | 32 + src/libs/libunwind/sh/offsets.h | 32 + src/libs/libunwind/sh/regname.c | 56 + src/libs/libunwind/sh/siglongjmp.S | 8 + src/libs/libunwind/sh/unwind_i.h | 40 + .../libunwind/tilegx/Gcreate_addr_space.c | 65 + src/libs/libunwind/tilegx/Gget_proc_info.c | 48 + src/libs/libunwind/tilegx/Gget_save_loc.c | 62 + src/libs/libunwind/tilegx/Gglobal.c | 64 + src/libs/libunwind/tilegx/Ginit.c | 167 +++ src/libs/libunwind/tilegx/Ginit_local.c | 57 + src/libs/libunwind/tilegx/Ginit_remote.c | 47 + src/libs/libunwind/tilegx/Gis_signal_frame.c | 115 ++ src/libs/libunwind/tilegx/Gregs.c | 66 + src/libs/libunwind/tilegx/Gresume.c | 94 ++ src/libs/libunwind/tilegx/Gstep.c | 53 + .../libunwind/tilegx/Lcreate_addr_space.c | 5 + src/libs/libunwind/tilegx/Lget_proc_info.c | 5 + src/libs/libunwind/tilegx/Lget_save_loc.c | 5 + src/libs/libunwind/tilegx/Lglobal.c | 5 + src/libs/libunwind/tilegx/Linit.c | 5 + src/libs/libunwind/tilegx/Linit_local.c | 5 + src/libs/libunwind/tilegx/Linit_remote.c | 5 + src/libs/libunwind/tilegx/Lis_signal_frame.c | 5 + src/libs/libunwind/tilegx/Lregs.c | 5 + src/libs/libunwind/tilegx/Lresume.c | 5 + src/libs/libunwind/tilegx/Lstep.c | 5 + src/libs/libunwind/tilegx/elfxx.c | 27 + src/libs/libunwind/tilegx/gen-offsets.c | 30 + src/libs/libunwind/tilegx/getcontext.S | 36 + src/libs/libunwind/tilegx/init.h | 64 + src/libs/libunwind/tilegx/is_fpreg.c | 33 + src/libs/libunwind/tilegx/offsets.h | 12 + src/libs/libunwind/tilegx/regname.c | 55 + src/libs/libunwind/tilegx/siglongjmp.S | 7 + src/libs/libunwind/tilegx/unwind_i.h | 44 + src/libs/libunwind/unwind/Backtrace.c | 56 + src/libs/libunwind/unwind/DeleteException.c | 38 + .../libunwind/unwind/FindEnclosingFunction.c | 42 + src/libs/libunwind/unwind/ForcedUnwind.c | 52 + src/libs/libunwind/unwind/GetBSP.c | 42 + src/libs/libunwind/unwind/GetCFA.c | 38 + src/libs/libunwind/unwind/GetDataRelBase.c | 39 + src/libs/libunwind/unwind/GetGR.c | 43 + src/libs/libunwind/unwind/GetIP.c | 38 + src/libs/libunwind/unwind/GetIPInfo.c | 42 + .../unwind/GetLanguageSpecificData.c | 40 + src/libs/libunwind/unwind/GetRegionStart.c | 39 + src/libs/libunwind/unwind/GetTextRelBase.c | 35 + src/libs/libunwind/unwind/RaiseException.c | 103 ++ src/libs/libunwind/unwind/Resume.c | 42 + src/libs/libunwind/unwind/Resume_or_Rethrow.c | 47 + src/libs/libunwind/unwind/SetGR.c | 47 + src/libs/libunwind/unwind/SetIP.c | 35 + src/libs/libunwind/unwind/unwind-internal.h | 140 ++ src/libs/libunwind/x86/Gcreate_addr_space.c | 58 + src/libs/libunwind/x86/Gget_proc_info.c | 45 + src/libs/libunwind/x86/Gget_save_loc.c | 133 ++ src/libs/libunwind/x86/Gglobal.c | 67 + src/libs/libunwind/x86/Ginit.c | 243 ++++ src/libs/libunwind/x86/Ginit_local.c | 56 + src/libs/libunwind/x86/Ginit_remote.c | 56 + src/libs/libunwind/x86/Gos-freebsd.c | 374 ++++++ src/libs/libunwind/x86/Gos-linux.c | 308 +++++ src/libs/libunwind/x86/Gregs.c | 178 +++ src/libs/libunwind/x86/Gresume.c | 82 ++ src/libs/libunwind/x86/Gstep.c | 116 ++ src/libs/libunwind/x86/Lcreate_addr_space.c | 5 + src/libs/libunwind/x86/Lget_proc_info.c | 5 + src/libs/libunwind/x86/Lget_save_loc.c | 5 + src/libs/libunwind/x86/Lglobal.c | 5 + src/libs/libunwind/x86/Linit.c | 5 + src/libs/libunwind/x86/Linit_local.c | 5 + src/libs/libunwind/x86/Linit_remote.c | 5 + src/libs/libunwind/x86/Los-freebsd.c | 5 + src/libs/libunwind/x86/Los-linux.c | 5 + src/libs/libunwind/x86/Lregs.c | 5 + src/libs/libunwind/x86/Lresume.c | 5 + src/libs/libunwind/x86/Lstep.c | 5 + src/libs/libunwind/x86/getcontext-freebsd.S | 112 ++ src/libs/libunwind/x86/getcontext-linux.S | 74 ++ src/libs/libunwind/x86/init.h | 70 + src/libs/libunwind/x86/is_fpreg.c | 34 + src/libs/libunwind/x86/longjmp.S | 39 + src/libs/libunwind/x86/offsets.h | 140 ++ src/libs/libunwind/x86/regname.c | 27 + src/libs/libunwind/x86/siglongjmp.S | 92 ++ src/libs/libunwind/x86/unwind_i.h | 63 + .../libunwind/x86_64/Gcreate_addr_space.c | 61 + src/libs/libunwind/x86_64/Gget_proc_info.c | 48 + src/libs/libunwind/x86_64/Gget_save_loc.c | 73 ++ src/libs/libunwind/x86_64/Gglobal.c | 102 ++ src/libs/libunwind/x86_64/Ginit.c | 269 ++++ src/libs/libunwind/x86_64/Ginit_local.c | 58 + src/libs/libunwind/x86_64/Ginit_remote.c | 57 + src/libs/libunwind/x86_64/Gos-freebsd.c | 200 +++ src/libs/libunwind/x86_64/Gos-linux.c | 154 +++ src/libs/libunwind/x86_64/Gos-solaris.c | 156 +++ src/libs/libunwind/x86_64/Gregs.c | 138 ++ src/libs/libunwind/x86_64/Gresume.c | 114 ++ src/libs/libunwind/x86_64/Gstash_frame.c | 98 ++ src/libs/libunwind/x86_64/Gstep.c | 230 ++++ src/libs/libunwind/x86_64/Gtrace.c | 533 ++++++++ .../libunwind/x86_64/Lcreate_addr_space.c | 5 + src/libs/libunwind/x86_64/Lget_proc_info.c | 5 + src/libs/libunwind/x86_64/Lget_save_loc.c | 5 + src/libs/libunwind/x86_64/Lglobal.c | 6 + src/libs/libunwind/x86_64/Linit.c | 5 + src/libs/libunwind/x86_64/Linit_local.c | 5 + src/libs/libunwind/x86_64/Linit_remote.c | 5 + src/libs/libunwind/x86_64/Los-freebsd.c | 5 + src/libs/libunwind/x86_64/Los-linux.c | 5 + src/libs/libunwind/x86_64/Los-solaris.c | 5 + src/libs/libunwind/x86_64/Lregs.c | 5 + src/libs/libunwind/x86_64/Lresume.c | 5 + src/libs/libunwind/x86_64/Lstash_frame.c | 5 + src/libs/libunwind/x86_64/Lstep.c | 5 + src/libs/libunwind/x86_64/Ltrace.c | 5 + src/libs/libunwind/x86_64/getcontext.S | 136 ++ src/libs/libunwind/x86_64/init.h | 89 ++ src/libs/libunwind/x86_64/is_fpreg.c | 38 + src/libs/libunwind/x86_64/longjmp.S | 34 + src/libs/libunwind/x86_64/offsets.h | 3 + src/libs/libunwind/x86_64/regname.c | 56 + src/libs/libunwind/x86_64/setcontext.S | 124 ++ src/libs/libunwind/x86_64/siglongjmp.S | 32 + src/libs/libunwind/x86_64/ucontext_i.h | 102 ++ src/libs/libunwind/x86_64/unwind_i.h | 91 ++ 555 files changed, 49022 insertions(+) create mode 100644 headers/libs/libunwind/compiler.h create mode 100644 headers/libs/libunwind/dwarf-eh.h create mode 100644 headers/libs/libunwind/dwarf.h create mode 100644 headers/libs/libunwind/dwarf_i.h create mode 100644 headers/libs/libunwind/libunwind-aarch64.h create mode 100644 headers/libs/libunwind/libunwind-arm.h create mode 100644 headers/libs/libunwind/libunwind-common.h create mode 100644 headers/libs/libunwind/libunwind-coredump.h create mode 100644 headers/libs/libunwind/libunwind-dynamic.h create mode 100644 headers/libs/libunwind/libunwind-hppa.h create mode 100644 headers/libs/libunwind/libunwind-ia64.h create mode 100644 headers/libs/libunwind/libunwind-mips.h create mode 100644 headers/libs/libunwind/libunwind-ppc32.h create mode 100644 headers/libs/libunwind/libunwind-ppc64.h create mode 100644 headers/libs/libunwind/libunwind-ptrace.h create mode 100644 headers/libs/libunwind/libunwind-sh.h create mode 100644 headers/libs/libunwind/libunwind-tilegx.h create mode 100644 headers/libs/libunwind/libunwind-x86.h create mode 100644 headers/libs/libunwind/libunwind-x86_64.h create mode 100644 headers/libs/libunwind/libunwind.h create mode 100644 headers/libs/libunwind/libunwind_i.h create mode 100644 headers/libs/libunwind/mempool.h create mode 100644 headers/libs/libunwind/remote.h create mode 100644 headers/libs/libunwind/tdep-aarch64/dwarf-config.h create mode 100644 headers/libs/libunwind/tdep-aarch64/jmpbuf.h create mode 100644 headers/libs/libunwind/tdep-aarch64/libunwind_i.h create mode 100644 headers/libs/libunwind/tdep-arm/dwarf-config.h create mode 100644 headers/libs/libunwind/tdep-arm/ex_tables.h create mode 100644 headers/libs/libunwind/tdep-arm/jmpbuf.h create mode 100644 headers/libs/libunwind/tdep-arm/libunwind_i.h create mode 100644 headers/libs/libunwind/tdep-hppa/dwarf-config.h create mode 100644 headers/libs/libunwind/tdep-hppa/jmpbuf.h create mode 100644 headers/libs/libunwind/tdep-hppa/libunwind_i.h create mode 100644 headers/libs/libunwind/tdep-ia64/jmpbuf.h create mode 100644 headers/libs/libunwind/tdep-ia64/libunwind_i.h create mode 100644 headers/libs/libunwind/tdep-ia64/rse.h create mode 100644 headers/libs/libunwind/tdep-ia64/script.h create mode 100644 headers/libs/libunwind/tdep-mips/dwarf-config.h create mode 100644 headers/libs/libunwind/tdep-mips/jmpbuf.h create mode 100644 headers/libs/libunwind/tdep-mips/libunwind_i.h create mode 100644 headers/libs/libunwind/tdep-ppc32/dwarf-config.h create mode 100644 headers/libs/libunwind/tdep-ppc32/jmpbuf.h create mode 100644 headers/libs/libunwind/tdep-ppc32/libunwind_i.h create mode 100644 headers/libs/libunwind/tdep-ppc64/dwarf-config.h create mode 100644 headers/libs/libunwind/tdep-ppc64/jmpbuf.h create mode 100644 headers/libs/libunwind/tdep-ppc64/libunwind_i.h create mode 100644 headers/libs/libunwind/tdep-sh/dwarf-config.h create mode 100644 headers/libs/libunwind/tdep-sh/jmpbuf.h create mode 100644 headers/libs/libunwind/tdep-sh/libunwind_i.h create mode 100644 headers/libs/libunwind/tdep-tilegx/dwarf-config.h create mode 100644 headers/libs/libunwind/tdep-tilegx/jmpbuf.h create mode 100644 headers/libs/libunwind/tdep-tilegx/libunwind_i.h create mode 100644 headers/libs/libunwind/tdep-x86/dwarf-config.h create mode 100644 headers/libs/libunwind/tdep-x86/jmpbuf.h create mode 100644 headers/libs/libunwind/tdep-x86/libunwind_i.h create mode 100644 headers/libs/libunwind/tdep-x86_64/dwarf-config.h create mode 100644 headers/libs/libunwind/tdep-x86_64/jmpbuf.h create mode 100644 headers/libs/libunwind/tdep-x86_64/libunwind_i.h create mode 100644 headers/libs/libunwind/tdep/dwarf-config.h create mode 100644 headers/libs/libunwind/tdep/jmpbuf.h create mode 100644 headers/libs/libunwind/tdep/libunwind_i.h create mode 100644 headers/libs/libunwind/unwind.h create mode 100644 headers/libs/libunwind/x86/jmpbuf.h create mode 100644 src/libs/libunwind/.gitignore create mode 100644 src/libs/libunwind/AUTHORS create mode 100644 src/libs/libunwind/COPYING create mode 100644 src/libs/libunwind/ChangeLog create mode 100644 src/libs/libunwind/LICENSE create mode 100644 src/libs/libunwind/Makefile.am create mode 100644 src/libs/libunwind/NEWS create mode 100644 src/libs/libunwind/README create mode 100644 src/libs/libunwind/TODO create mode 100644 src/libs/libunwind/aarch64/Gcreate_addr_space.c create mode 100644 src/libs/libunwind/aarch64/Gget_proc_info.c create mode 100644 src/libs/libunwind/aarch64/Gget_save_loc.c create mode 100644 src/libs/libunwind/aarch64/Gglobal.c create mode 100644 src/libs/libunwind/aarch64/Ginit.c create mode 100644 src/libs/libunwind/aarch64/Ginit_local.c create mode 100644 src/libs/libunwind/aarch64/Ginit_remote.c create mode 100644 src/libs/libunwind/aarch64/Gis_signal_frame.c create mode 100644 src/libs/libunwind/aarch64/Gregs.c create mode 100644 src/libs/libunwind/aarch64/Gresume.c create mode 100644 src/libs/libunwind/aarch64/Gstash_frame.c create mode 100644 src/libs/libunwind/aarch64/Gstep.c create mode 100644 src/libs/libunwind/aarch64/Gtrace.c create mode 100644 src/libs/libunwind/aarch64/Lcreate_addr_space.c create mode 100644 src/libs/libunwind/aarch64/Lget_proc_info.c create mode 100644 src/libs/libunwind/aarch64/Lget_save_loc.c create mode 100644 src/libs/libunwind/aarch64/Lglobal.c create mode 100644 src/libs/libunwind/aarch64/Linit.c create mode 100644 src/libs/libunwind/aarch64/Linit_local.c create mode 100644 src/libs/libunwind/aarch64/Linit_remote.c create mode 100644 src/libs/libunwind/aarch64/Lis_signal_frame.c create mode 100644 src/libs/libunwind/aarch64/Lregs.c create mode 100644 src/libs/libunwind/aarch64/Lresume.c create mode 100644 src/libs/libunwind/aarch64/Lstash_frame.c create mode 100644 src/libs/libunwind/aarch64/Lstep.c create mode 100644 src/libs/libunwind/aarch64/Ltrace.c create mode 100644 src/libs/libunwind/aarch64/gen-offsets.c create mode 100644 src/libs/libunwind/aarch64/getcontext.S create mode 100644 src/libs/libunwind/aarch64/init.h create mode 100644 src/libs/libunwind/aarch64/is_fpreg.c create mode 100644 src/libs/libunwind/aarch64/offsets.h create mode 100644 src/libs/libunwind/aarch64/regname.c create mode 100644 src/libs/libunwind/aarch64/siglongjmp.S create mode 100644 src/libs/libunwind/aarch64/unwind_i.h create mode 100644 src/libs/libunwind/arm/Gcreate_addr_space.c create mode 100644 src/libs/libunwind/arm/Gex_tables.c create mode 100644 src/libs/libunwind/arm/Gget_proc_info.c create mode 100644 src/libs/libunwind/arm/Gget_save_loc.c create mode 100644 src/libs/libunwind/arm/Gglobal.c create mode 100644 src/libs/libunwind/arm/Ginit.c create mode 100644 src/libs/libunwind/arm/Ginit_local.c create mode 100644 src/libs/libunwind/arm/Ginit_remote.c create mode 100644 src/libs/libunwind/arm/Gis_signal_frame.c create mode 100644 src/libs/libunwind/arm/Gregs.c create mode 100644 src/libs/libunwind/arm/Gresume.c create mode 100644 src/libs/libunwind/arm/Gstash_frame.c create mode 100644 src/libs/libunwind/arm/Gstep.c create mode 100644 src/libs/libunwind/arm/Gtrace.c create mode 100644 src/libs/libunwind/arm/Lcreate_addr_space.c create mode 100644 src/libs/libunwind/arm/Lex_tables.c create mode 100644 src/libs/libunwind/arm/Lget_proc_info.c create mode 100644 src/libs/libunwind/arm/Lget_save_loc.c create mode 100644 src/libs/libunwind/arm/Lglobal.c create mode 100644 src/libs/libunwind/arm/Linit.c create mode 100644 src/libs/libunwind/arm/Linit_local.c create mode 100644 src/libs/libunwind/arm/Linit_remote.c create mode 100644 src/libs/libunwind/arm/Lis_signal_frame.c create mode 100644 src/libs/libunwind/arm/Lregs.c create mode 100644 src/libs/libunwind/arm/Lresume.c create mode 100644 src/libs/libunwind/arm/Lstash_frame.c create mode 100644 src/libs/libunwind/arm/Lstep.c create mode 100644 src/libs/libunwind/arm/Ltrace.c create mode 100644 src/libs/libunwind/arm/gen-offsets.c create mode 100644 src/libs/libunwind/arm/getcontext.S create mode 100644 src/libs/libunwind/arm/init.h create mode 100644 src/libs/libunwind/arm/is_fpreg.c create mode 100644 src/libs/libunwind/arm/offsets.h create mode 100644 src/libs/libunwind/arm/regname.c create mode 100644 src/libs/libunwind/arm/siglongjmp.S create mode 100644 src/libs/libunwind/arm/unwind_i.h create mode 100644 src/libs/libunwind/coredump/README create mode 100644 src/libs/libunwind/coredump/_UCD_access_mem.c create mode 100644 src/libs/libunwind/coredump/_UCD_access_reg_freebsd.c create mode 100644 src/libs/libunwind/coredump/_UCD_access_reg_linux.c create mode 100644 src/libs/libunwind/coredump/_UCD_accessors.c create mode 100644 src/libs/libunwind/coredump/_UCD_create.c create mode 100644 src/libs/libunwind/coredump/_UCD_destroy.c create mode 100644 src/libs/libunwind/coredump/_UCD_elf_map_image.c create mode 100644 src/libs/libunwind/coredump/_UCD_find_proc_info.c create mode 100644 src/libs/libunwind/coredump/_UCD_get_proc_name.c create mode 100644 src/libs/libunwind/coredump/_UCD_internal.h create mode 100644 src/libs/libunwind/coredump/_UCD_lib.h create mode 100644 src/libs/libunwind/coredump/_UPT_access_fpreg.c create mode 100644 src/libs/libunwind/coredump/_UPT_elf.c create mode 100644 src/libs/libunwind/coredump/_UPT_get_dyn_info_list_addr.c create mode 100644 src/libs/libunwind/coredump/_UPT_put_unwind_info.c create mode 100644 src/libs/libunwind/coredump/_UPT_resume.c create mode 100644 src/libs/libunwind/dwarf/Gexpr.c create mode 100644 src/libs/libunwind/dwarf/Gfde.c create mode 100644 src/libs/libunwind/dwarf/Gfind_proc_info-lsb.c create mode 100644 src/libs/libunwind/dwarf/Gfind_unwind_table.c create mode 100644 src/libs/libunwind/dwarf/Gparser.c create mode 100644 src/libs/libunwind/dwarf/Gpe.c create mode 100644 src/libs/libunwind/dwarf/Gstep.c create mode 100644 src/libs/libunwind/dwarf/Lexpr.c create mode 100644 src/libs/libunwind/dwarf/Lfde.c create mode 100644 src/libs/libunwind/dwarf/Lfind_proc_info-lsb.c create mode 100644 src/libs/libunwind/dwarf/Lfind_unwind_table.c create mode 100644 src/libs/libunwind/dwarf/Lparser.c create mode 100644 src/libs/libunwind/dwarf/Lpe.c create mode 100644 src/libs/libunwind/dwarf/Lstep.c create mode 100644 src/libs/libunwind/dwarf/global.c create mode 100644 src/libs/libunwind/elf32.c create mode 100644 src/libs/libunwind/elf32.h create mode 100644 src/libs/libunwind/elf64.c create mode 100644 src/libs/libunwind/elf64.h create mode 100644 src/libs/libunwind/elfxx.c create mode 100644 src/libs/libunwind/elfxx.h create mode 100644 src/libs/libunwind/hppa/Gcreate_addr_space.c create mode 100644 src/libs/libunwind/hppa/Gget_proc_info.c create mode 100644 src/libs/libunwind/hppa/Gget_save_loc.c create mode 100644 src/libs/libunwind/hppa/Gglobal.c create mode 100644 src/libs/libunwind/hppa/Ginit.c create mode 100644 src/libs/libunwind/hppa/Ginit_local.c create mode 100644 src/libs/libunwind/hppa/Ginit_remote.c create mode 100644 src/libs/libunwind/hppa/Gis_signal_frame.c create mode 100644 src/libs/libunwind/hppa/Gregs.c create mode 100644 src/libs/libunwind/hppa/Gresume.c create mode 100644 src/libs/libunwind/hppa/Gstep.c create mode 100644 src/libs/libunwind/hppa/Lcreate_addr_space.c create mode 100644 src/libs/libunwind/hppa/Lget_proc_info.c create mode 100644 src/libs/libunwind/hppa/Lget_save_loc.c create mode 100644 src/libs/libunwind/hppa/Lglobal.c create mode 100644 src/libs/libunwind/hppa/Linit.c create mode 100644 src/libs/libunwind/hppa/Linit_local.c create mode 100644 src/libs/libunwind/hppa/Linit_remote.c create mode 100644 src/libs/libunwind/hppa/Lis_signal_frame.c create mode 100644 src/libs/libunwind/hppa/Lregs.c create mode 100644 src/libs/libunwind/hppa/Lresume.c create mode 100644 src/libs/libunwind/hppa/Lstep.c create mode 100644 src/libs/libunwind/hppa/get_accessors.c create mode 100644 src/libs/libunwind/hppa/getcontext.S create mode 100644 src/libs/libunwind/hppa/init.h create mode 100644 src/libs/libunwind/hppa/offsets.h create mode 100644 src/libs/libunwind/hppa/regname.c create mode 100644 src/libs/libunwind/hppa/setcontext.S create mode 100644 src/libs/libunwind/hppa/siglongjmp.S create mode 100644 src/libs/libunwind/hppa/tables.c create mode 100644 src/libs/libunwind/hppa/unwind_i.h create mode 100644 src/libs/libunwind/ia64/Gcreate_addr_space.c create mode 100644 src/libs/libunwind/ia64/Gfind_unwind_table.c create mode 100644 src/libs/libunwind/ia64/Gget_proc_info.c create mode 100644 src/libs/libunwind/ia64/Gget_save_loc.c create mode 100644 src/libs/libunwind/ia64/Gglobal.c create mode 100644 src/libs/libunwind/ia64/Ginit.c create mode 100644 src/libs/libunwind/ia64/Ginit_local.c create mode 100644 src/libs/libunwind/ia64/Ginit_remote.c create mode 100644 src/libs/libunwind/ia64/Ginstall_cursor.S create mode 100644 src/libs/libunwind/ia64/Gis_signal_frame.c create mode 100644 src/libs/libunwind/ia64/Gparser.c create mode 100644 src/libs/libunwind/ia64/Grbs.c create mode 100644 src/libs/libunwind/ia64/Gregs.c create mode 100644 src/libs/libunwind/ia64/Gresume.c create mode 100644 src/libs/libunwind/ia64/Gscript.c create mode 100644 src/libs/libunwind/ia64/Gstep.c create mode 100644 src/libs/libunwind/ia64/Gtables.c create mode 100644 src/libs/libunwind/ia64/Lcreate_addr_space.c create mode 100644 src/libs/libunwind/ia64/Lfind_unwind_table.c create mode 100644 src/libs/libunwind/ia64/Lget_proc_info.c create mode 100644 src/libs/libunwind/ia64/Lget_save_loc.c create mode 100644 src/libs/libunwind/ia64/Lglobal.c create mode 100644 src/libs/libunwind/ia64/Linit.c create mode 100644 src/libs/libunwind/ia64/Linit_local.c create mode 100644 src/libs/libunwind/ia64/Linit_remote.c create mode 100644 src/libs/libunwind/ia64/Linstall_cursor.S create mode 100644 src/libs/libunwind/ia64/Lis_signal_frame.c create mode 100644 src/libs/libunwind/ia64/Lparser.c create mode 100644 src/libs/libunwind/ia64/Lrbs.c create mode 100644 src/libs/libunwind/ia64/Lregs.c create mode 100644 src/libs/libunwind/ia64/Lresume.c create mode 100644 src/libs/libunwind/ia64/Lscript.c create mode 100644 src/libs/libunwind/ia64/Lstep.c create mode 100644 src/libs/libunwind/ia64/Ltables.c create mode 100644 src/libs/libunwind/ia64/NOTES create mode 100644 src/libs/libunwind/ia64/dyn_info_list.S create mode 100644 src/libs/libunwind/ia64/getcontext.S create mode 100644 src/libs/libunwind/ia64/init.h create mode 100644 src/libs/libunwind/ia64/longjmp.S create mode 100644 src/libs/libunwind/ia64/mk_Gcursor_i.c create mode 100644 src/libs/libunwind/ia64/mk_Lcursor_i.c create mode 100755 src/libs/libunwind/ia64/mk_cursor_i create mode 100644 src/libs/libunwind/ia64/offsets.h create mode 100644 src/libs/libunwind/ia64/regname.c create mode 100644 src/libs/libunwind/ia64/regs.h create mode 100644 src/libs/libunwind/ia64/setjmp.S create mode 100644 src/libs/libunwind/ia64/siglongjmp.S create mode 100644 src/libs/libunwind/ia64/sigsetjmp.S create mode 100644 src/libs/libunwind/ia64/ucontext_i.h create mode 100644 src/libs/libunwind/ia64/unwind_decoder.h create mode 100644 src/libs/libunwind/ia64/unwind_i.h create mode 100644 src/libs/libunwind/mi/Gdestroy_addr_space.c create mode 100644 src/libs/libunwind/mi/Gdyn-extract.c create mode 100644 src/libs/libunwind/mi/Gdyn-remote.c create mode 100644 src/libs/libunwind/mi/Gfind_dynamic_proc_info.c create mode 100644 src/libs/libunwind/mi/Gget_accessors.c create mode 100644 src/libs/libunwind/mi/Gget_fpreg.c create mode 100644 src/libs/libunwind/mi/Gget_proc_info_by_ip.c create mode 100644 src/libs/libunwind/mi/Gget_proc_name.c create mode 100644 src/libs/libunwind/mi/Gget_reg.c create mode 100644 src/libs/libunwind/mi/Gput_dynamic_unwind_info.c create mode 100644 src/libs/libunwind/mi/Gset_caching_policy.c create mode 100644 src/libs/libunwind/mi/Gset_fpreg.c create mode 100644 src/libs/libunwind/mi/Gset_reg.c create mode 100644 src/libs/libunwind/mi/Ldestroy_addr_space.c create mode 100644 src/libs/libunwind/mi/Ldyn-extract.c create mode 100644 src/libs/libunwind/mi/Ldyn-remote.c create mode 100644 src/libs/libunwind/mi/Lfind_dynamic_proc_info.c create mode 100644 src/libs/libunwind/mi/Lget_accessors.c create mode 100644 src/libs/libunwind/mi/Lget_fpreg.c create mode 100644 src/libs/libunwind/mi/Lget_proc_info_by_ip.c create mode 100644 src/libs/libunwind/mi/Lget_proc_name.c create mode 100644 src/libs/libunwind/mi/Lget_reg.c create mode 100644 src/libs/libunwind/mi/Lput_dynamic_unwind_info.c create mode 100644 src/libs/libunwind/mi/Lset_caching_policy.c create mode 100644 src/libs/libunwind/mi/Lset_fpreg.c create mode 100644 src/libs/libunwind/mi/Lset_reg.c create mode 100644 src/libs/libunwind/mi/_ReadSLEB.c create mode 100644 src/libs/libunwind/mi/_ReadULEB.c create mode 100644 src/libs/libunwind/mi/backtrace.c create mode 100644 src/libs/libunwind/mi/dyn-cancel.c create mode 100644 src/libs/libunwind/mi/dyn-info-list.c create mode 100644 src/libs/libunwind/mi/dyn-register.c create mode 100644 src/libs/libunwind/mi/flush_cache.c create mode 100644 src/libs/libunwind/mi/init.c create mode 100644 src/libs/libunwind/mi/mempool.c create mode 100644 src/libs/libunwind/mi/strerror.c create mode 100644 src/libs/libunwind/mips/Gcreate_addr_space.c create mode 100644 src/libs/libunwind/mips/Gget_proc_info.c create mode 100644 src/libs/libunwind/mips/Gget_save_loc.c create mode 100644 src/libs/libunwind/mips/Gglobal.c create mode 100644 src/libs/libunwind/mips/Ginit.c create mode 100644 src/libs/libunwind/mips/Ginit_local.c create mode 100644 src/libs/libunwind/mips/Ginit_remote.c create mode 100644 src/libs/libunwind/mips/Gis_signal_frame.c create mode 100644 src/libs/libunwind/mips/Gregs.c create mode 100644 src/libs/libunwind/mips/Gresume.c create mode 100644 src/libs/libunwind/mips/Gstep.c create mode 100644 src/libs/libunwind/mips/Lcreate_addr_space.c create mode 100644 src/libs/libunwind/mips/Lget_proc_info.c create mode 100644 src/libs/libunwind/mips/Lget_save_loc.c create mode 100644 src/libs/libunwind/mips/Lglobal.c create mode 100644 src/libs/libunwind/mips/Linit.c create mode 100644 src/libs/libunwind/mips/Linit_local.c create mode 100644 src/libs/libunwind/mips/Linit_remote.c create mode 100644 src/libs/libunwind/mips/Lis_signal_frame.c create mode 100644 src/libs/libunwind/mips/Lregs.c create mode 100644 src/libs/libunwind/mips/Lresume.c create mode 100644 src/libs/libunwind/mips/Lstep.c create mode 100644 src/libs/libunwind/mips/elfxx.c create mode 100644 src/libs/libunwind/mips/gen-offsets.c create mode 100644 src/libs/libunwind/mips/getcontext.S create mode 100644 src/libs/libunwind/mips/init.h create mode 100644 src/libs/libunwind/mips/is_fpreg.c create mode 100644 src/libs/libunwind/mips/offsets.h create mode 100644 src/libs/libunwind/mips/regname.c create mode 100644 src/libs/libunwind/mips/siglongjmp.S create mode 100644 src/libs/libunwind/mips/unwind_i.h create mode 100644 src/libs/libunwind/os-freebsd.c create mode 100644 src/libs/libunwind/os-hpux.c create mode 100644 src/libs/libunwind/os-linux.c create mode 100644 src/libs/libunwind/os-linux.h create mode 100644 src/libs/libunwind/os-qnx.c create mode 100644 src/libs/libunwind/ppc/Gget_proc_info.c create mode 100644 src/libs/libunwind/ppc/Gget_save_loc.c create mode 100644 src/libs/libunwind/ppc/Ginit_local.c create mode 100644 src/libs/libunwind/ppc/Ginit_remote.c create mode 100644 src/libs/libunwind/ppc/Gis_signal_frame.c create mode 100644 src/libs/libunwind/ppc/Lget_proc_info.c create mode 100644 src/libs/libunwind/ppc/Lget_save_loc.c create mode 100644 src/libs/libunwind/ppc/Linit_local.c create mode 100644 src/libs/libunwind/ppc/Linit_remote.c create mode 100644 src/libs/libunwind/ppc/Lis_signal_frame.c create mode 100644 src/libs/libunwind/ppc/longjmp.S create mode 100644 src/libs/libunwind/ppc/siglongjmp.S create mode 100644 src/libs/libunwind/ppc32/Gcreate_addr_space.c create mode 100644 src/libs/libunwind/ppc32/Gglobal.c create mode 100644 src/libs/libunwind/ppc32/Ginit.c create mode 100644 src/libs/libunwind/ppc32/Gregs.c create mode 100644 src/libs/libunwind/ppc32/Gresume.c create mode 100644 src/libs/libunwind/ppc32/Gstep.c create mode 100644 src/libs/libunwind/ppc32/Lcreate_addr_space.c create mode 100644 src/libs/libunwind/ppc32/Lglobal.c create mode 100644 src/libs/libunwind/ppc32/Linit.c create mode 100644 src/libs/libunwind/ppc32/Lregs.c create mode 100644 src/libs/libunwind/ppc32/Lresume.c create mode 100644 src/libs/libunwind/ppc32/Lstep.c create mode 100644 src/libs/libunwind/ppc32/get_func_addr.c create mode 100644 src/libs/libunwind/ppc32/init.h create mode 100644 src/libs/libunwind/ppc32/is_fpreg.c create mode 100644 src/libs/libunwind/ppc32/regname.c create mode 100644 src/libs/libunwind/ppc32/setcontext.S create mode 100644 src/libs/libunwind/ppc32/ucontext_i.h create mode 100644 src/libs/libunwind/ppc32/unwind_i.h create mode 100644 src/libs/libunwind/ppc64/Gcreate_addr_space.c create mode 100644 src/libs/libunwind/ppc64/Gglobal.c create mode 100644 src/libs/libunwind/ppc64/Ginit.c create mode 100644 src/libs/libunwind/ppc64/Gregs.c create mode 100644 src/libs/libunwind/ppc64/Gresume.c create mode 100644 src/libs/libunwind/ppc64/Gstep.c create mode 100644 src/libs/libunwind/ppc64/Lcreate_addr_space.c create mode 100644 src/libs/libunwind/ppc64/Lglobal.c create mode 100644 src/libs/libunwind/ppc64/Linit.c create mode 100644 src/libs/libunwind/ppc64/Lregs.c create mode 100644 src/libs/libunwind/ppc64/Lresume.c create mode 100644 src/libs/libunwind/ppc64/Lstep.c create mode 100644 src/libs/libunwind/ppc64/get_func_addr.c create mode 100644 src/libs/libunwind/ppc64/init.h create mode 100644 src/libs/libunwind/ppc64/is_fpreg.c create mode 100644 src/libs/libunwind/ppc64/regname.c create mode 100644 src/libs/libunwind/ppc64/setcontext.S create mode 100644 src/libs/libunwind/ppc64/ucontext_i.h create mode 100644 src/libs/libunwind/ppc64/unwind_i.h create mode 100644 src/libs/libunwind/ptrace/_UPT_access_fpreg.c create mode 100644 src/libs/libunwind/ptrace/_UPT_access_mem.c create mode 100644 src/libs/libunwind/ptrace/_UPT_access_reg.c create mode 100644 src/libs/libunwind/ptrace/_UPT_accessors.c create mode 100644 src/libs/libunwind/ptrace/_UPT_create.c create mode 100644 src/libs/libunwind/ptrace/_UPT_destroy.c create mode 100644 src/libs/libunwind/ptrace/_UPT_elf.c create mode 100644 src/libs/libunwind/ptrace/_UPT_find_proc_info.c create mode 100644 src/libs/libunwind/ptrace/_UPT_get_dyn_info_list_addr.c create mode 100644 src/libs/libunwind/ptrace/_UPT_get_proc_name.c create mode 100644 src/libs/libunwind/ptrace/_UPT_internal.h create mode 100644 src/libs/libunwind/ptrace/_UPT_put_unwind_info.c create mode 100644 src/libs/libunwind/ptrace/_UPT_reg_offset.c create mode 100644 src/libs/libunwind/ptrace/_UPT_resume.c create mode 100644 src/libs/libunwind/setjmp/longjmp.c create mode 100644 src/libs/libunwind/setjmp/setjmp.c create mode 100644 src/libs/libunwind/setjmp/setjmp_i.h create mode 100644 src/libs/libunwind/setjmp/siglongjmp.c create mode 100644 src/libs/libunwind/setjmp/sigsetjmp.c create mode 100644 src/libs/libunwind/sh/Gcreate_addr_space.c create mode 100644 src/libs/libunwind/sh/Gget_proc_info.c create mode 100644 src/libs/libunwind/sh/Gget_save_loc.c create mode 100644 src/libs/libunwind/sh/Gglobal.c create mode 100644 src/libs/libunwind/sh/Ginit.c create mode 100644 src/libs/libunwind/sh/Ginit_local.c create mode 100644 src/libs/libunwind/sh/Ginit_remote.c create mode 100644 src/libs/libunwind/sh/Gis_signal_frame.c create mode 100644 src/libs/libunwind/sh/Gregs.c create mode 100644 src/libs/libunwind/sh/Gresume.c create mode 100644 src/libs/libunwind/sh/Gstep.c create mode 100644 src/libs/libunwind/sh/Lcreate_addr_space.c create mode 100644 src/libs/libunwind/sh/Lget_proc_info.c create mode 100644 src/libs/libunwind/sh/Lget_save_loc.c create mode 100644 src/libs/libunwind/sh/Lglobal.c create mode 100644 src/libs/libunwind/sh/Linit.c create mode 100644 src/libs/libunwind/sh/Linit_local.c create mode 100644 src/libs/libunwind/sh/Linit_remote.c create mode 100644 src/libs/libunwind/sh/Lis_signal_frame.c create mode 100644 src/libs/libunwind/sh/Lregs.c create mode 100644 src/libs/libunwind/sh/Lresume.c create mode 100644 src/libs/libunwind/sh/Lstep.c create mode 100644 src/libs/libunwind/sh/gen-offsets.c create mode 100644 src/libs/libunwind/sh/init.h create mode 100644 src/libs/libunwind/sh/is_fpreg.c create mode 100644 src/libs/libunwind/sh/offsets.h create mode 100644 src/libs/libunwind/sh/regname.c create mode 100644 src/libs/libunwind/sh/siglongjmp.S create mode 100644 src/libs/libunwind/sh/unwind_i.h create mode 100644 src/libs/libunwind/tilegx/Gcreate_addr_space.c create mode 100644 src/libs/libunwind/tilegx/Gget_proc_info.c create mode 100644 src/libs/libunwind/tilegx/Gget_save_loc.c create mode 100644 src/libs/libunwind/tilegx/Gglobal.c create mode 100644 src/libs/libunwind/tilegx/Ginit.c create mode 100644 src/libs/libunwind/tilegx/Ginit_local.c create mode 100644 src/libs/libunwind/tilegx/Ginit_remote.c create mode 100644 src/libs/libunwind/tilegx/Gis_signal_frame.c create mode 100644 src/libs/libunwind/tilegx/Gregs.c create mode 100644 src/libs/libunwind/tilegx/Gresume.c create mode 100644 src/libs/libunwind/tilegx/Gstep.c create mode 100644 src/libs/libunwind/tilegx/Lcreate_addr_space.c create mode 100644 src/libs/libunwind/tilegx/Lget_proc_info.c create mode 100644 src/libs/libunwind/tilegx/Lget_save_loc.c create mode 100644 src/libs/libunwind/tilegx/Lglobal.c create mode 100644 src/libs/libunwind/tilegx/Linit.c create mode 100644 src/libs/libunwind/tilegx/Linit_local.c create mode 100644 src/libs/libunwind/tilegx/Linit_remote.c create mode 100644 src/libs/libunwind/tilegx/Lis_signal_frame.c create mode 100644 src/libs/libunwind/tilegx/Lregs.c create mode 100644 src/libs/libunwind/tilegx/Lresume.c create mode 100644 src/libs/libunwind/tilegx/Lstep.c create mode 100644 src/libs/libunwind/tilegx/elfxx.c create mode 100644 src/libs/libunwind/tilegx/gen-offsets.c create mode 100644 src/libs/libunwind/tilegx/getcontext.S create mode 100644 src/libs/libunwind/tilegx/init.h create mode 100644 src/libs/libunwind/tilegx/is_fpreg.c create mode 100644 src/libs/libunwind/tilegx/offsets.h create mode 100644 src/libs/libunwind/tilegx/regname.c create mode 100644 src/libs/libunwind/tilegx/siglongjmp.S create mode 100644 src/libs/libunwind/tilegx/unwind_i.h create mode 100644 src/libs/libunwind/unwind/Backtrace.c create mode 100644 src/libs/libunwind/unwind/DeleteException.c create mode 100644 src/libs/libunwind/unwind/FindEnclosingFunction.c create mode 100644 src/libs/libunwind/unwind/ForcedUnwind.c create mode 100644 src/libs/libunwind/unwind/GetBSP.c create mode 100644 src/libs/libunwind/unwind/GetCFA.c create mode 100644 src/libs/libunwind/unwind/GetDataRelBase.c create mode 100644 src/libs/libunwind/unwind/GetGR.c create mode 100644 src/libs/libunwind/unwind/GetIP.c create mode 100644 src/libs/libunwind/unwind/GetIPInfo.c create mode 100644 src/libs/libunwind/unwind/GetLanguageSpecificData.c create mode 100644 src/libs/libunwind/unwind/GetRegionStart.c create mode 100644 src/libs/libunwind/unwind/GetTextRelBase.c create mode 100644 src/libs/libunwind/unwind/RaiseException.c create mode 100644 src/libs/libunwind/unwind/Resume.c create mode 100644 src/libs/libunwind/unwind/Resume_or_Rethrow.c create mode 100644 src/libs/libunwind/unwind/SetGR.c create mode 100644 src/libs/libunwind/unwind/SetIP.c create mode 100644 src/libs/libunwind/unwind/unwind-internal.h create mode 100644 src/libs/libunwind/x86/Gcreate_addr_space.c create mode 100644 src/libs/libunwind/x86/Gget_proc_info.c create mode 100644 src/libs/libunwind/x86/Gget_save_loc.c create mode 100644 src/libs/libunwind/x86/Gglobal.c create mode 100644 src/libs/libunwind/x86/Ginit.c create mode 100644 src/libs/libunwind/x86/Ginit_local.c create mode 100644 src/libs/libunwind/x86/Ginit_remote.c create mode 100644 src/libs/libunwind/x86/Gos-freebsd.c create mode 100644 src/libs/libunwind/x86/Gos-linux.c create mode 100644 src/libs/libunwind/x86/Gregs.c create mode 100644 src/libs/libunwind/x86/Gresume.c create mode 100644 src/libs/libunwind/x86/Gstep.c create mode 100644 src/libs/libunwind/x86/Lcreate_addr_space.c create mode 100644 src/libs/libunwind/x86/Lget_proc_info.c create mode 100644 src/libs/libunwind/x86/Lget_save_loc.c create mode 100644 src/libs/libunwind/x86/Lglobal.c create mode 100644 src/libs/libunwind/x86/Linit.c create mode 100644 src/libs/libunwind/x86/Linit_local.c create mode 100644 src/libs/libunwind/x86/Linit_remote.c create mode 100644 src/libs/libunwind/x86/Los-freebsd.c create mode 100644 src/libs/libunwind/x86/Los-linux.c create mode 100644 src/libs/libunwind/x86/Lregs.c create mode 100644 src/libs/libunwind/x86/Lresume.c create mode 100644 src/libs/libunwind/x86/Lstep.c create mode 100644 src/libs/libunwind/x86/getcontext-freebsd.S create mode 100644 src/libs/libunwind/x86/getcontext-linux.S create mode 100644 src/libs/libunwind/x86/init.h create mode 100644 src/libs/libunwind/x86/is_fpreg.c create mode 100644 src/libs/libunwind/x86/longjmp.S create mode 100644 src/libs/libunwind/x86/offsets.h create mode 100644 src/libs/libunwind/x86/regname.c create mode 100644 src/libs/libunwind/x86/siglongjmp.S create mode 100644 src/libs/libunwind/x86/unwind_i.h create mode 100644 src/libs/libunwind/x86_64/Gcreate_addr_space.c create mode 100644 src/libs/libunwind/x86_64/Gget_proc_info.c create mode 100644 src/libs/libunwind/x86_64/Gget_save_loc.c create mode 100644 src/libs/libunwind/x86_64/Gglobal.c create mode 100644 src/libs/libunwind/x86_64/Ginit.c create mode 100644 src/libs/libunwind/x86_64/Ginit_local.c create mode 100644 src/libs/libunwind/x86_64/Ginit_remote.c create mode 100644 src/libs/libunwind/x86_64/Gos-freebsd.c create mode 100644 src/libs/libunwind/x86_64/Gos-linux.c create mode 100644 src/libs/libunwind/x86_64/Gos-solaris.c create mode 100644 src/libs/libunwind/x86_64/Gregs.c create mode 100644 src/libs/libunwind/x86_64/Gresume.c create mode 100644 src/libs/libunwind/x86_64/Gstash_frame.c create mode 100644 src/libs/libunwind/x86_64/Gstep.c create mode 100644 src/libs/libunwind/x86_64/Gtrace.c create mode 100644 src/libs/libunwind/x86_64/Lcreate_addr_space.c create mode 100644 src/libs/libunwind/x86_64/Lget_proc_info.c create mode 100644 src/libs/libunwind/x86_64/Lget_save_loc.c create mode 100644 src/libs/libunwind/x86_64/Lglobal.c create mode 100644 src/libs/libunwind/x86_64/Linit.c create mode 100644 src/libs/libunwind/x86_64/Linit_local.c create mode 100644 src/libs/libunwind/x86_64/Linit_remote.c create mode 100644 src/libs/libunwind/x86_64/Los-freebsd.c create mode 100644 src/libs/libunwind/x86_64/Los-linux.c create mode 100644 src/libs/libunwind/x86_64/Los-solaris.c create mode 100644 src/libs/libunwind/x86_64/Lregs.c create mode 100644 src/libs/libunwind/x86_64/Lresume.c create mode 100644 src/libs/libunwind/x86_64/Lstash_frame.c create mode 100644 src/libs/libunwind/x86_64/Lstep.c create mode 100644 src/libs/libunwind/x86_64/Ltrace.c create mode 100644 src/libs/libunwind/x86_64/getcontext.S create mode 100644 src/libs/libunwind/x86_64/init.h create mode 100644 src/libs/libunwind/x86_64/is_fpreg.c create mode 100644 src/libs/libunwind/x86_64/longjmp.S create mode 100644 src/libs/libunwind/x86_64/offsets.h create mode 100644 src/libs/libunwind/x86_64/regname.c create mode 100644 src/libs/libunwind/x86_64/setcontext.S create mode 100644 src/libs/libunwind/x86_64/siglongjmp.S create mode 100644 src/libs/libunwind/x86_64/ucontext_i.h create mode 100644 src/libs/libunwind/x86_64/unwind_i.h diff --git a/headers/libs/libunwind/compiler.h b/headers/libs/libunwind/compiler.h new file mode 100644 index 0000000000..abd424d8ab --- /dev/null +++ b/headers/libs/libunwind/compiler.h @@ -0,0 +1,74 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Compiler specific useful bits that are used in libunwind, and also in the + * tests. */ + +#ifndef COMPILER_H +#define COMPILER_H + +#ifdef __GNUC__ +# define ALIGNED(x) __attribute__((aligned(x))) +# define CONST_ATTR __attribute__((__const__)) +# define UNUSED __attribute__((unused)) +# define NOINLINE __attribute__((noinline)) +# define NORETURN __attribute__((noreturn)) +# define ALIAS(name) __attribute__((alias (#name))) +# if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) +# define ALWAYS_INLINE inline __attribute__((always_inline)) +# define HIDDEN __attribute__((visibility ("hidden"))) +# define PROTECTED __attribute__((visibility ("protected"))) +# else +# define ALWAYS_INLINE +# define HIDDEN +# define PROTECTED +# endif +# define WEAK __attribute__((weak)) +# if (__GNUC__ >= 3) +# define likely(x) __builtin_expect ((x), 1) +# define unlikely(x) __builtin_expect ((x), 0) +# else +# define likely(x) (x) +# define unlikely(x) (x) +# endif +#else +# define ALIGNED(x) +# define ALWAYS_INLINE +# define CONST_ATTR +# define UNUSED +# define NOINLINE +# define NORETURN +# define ALIAS(name) +# define HIDDEN +# define PROTECTED +# define WEAK +# define likely(x) (x) +# define unlikely(x) (x) +#endif + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) + +#endif /* COMPILER_H */ diff --git a/headers/libs/libunwind/dwarf-eh.h b/headers/libs/libunwind/dwarf-eh.h new file mode 100644 index 0000000000..e81aaef88a --- /dev/null +++ b/headers/libs/libunwind/dwarf-eh.h @@ -0,0 +1,128 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef dwarf_eh_h +#define dwarf_eh_h + +#include "dwarf.h" + +/* This header file defines the format of a DWARF exception-header + section (.eh_frame_hdr, pointed to by program-header + PT_GNU_EH_FRAME). The exception-header is self-describing in the + sense that the format of the addresses contained in it is expressed + as a one-byte type-descriptor called a "pointer-encoding" (PE). + + The exception header encodes the address of the .eh_frame section + and optionally contains a binary search table for the + Frame Descriptor Entries (FDEs) in the .eh_frame. The contents of + .eh_frame has the format described by the DWARF v3 standard + (http://www.eagercon.com/dwarf/dwarf3std.htm), except that code + addresses may be encoded in different ways. Also, .eh_frame has + augmentations that allow encoding a language-specific data-area + (LSDA) pointer and a pointer to a personality-routine. + + Details: + + The Common Information Entry (CIE) associated with an FDE may + contain an augmentation string. Each character in this string has + a specific meaning and either one or two associated operands. The + operands are stored in an augmentation body which appears right + after the "return_address_register" member and before the + "initial_instructions" member. The operands appear in the order + in which the characters appear in the string. For example, if the + augmentation string is "zL", the operand for 'z' would be first in + the augmentation body and the operand for 'L' would be second. + The following characters are supported for the CIE augmentation + string: + + 'z': The operand for this character is a uleb128 value that gives the + length of the CIE augmentation body, not counting the length + of the uleb128 operand itself. If present, this code must + appear as the first character in the augmentation body. + + 'L': Indicates that the FDE's augmentation body contains an LSDA + pointer. The operand for this character is a single byte + that specifies the pointer-encoding (PE) that is used for + the LSDA pointer. + + 'R': Indicates that the code-pointers (FDE members + "initial_location" and "address_range" and the operand for + DW_CFA_set_loc) in the FDE have a non-default encoding. The + operand for this character is a single byte that specifies + the pointer-encoding (PE) that is used for the + code-pointers. Note: the "address_range" member is always + encoded as an absolute value. Apart from that, the specified + FDE pointer-encoding applies. + + 'P': Indicates the presence of a personality routine (handler). + The first operand for this character specifies the + pointer-encoding (PE) that is used for the second operand, + which specifies the address of the personality routine. + + If the augmentation string contains any other characters, the + remainder of the augmentation string should be ignored. + Furthermore, if the size of the augmentation body is unknown + (i.e., 'z' is not the first character of the augmentation string), + then the entire CIE as well all associated FDEs must be ignored. + + A Frame Descriptor Entries (FDE) may contain an augmentation body + which, if present, appears right after the "address_range" member + and before the "instructions" member. The contents of this body + is implicitly defined by the augmentation string of the associated + CIE. The meaning of the characters in the CIE's augmentation + string as far as FDEs are concerned is as follows: + + 'z': The first operand in the FDE's augmentation body specifies + the total length of the augmentation body as a uleb128 (not + counting the length of the uleb128 operand itself). + + 'L': The operand for this character is an LSDA pointer, encoded + in the format specified by the corresponding operand in the + CIE's augmentation body. + +*/ + +#define DW_EH_VERSION 1 /* The version we're implementing */ + +struct dwarf_eh_frame_hdr + { + unsigned char version; + unsigned char eh_frame_ptr_enc; + unsigned char fde_count_enc; + unsigned char table_enc; + /* The rest of the header is variable-length and consists of the + following members: + + encoded_t eh_frame_ptr; + encoded_t fde_count; + struct + { + encoded_t start_ip; // first address covered by this FDE + encoded_t fde_addr; // address of the FDE + } + binary_search_table[fde_count]; */ + }; + +#endif /* dwarf_eh_h */ diff --git a/headers/libs/libunwind/dwarf.h b/headers/libs/libunwind/dwarf.h new file mode 100644 index 0000000000..a72c31b574 --- /dev/null +++ b/headers/libs/libunwind/dwarf.h @@ -0,0 +1,444 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef dwarf_h +#define dwarf_h + +#include + +struct dwarf_cursor; /* forward-declaration */ +struct elf_dyn_info; + +#include "dwarf-config.h" + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE___THREAD + /* For now, turn off per-thread caching. It uses up too much TLS + memory per thread even when the thread never uses libunwind at + all. */ +# undef HAVE___THREAD +#endif + +#ifndef UNW_REMOTE_ONLY + #if defined(HAVE_LINK_H) + #include + #elif defined(HAVE_SYS_LINK_H) + #include + #else + #error Could not find + #endif +#endif + +#include + +/* DWARF expression opcodes. */ + +typedef enum + { + DW_OP_addr = 0x03, + DW_OP_deref = 0x06, + DW_OP_const1u = 0x08, + DW_OP_const1s = 0x09, + DW_OP_const2u = 0x0a, + DW_OP_const2s = 0x0b, + DW_OP_const4u = 0x0c, + DW_OP_const4s = 0x0d, + DW_OP_const8u = 0x0e, + DW_OP_const8s = 0x0f, + DW_OP_constu = 0x10, + DW_OP_consts = 0x11, + DW_OP_dup = 0x12, + DW_OP_drop = 0x13, + DW_OP_over = 0x14, + DW_OP_pick = 0x15, + DW_OP_swap = 0x16, + DW_OP_rot = 0x17, + DW_OP_xderef = 0x18, + DW_OP_abs = 0x19, + DW_OP_and = 0x1a, + DW_OP_div = 0x1b, + DW_OP_minus = 0x1c, + DW_OP_mod = 0x1d, + DW_OP_mul = 0x1e, + DW_OP_neg = 0x1f, + DW_OP_not = 0x20, + DW_OP_or = 0x21, + DW_OP_plus = 0x22, + DW_OP_plus_uconst = 0x23, + DW_OP_shl = 0x24, + DW_OP_shr = 0x25, + DW_OP_shra = 0x26, + DW_OP_xor = 0x27, + DW_OP_skip = 0x2f, + DW_OP_bra = 0x28, + DW_OP_eq = 0x29, + DW_OP_ge = 0x2a, + DW_OP_gt = 0x2b, + DW_OP_le = 0x2c, + DW_OP_lt = 0x2d, + DW_OP_ne = 0x2e, + DW_OP_lit0 = 0x30, + DW_OP_lit1, DW_OP_lit2, DW_OP_lit3, DW_OP_lit4, DW_OP_lit5, + DW_OP_lit6, DW_OP_lit7, DW_OP_lit8, DW_OP_lit9, DW_OP_lit10, + DW_OP_lit11, DW_OP_lit12, DW_OP_lit13, DW_OP_lit14, DW_OP_lit15, + DW_OP_lit16, DW_OP_lit17, DW_OP_lit18, DW_OP_lit19, DW_OP_lit20, + DW_OP_lit21, DW_OP_lit22, DW_OP_lit23, DW_OP_lit24, DW_OP_lit25, + DW_OP_lit26, DW_OP_lit27, DW_OP_lit28, DW_OP_lit29, DW_OP_lit30, + DW_OP_lit31, + DW_OP_reg0 = 0x50, + DW_OP_reg1, DW_OP_reg2, DW_OP_reg3, DW_OP_reg4, DW_OP_reg5, + DW_OP_reg6, DW_OP_reg7, DW_OP_reg8, DW_OP_reg9, DW_OP_reg10, + DW_OP_reg11, DW_OP_reg12, DW_OP_reg13, DW_OP_reg14, DW_OP_reg15, + DW_OP_reg16, DW_OP_reg17, DW_OP_reg18, DW_OP_reg19, DW_OP_reg20, + DW_OP_reg21, DW_OP_reg22, DW_OP_reg23, DW_OP_reg24, DW_OP_reg25, + DW_OP_reg26, DW_OP_reg27, DW_OP_reg28, DW_OP_reg29, DW_OP_reg30, + DW_OP_reg31, + DW_OP_breg0 = 0x70, + DW_OP_breg1, DW_OP_breg2, DW_OP_breg3, DW_OP_breg4, DW_OP_breg5, + DW_OP_breg6, DW_OP_breg7, DW_OP_breg8, DW_OP_breg9, DW_OP_breg10, + DW_OP_breg11, DW_OP_breg12, DW_OP_breg13, DW_OP_breg14, DW_OP_breg15, + DW_OP_breg16, DW_OP_breg17, DW_OP_breg18, DW_OP_breg19, DW_OP_breg20, + DW_OP_breg21, DW_OP_breg22, DW_OP_breg23, DW_OP_breg24, DW_OP_breg25, + DW_OP_breg26, DW_OP_breg27, DW_OP_breg28, DW_OP_breg29, DW_OP_breg30, + DW_OP_breg31, + DW_OP_regx = 0x90, + DW_OP_fbreg = 0x91, + DW_OP_bregx = 0x92, + DW_OP_piece = 0x93, + DW_OP_deref_size = 0x94, + DW_OP_xderef_size = 0x95, + DW_OP_nop = 0x96, + DW_OP_push_object_address = 0x97, + DW_OP_call2 = 0x98, + DW_OP_call4 = 0x99, + DW_OP_call_ref = 0x9a, + DW_OP_lo_user = 0xe0, + DW_OP_hi_user = 0xff + } +dwarf_expr_op_t; + +#define DWARF_CIE_VERSION 3 /* GCC emits version 1??? */ + +#define DWARF_CFA_OPCODE_MASK 0xc0 +#define DWARF_CFA_OPERAND_MASK 0x3f + +typedef enum + { + DW_CFA_advance_loc = 0x40, + DW_CFA_offset = 0x80, + DW_CFA_restore = 0xc0, + DW_CFA_nop = 0x00, + DW_CFA_set_loc = 0x01, + DW_CFA_advance_loc1 = 0x02, + DW_CFA_advance_loc2 = 0x03, + DW_CFA_advance_loc4 = 0x04, + DW_CFA_offset_extended = 0x05, + DW_CFA_restore_extended = 0x06, + DW_CFA_undefined = 0x07, + DW_CFA_same_value = 0x08, + DW_CFA_register = 0x09, + DW_CFA_remember_state = 0x0a, + DW_CFA_restore_state = 0x0b, + DW_CFA_def_cfa = 0x0c, + DW_CFA_def_cfa_register = 0x0d, + DW_CFA_def_cfa_offset = 0x0e, + DW_CFA_def_cfa_expression = 0x0f, + DW_CFA_expression = 0x10, + DW_CFA_offset_extended_sf = 0x11, + DW_CFA_def_cfa_sf = 0x12, + DW_CFA_def_cfa_offset_sf = 0x13, + DW_CFA_val_expression = 0x16, + DW_CFA_lo_user = 0x1c, + DW_CFA_MIPS_advance_loc8 = 0x1d, + DW_CFA_GNU_window_save = 0x2d, + DW_CFA_GNU_args_size = 0x2e, + DW_CFA_GNU_negative_offset_extended = 0x2f, + DW_CFA_hi_user = 0x3c + } +dwarf_cfa_t; + +/* DWARF Pointer-Encoding (PEs). + + Pointer-Encodings were invented for the GCC exception-handling + support for C++, but they represent a rather generic way of + describing the format in which an address/pointer is stored and + hence we include the definitions here, in the main dwarf.h file. + The Pointer-Encoding format is partially documented in Linux Base + Spec v1.3 (http://www.linuxbase.org/spec/). The rest is reverse + engineered from GCC. + +*/ +#define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */ +#define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */ +/* Flag bit. If set, the resulting pointer is the address of the word + that contains the final address. */ +#define DW_EH_PE_indirect 0x80 + +/* Pointer-encoding formats: */ +#define DW_EH_PE_omit 0xff +#define DW_EH_PE_ptr 0x00 /* pointer-sized unsigned value */ +#define DW_EH_PE_uleb128 0x01 /* unsigned LE base-128 value */ +#define DW_EH_PE_udata2 0x02 /* unsigned 16-bit value */ +#define DW_EH_PE_udata4 0x03 /* unsigned 32-bit value */ +#define DW_EH_PE_udata8 0x04 /* unsigned 64-bit value */ +#define DW_EH_PE_sleb128 0x09 /* signed LE base-128 value */ +#define DW_EH_PE_sdata2 0x0a /* signed 16-bit value */ +#define DW_EH_PE_sdata4 0x0b /* signed 32-bit value */ +#define DW_EH_PE_sdata8 0x0c /* signed 64-bit value */ + +/* Pointer-encoding application: */ +#define DW_EH_PE_absptr 0x00 /* absolute value */ +#define DW_EH_PE_pcrel 0x10 /* rel. to addr. of encoded value */ +#define DW_EH_PE_textrel 0x20 /* text-relative (GCC-specific???) */ +#define DW_EH_PE_datarel 0x30 /* data-relative */ +/* The following are not documented by LSB v1.3, yet they are used by + GCC, presumably they aren't documented by LSB since they aren't + used on Linux: */ +#define DW_EH_PE_funcrel 0x40 /* start-of-procedure-relative */ +#define DW_EH_PE_aligned 0x50 /* aligned pointer */ + +extern struct mempool dwarf_reg_state_pool; +extern struct mempool dwarf_cie_info_pool; + +typedef enum + { + DWARF_WHERE_UNDEF, /* register isn't saved at all */ + DWARF_WHERE_SAME, /* register has same value as in prev. frame */ + DWARF_WHERE_CFAREL, /* register saved at CFA-relative address */ + DWARF_WHERE_REG, /* register saved in another register */ + DWARF_WHERE_EXPR, /* register saved */ + DWARF_WHERE_VAL_EXPR, /* register has computed value */ + } +dwarf_where_t; + +typedef struct + { + dwarf_where_t where; /* how is the register saved? */ + unw_word_t val; /* where it's saved */ + } +dwarf_save_loc_t; + +/* For uniformity, we'd like to treat the CFA save-location like any + other register save-location, but this doesn't quite work, because + the CFA can be expressed as a (REGISTER,OFFSET) pair. To handle + this, we use two dwarf_save_loc structures to describe the CFA. + The first one (CFA_REG_COLUMN), tells us where the CFA is saved. + In the case of DWARF_WHERE_EXPR, the CFA is defined by a DWARF + location expression whose address is given by member "val". In the + case of DWARF_WHERE_REG, member "val" gives the number of the + base-register and the "val" member of DWARF_CFA_OFF_COLUMN gives + the offset value. */ +#define DWARF_CFA_REG_COLUMN DWARF_NUM_PRESERVED_REGS +#define DWARF_CFA_OFF_COLUMN (DWARF_NUM_PRESERVED_REGS + 1) + +typedef struct dwarf_reg_state + { + struct dwarf_reg_state *next; /* for rs_stack */ + dwarf_save_loc_t reg[DWARF_NUM_PRESERVED_REGS + 2]; + unw_word_t ip; /* ip this rs is for */ + unw_word_t ret_addr_column; /* indicates which column in the rule table represents return address */ + unsigned short lru_chain; /* used for least-recently-used chain */ + unsigned short coll_chain; /* used for hash collisions */ + unsigned short hint; /* hint for next rs to try (or -1) */ + unsigned short valid : 1; /* optional machine-dependent signal info */ + unsigned short signal_frame : 1; /* optional machine-dependent signal info */ + } +dwarf_reg_state_t; + +typedef struct dwarf_cie_info + { + unw_word_t cie_instr_start; /* start addr. of CIE "initial_instructions" */ + unw_word_t cie_instr_end; /* end addr. of CIE "initial_instructions" */ + unw_word_t fde_instr_start; /* start addr. of FDE "instructions" */ + unw_word_t fde_instr_end; /* end addr. of FDE "instructions" */ + unw_word_t code_align; /* code-alignment factor */ + unw_word_t data_align; /* data-alignment factor */ + unw_word_t ret_addr_column; /* column of return-address register */ + unw_word_t handler; /* address of personality-routine */ + uint16_t abi; + uint16_t tag; + uint8_t fde_encoding; + uint8_t lsda_encoding; + unsigned int sized_augmentation : 1; + unsigned int have_abi_marker : 1; + unsigned int signal_frame : 1; + } +dwarf_cie_info_t; + +typedef struct dwarf_state_record + { + unsigned char fde_encoding; + unw_word_t args_size; + + dwarf_reg_state_t rs_initial; /* reg-state after CIE instructions */ + dwarf_reg_state_t rs_current; /* current reg-state */ + } +dwarf_state_record_t; + +typedef struct dwarf_cursor + { + void *as_arg; /* argument to address-space callbacks */ + unw_addr_space_t as; /* reference to per-address-space info */ + + unw_word_t cfa; /* canonical frame address; aka frame-/stack-pointer */ + unw_word_t ip; /* instruction pointer */ + unw_word_t args_size; /* size of arguments */ + unw_word_t ret_addr_column; /* column for return-address */ + unw_word_t eh_args[UNW_TDEP_NUM_EH_REGS]; + unsigned int eh_valid_mask; + + dwarf_loc_t loc[DWARF_NUM_PRESERVED_REGS]; + + unsigned int stash_frames :1; /* stash frames for fast lookup */ + unsigned int use_prev_instr :1; /* use previous (= call) or current (= signal) instruction? */ + unsigned int pi_valid :1; /* is proc_info valid? */ + unsigned int pi_is_dynamic :1; /* proc_info found via dynamic proc info? */ + unw_proc_info_t pi; /* info about current procedure */ + + short hint; /* faster lookup of the rs cache */ + short prev_rs; + } +dwarf_cursor_t; + +#define DWARF_LOG_UNW_CACHE_SIZE 7 +#define DWARF_UNW_CACHE_SIZE (1 << DWARF_LOG_UNW_CACHE_SIZE) + +#define DWARF_LOG_UNW_HASH_SIZE (DWARF_LOG_UNW_CACHE_SIZE + 1) +#define DWARF_UNW_HASH_SIZE (1 << DWARF_LOG_UNW_HASH_SIZE) + +typedef unsigned char unw_hash_index_t; + +struct dwarf_rs_cache + { + pthread_mutex_t lock; + unsigned short lru_head; /* index of lead-recently used rs */ + unsigned short lru_tail; /* index of most-recently used rs */ + + /* hash table that maps instruction pointer to rs index: */ + unsigned short hash[DWARF_UNW_HASH_SIZE]; + + uint32_t generation; /* generation number */ + + /* rs cache: */ + dwarf_reg_state_t buckets[DWARF_UNW_CACHE_SIZE]; + }; + +/* A list of descriptors for loaded .debug_frame sections. */ + +struct unw_debug_frame_list + { + /* The start (inclusive) and end (exclusive) of the described region. */ + unw_word_t start; + unw_word_t end; + /* The debug frame itself. */ + char *debug_frame; + size_t debug_frame_size; + /* Index (for binary search). */ + struct table_entry *index; + size_t index_size; + /* Pointer to next descriptor. */ + struct unw_debug_frame_list *next; + }; + +struct dwarf_callback_data + { + /* in: */ + unw_word_t ip; /* instruction-pointer we're looking for */ + int need_unwind_info; + void *arg; + /* out: */ + unw_word_t fde_addr; + unw_word_t fde_base; + unw_word_t ip_offset; + unw_word_t gp; + }; + +/* Convenience macros: */ +#define dwarf_init UNW_ARCH_OBJ (dwarf_init) +#define dwarf_callback UNW_OBJ (dwarf_callback) +#define dwarf_find_proc_info UNW_OBJ (dwarf_find_proc_info) +#define dwarf_find_debug_frame UNW_OBJ (dwarf_find_debug_frame) +#define dwarf_search_unwind_table UNW_OBJ (dwarf_search_unwind_table) +#define dwarf_find_unwind_table UNW_OBJ (dwarf_find_unwind_table) +#define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info) +#define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info) +#define dwarf_eval_expr UNW_OBJ (dwarf_eval_expr) +#define dwarf_extract_proc_info_from_fde \ + UNW_OBJ (dwarf_extract_proc_info_from_fde) +#define dwarf_find_save_locs UNW_OBJ (dwarf_find_save_locs) +#define dwarf_create_state_record UNW_OBJ (dwarf_create_state_record) +#define dwarf_make_proc_info UNW_OBJ (dwarf_make_proc_info) +#define dwarf_read_encoded_pointer UNW_OBJ (dwarf_read_encoded_pointer) +#define dwarf_step UNW_OBJ (dwarf_step) + +extern int dwarf_init (void); +#ifndef UNW_REMOTE_ONLY +extern int dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr); +extern int dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, + int need_unwind_info, void *arg); +#endif /* !UNW_REMOTE_ONLY */ +extern int dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, + unw_word_t ip, unw_word_t segbase, + const char* obj_name, unw_word_t start, + unw_word_t end); +extern int dwarf_search_unwind_table (unw_addr_space_t as, + unw_word_t ip, + unw_dyn_info_t *di, + unw_proc_info_t *pi, + int need_unwind_info, void *arg); +extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, + char *path, unw_word_t segbase, unw_word_t mapoff, + unw_word_t ip); +extern void dwarf_put_unwind_info (unw_addr_space_t as, + unw_proc_info_t *pi, void *arg); +extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, + unw_word_t len, unw_word_t *valp, + int *is_register); +extern int dwarf_extract_proc_info_from_fde (unw_addr_space_t as, + unw_accessors_t *a, + unw_word_t *fde_addr, + unw_proc_info_t *pi, + unw_word_t base, + int need_unwind_info, + int is_debug_frame, + void *arg); +extern int dwarf_find_save_locs (struct dwarf_cursor *c); +extern int dwarf_create_state_record (struct dwarf_cursor *c, + dwarf_state_record_t *sr); +extern int dwarf_make_proc_info (struct dwarf_cursor *c); +extern int dwarf_read_encoded_pointer (unw_addr_space_t as, + unw_accessors_t *a, + unw_word_t *addr, + unsigned char encoding, + unw_word_t gp, + unw_word_t start_ip, + unw_word_t *valp, void *arg); +extern int dwarf_step (struct dwarf_cursor *c); + +#endif /* dwarf_h */ diff --git a/headers/libs/libunwind/dwarf_i.h b/headers/libs/libunwind/dwarf_i.h new file mode 100644 index 0000000000..0ac0d2a256 --- /dev/null +++ b/headers/libs/libunwind/dwarf_i.h @@ -0,0 +1,490 @@ +#ifndef DWARF_I_H +#define DWARF_I_H + +/* This file contains definitions that cannot be used in code outside + of libunwind. In particular, most inline functions are here + because otherwise they'd generate unresolved references when the + files are compiled with inlining disabled. */ + +#include "dwarf.h" +#include "libunwind_i.h" + +/* Unless we are told otherwise, assume that a "machine address" is + the size of an unw_word_t. */ +#ifndef dwarf_addr_size +# define dwarf_addr_size(as) (sizeof (unw_word_t)) +#endif + +#ifndef dwarf_to_unw_regnum +# define dwarf_to_unw_regnum_map UNW_OBJ (dwarf_to_unw_regnum_map) +extern const uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH]; +/* REG is evaluated multiple times; it better be side-effects free! */ +# define dwarf_to_unw_regnum(reg) \ + (((reg) < DWARF_REGNUM_MAP_LENGTH) ? dwarf_to_unw_regnum_map[reg] : 0) +#endif + +#ifdef UNW_LOCAL_ONLY + +/* In the local-only case, we can let the compiler directly access + memory and don't need to worry about differing byte-order. */ + +typedef union __attribute__ ((packed)) + { + int8_t s8; + int16_t s16; + int32_t s32; + int64_t s64; + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint64_t u64; + void *ptr; + } +dwarf_misaligned_value_t; + +static inline int +dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int8_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; + + *val = mvp->s8; + *addr += sizeof (mvp->s8); + return 0; +} + +static inline int +dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int16_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; + + *val = mvp->s16; + *addr += sizeof (mvp->s16); + return 0; +} + +static inline int +dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int32_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; + + *val = mvp->s32; + *addr += sizeof (mvp->s32); + return 0; +} + +static inline int +dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int64_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; + + *val = mvp->s64; + *addr += sizeof (mvp->s64); + return 0; +} + +static inline int +dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint8_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; + + *val = mvp->u8; + *addr += sizeof (mvp->u8); + return 0; +} + +static inline int +dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint16_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; + + *val = mvp->u16; + *addr += sizeof (mvp->u16); + return 0; +} + +static inline int +dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint32_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; + + *val = mvp->u32; + *addr += sizeof (mvp->u32); + return 0; +} + +static inline int +dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint64_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr; + + *val = mvp->u64; + *addr += sizeof (mvp->u64); + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ + +static inline int +dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint8_t *valp, void *arg) +{ + unw_word_t val, aligned_addr = *addr & -sizeof (unw_word_t); + unw_word_t off = *addr - aligned_addr; + int ret; + + *addr += 1; + ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg); +#if __BYTE_ORDER == __LITTLE_ENDIAN + val >>= 8*off; +#else + val >>= 8*(sizeof (unw_word_t) - 1 - off); +#endif + *valp = (uint8_t) val; + return ret; +} + +static inline int +dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint16_t *val, void *arg) +{ + uint8_t v0, v1; + int ret; + + if ((ret = dwarf_readu8 (as, a, addr, &v0, arg)) < 0 + || (ret = dwarf_readu8 (as, a, addr, &v1, arg)) < 0) + return ret; + + if (tdep_big_endian (as)) + *val = (uint16_t) v0 << 8 | v1; + else + *val = (uint16_t) v1 << 8 | v0; + return 0; +} + +static inline int +dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint32_t *val, void *arg) +{ + uint16_t v0, v1; + int ret; + + if ((ret = dwarf_readu16 (as, a, addr, &v0, arg)) < 0 + || (ret = dwarf_readu16 (as, a, addr, &v1, arg)) < 0) + return ret; + + if (tdep_big_endian (as)) + *val = (uint32_t) v0 << 16 | v1; + else + *val = (uint32_t) v1 << 16 | v0; + return 0; +} + +static inline int +dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint64_t *val, void *arg) +{ + uint32_t v0, v1; + int ret; + + if ((ret = dwarf_readu32 (as, a, addr, &v0, arg)) < 0 + || (ret = dwarf_readu32 (as, a, addr, &v1, arg)) < 0) + return ret; + + if (tdep_big_endian (as)) + *val = (uint64_t) v0 << 32 | v1; + else + *val = (uint64_t) v1 << 32 | v0; + return 0; +} + +static inline int +dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int8_t *val, void *arg) +{ + uint8_t uval; + int ret; + + if ((ret = dwarf_readu8 (as, a, addr, &uval, arg)) < 0) + return ret; + *val = (int8_t) uval; + return 0; +} + +static inline int +dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int16_t *val, void *arg) +{ + uint16_t uval; + int ret; + + if ((ret = dwarf_readu16 (as, a, addr, &uval, arg)) < 0) + return ret; + *val = (int16_t) uval; + return 0; +} + +static inline int +dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int32_t *val, void *arg) +{ + uint32_t uval; + int ret; + + if ((ret = dwarf_readu32 (as, a, addr, &uval, arg)) < 0) + return ret; + *val = (int32_t) uval; + return 0; +} + +static inline int +dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int64_t *val, void *arg) +{ + uint64_t uval; + int ret; + + if ((ret = dwarf_readu64 (as, a, addr, &uval, arg)) < 0) + return ret; + *val = (int64_t) uval; + return 0; +} + +#endif /* !UNW_LOCAL_ONLY */ + +static inline int +dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + unw_word_t *val, void *arg) +{ + uint32_t u32; + uint64_t u64; + int ret; + + switch (dwarf_addr_size (as)) + { + case 4: + ret = dwarf_readu32 (as, a, addr, &u32, arg); + if (ret < 0) + return ret; + *val = u32; + return ret; + + case 8: + ret = dwarf_readu64 (as, a, addr, &u64, arg); + if (ret < 0) + return ret; + *val = u64; + return ret; + + default: + abort (); + } +} + +/* Read an unsigned "little-endian base 128" value. See Chapter 7.6 + of DWARF spec v3. */ + +static inline int +dwarf_read_uleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + unw_word_t *valp, void *arg) +{ + unw_word_t val = 0, shift = 0; + unsigned char byte; + int ret; + + do + { + if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0) + return ret; + + val |= ((unw_word_t) byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + + *valp = val; + return 0; +} + +/* Read a signed "little-endian base 128" value. See Chapter 7.6 of + DWARF spec v3. */ + +static inline int +dwarf_read_sleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + unw_word_t *valp, void *arg) +{ + unw_word_t val = 0, shift = 0; + unsigned char byte; + int ret; + + do + { + if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0) + return ret; + + val |= ((unw_word_t) byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + + if (shift < 8 * sizeof (unw_word_t) && (byte & 0x40) != 0) + /* sign-extend negative value */ + val |= ((unw_word_t) -1) << shift; + + *valp = val; + return 0; +} + +static ALWAYS_INLINE int +dwarf_read_encoded_pointer_inlined (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, unsigned char encoding, + unw_word_t gp, unw_word_t start_ip, + unw_word_t *valp, void *arg) +{ + unw_word_t val, initial_addr = *addr; + uint16_t uval16; + uint32_t uval32; + uint64_t uval64; + int16_t sval16; + int32_t sval32; + int64_t sval64; + int ret; + + /* DW_EH_PE_omit and DW_EH_PE_aligned don't follow the normal + format/application encoding. Handle them first. */ + if (encoding == DW_EH_PE_omit) + { + *valp = 0; + return 0; + } + else if (encoding == DW_EH_PE_aligned) + { + int size = dwarf_addr_size (as); + *addr = (initial_addr + size - 1) & -size; + return dwarf_readw (as, a, addr, valp, arg); + } + + switch (encoding & DW_EH_PE_FORMAT_MASK) + { + case DW_EH_PE_ptr: + if ((ret = dwarf_readw (as, a, addr, &val, arg)) < 0) + return ret; + break; + + case DW_EH_PE_uleb128: + if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) + return ret; + break; + + case DW_EH_PE_udata2: + if ((ret = dwarf_readu16 (as, a, addr, &uval16, arg)) < 0) + return ret; + val = uval16; + break; + + case DW_EH_PE_udata4: + if ((ret = dwarf_readu32 (as, a, addr, &uval32, arg)) < 0) + return ret; + val = uval32; + break; + + case DW_EH_PE_udata8: + if ((ret = dwarf_readu64 (as, a, addr, &uval64, arg)) < 0) + return ret; + val = uval64; + break; + + case DW_EH_PE_sleb128: + if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) + return ret; + break; + + case DW_EH_PE_sdata2: + if ((ret = dwarf_reads16 (as, a, addr, &sval16, arg)) < 0) + return ret; + val = sval16; + break; + + case DW_EH_PE_sdata4: + if ((ret = dwarf_reads32 (as, a, addr, &sval32, arg)) < 0) + return ret; + val = sval32; + break; + + case DW_EH_PE_sdata8: + if ((ret = dwarf_reads64 (as, a, addr, &sval64, arg)) < 0) + return ret; + val = sval64; + break; + + default: + Debug (1, "unexpected encoding format 0x%x\n", + encoding & DW_EH_PE_FORMAT_MASK); + return -UNW_EINVAL; + } + + if (val == 0) + { + /* 0 is a special value and always absolute. */ + *valp = 0; + return 0; + } + + switch (encoding & DW_EH_PE_APPL_MASK) + { + case DW_EH_PE_absptr: + break; + + case DW_EH_PE_pcrel: + val += initial_addr; + break; + + case DW_EH_PE_datarel: + /* XXX For now, assume that data-relative addresses are relative + to the global pointer. */ + val += gp; + break; + + case DW_EH_PE_funcrel: + val += start_ip; + break; + + case DW_EH_PE_textrel: + /* XXX For now we don't support text-rel values. If there is a + platform which needs this, we probably would have to add a + "segbase" member to unw_proc_info_t. */ + default: + Debug (1, "unexpected application type 0x%x\n", + encoding & DW_EH_PE_APPL_MASK); + return -UNW_EINVAL; + } + + /* Trim off any extra bits. Assume that sign extension isn't + required; the only place it is needed is MIPS kernel space + addresses. */ + if (sizeof (val) > dwarf_addr_size (as)) + { + assert (dwarf_addr_size (as) == 4); + val = (uint32_t) val; + } + + if (encoding & DW_EH_PE_indirect) + { + unw_word_t indirect_addr = val; + + if ((ret = dwarf_readw (as, a, &indirect_addr, &val, arg)) < 0) + return ret; + } + + *valp = val; + return 0; +} + +#endif /* DWARF_I_H */ diff --git a/headers/libs/libunwind/libunwind-aarch64.h b/headers/libs/libunwind/libunwind-aarch64.h new file mode 100644 index 0000000000..cd01e5785f --- /dev/null +++ b/headers/libs/libunwind/libunwind-aarch64.h @@ -0,0 +1,187 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBUNWIND_H +#define LIBUNWIND_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include +#include +#include + +#define UNW_TARGET aarch64 +#define UNW_TARGET_AARCH64 1 + +#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ + +/* This needs to be big enough to accommodate "struct cursor", while + leaving some slack for future expansion. Changing this value will + require recompiling all users of this library. Stack allocation is + relatively cheap and unwind-state copying is relatively rare, so we + want to err on making it rather too big than too small. */ + +#define UNW_TDEP_CURSOR_LEN 4096 + +typedef uint64_t unw_word_t; +typedef int64_t unw_sword_t; + +typedef long double unw_tdep_fpreg_t; + +typedef struct + { + /* no aarch64-specific auxiliary proc-info */ + } +unw_tdep_proc_info_t; + +typedef enum + { + /* 64-bit general registers. */ + UNW_AARCH64_X0, + UNW_AARCH64_X1, + UNW_AARCH64_X2, + UNW_AARCH64_X3, + UNW_AARCH64_X4, + UNW_AARCH64_X5, + UNW_AARCH64_X6, + UNW_AARCH64_X7, + UNW_AARCH64_X8, + + /* Temporary registers. */ + UNW_AARCH64_X9, + UNW_AARCH64_X10, + UNW_AARCH64_X11, + UNW_AARCH64_X12, + UNW_AARCH64_X13, + UNW_AARCH64_X14, + UNW_AARCH64_X15, + + /* Intra-procedure-call temporary registers. */ + UNW_AARCH64_X16, + UNW_AARCH64_X17, + + /* Callee-saved registers. */ + UNW_AARCH64_X18, + UNW_AARCH64_X19, + UNW_AARCH64_X20, + UNW_AARCH64_X21, + UNW_AARCH64_X22, + UNW_AARCH64_X23, + UNW_AARCH64_X24, + UNW_AARCH64_X25, + UNW_AARCH64_X26, + UNW_AARCH64_X27, + UNW_AARCH64_X28, + + /* 64-bit frame pointer. */ + UNW_AARCH64_X29, + + /* 64-bit link register. */ + UNW_AARCH64_X30, + + /* 64-bit stack pointer. */ + UNW_AARCH64_SP = 31, + UNW_AARCH64_PC, + UNW_AARCH64_PSTATE, + + /* 128-bit FP/Advanced SIMD registers. */ + UNW_AARCH64_V0 = 64, + UNW_AARCH64_V1, + UNW_AARCH64_V2, + UNW_AARCH64_V3, + UNW_AARCH64_V4, + UNW_AARCH64_V5, + UNW_AARCH64_V6, + UNW_AARCH64_V7, + UNW_AARCH64_V8, + UNW_AARCH64_V9, + UNW_AARCH64_V10, + UNW_AARCH64_V11, + UNW_AARCH64_V12, + UNW_AARCH64_V13, + UNW_AARCH64_V14, + UNW_AARCH64_V15, + UNW_AARCH64_V16, + UNW_AARCH64_V17, + UNW_AARCH64_V18, + UNW_AARCH64_V19, + UNW_AARCH64_V20, + UNW_AARCH64_V21, + UNW_AARCH64_V22, + UNW_AARCH64_V23, + UNW_AARCH64_V24, + UNW_AARCH64_V25, + UNW_AARCH64_V26, + UNW_AARCH64_V27, + UNW_AARCH64_V28, + UNW_AARCH64_V29, + UNW_AARCH64_V30, + UNW_AARCH64_V31, + + UNW_AARCH64_FPSR, + UNW_AARCH64_FPCR, + + /* For AArch64, the CFA is the value of SP (x31) at the call site of the + previous frame. */ + UNW_AARCH64_CFA = UNW_AARCH64_SP, + + UNW_TDEP_LAST_REG = UNW_AARCH64_FPCR, + + UNW_TDEP_IP = UNW_AARCH64_X30, + UNW_TDEP_SP = UNW_AARCH64_SP, + UNW_TDEP_EH = UNW_AARCH64_X0, + + } +aarch64_regnum_t; + +/* Use R0 through R3 to pass exception handling information. */ +#define UNW_TDEP_NUM_EH_REGS 4 + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. */ + } +unw_tdep_save_loc_t; + + +/* On AArch64, we can directly use ucontext_t as the unwind context. */ +typedef ucontext_t unw_tdep_context_t; + +#include "libunwind-common.h" +#include "libunwind-dynamic.h" + +#define unw_tdep_getcontext(uc) (getcontext (uc), 0) +#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) + +extern int unw_tdep_is_fpreg (int); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ diff --git a/headers/libs/libunwind/libunwind-arm.h b/headers/libs/libunwind/libunwind-arm.h new file mode 100644 index 0000000000..f208487a99 --- /dev/null +++ b/headers/libs/libunwind/libunwind-arm.h @@ -0,0 +1,302 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBUNWIND_H +#define LIBUNWIND_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include +#include + +#define UNW_TARGET arm +#define UNW_TARGET_ARM 1 + +#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ + +/* This needs to be big enough to accommodate "struct cursor", while + leaving some slack for future expansion. Changing this value will + require recompiling all users of this library. Stack allocation is + relatively cheap and unwind-state copying is relatively rare, so we + want to err on making it rather too big than too small. */ + +/* FIXME for ARM. Too big? What do other things use for similar tasks? */ +#define UNW_TDEP_CURSOR_LEN 4096 + +typedef uint32_t unw_word_t; +typedef int32_t unw_sword_t; + +typedef long double unw_tdep_fpreg_t; + +typedef enum + { + UNW_ARM_R0, + UNW_ARM_R1, + UNW_ARM_R2, + UNW_ARM_R3, + UNW_ARM_R4, + UNW_ARM_R5, + UNW_ARM_R6, + UNW_ARM_R7, + UNW_ARM_R8, + UNW_ARM_R9, + UNW_ARM_R10, + UNW_ARM_R11, + UNW_ARM_R12, + UNW_ARM_R13, + UNW_ARM_R14, + UNW_ARM_R15, + + /* VFPv2 s0-s31 (obsolescent numberings). */ + UNW_ARM_S0 = 64, + UNW_ARM_S1, + UNW_ARM_S2, + UNW_ARM_S3, + UNW_ARM_S4, + UNW_ARM_S5, + UNW_ARM_S6, + UNW_ARM_S7, + UNW_ARM_S8, + UNW_ARM_S9, + UNW_ARM_S10, + UNW_ARM_S11, + UNW_ARM_S12, + UNW_ARM_S13, + UNW_ARM_S14, + UNW_ARM_S15, + UNW_ARM_S16, + UNW_ARM_S17, + UNW_ARM_S18, + UNW_ARM_S19, + UNW_ARM_S20, + UNW_ARM_S21, + UNW_ARM_S22, + UNW_ARM_S23, + UNW_ARM_S24, + UNW_ARM_S25, + UNW_ARM_S26, + UNW_ARM_S27, + UNW_ARM_S28, + UNW_ARM_S29, + UNW_ARM_S30, + UNW_ARM_S31, + + /* FPA register numberings. */ + UNW_ARM_F0 = 96, + UNW_ARM_F1, + UNW_ARM_F2, + UNW_ARM_F3, + UNW_ARM_F4, + UNW_ARM_F5, + UNW_ARM_F6, + UNW_ARM_F7, + + /* iWMMXt GR register numberings. */ + UNW_ARM_wCGR0 = 104, + UNW_ARM_wCGR1, + UNW_ARM_wCGR2, + UNW_ARM_wCGR3, + UNW_ARM_wCGR4, + UNW_ARM_wCGR5, + UNW_ARM_wCGR6, + UNW_ARM_wCGR7, + + /* iWMMXt register numberings. */ + UNW_ARM_wR0 = 112, + UNW_ARM_wR1, + UNW_ARM_wR2, + UNW_ARM_wR3, + UNW_ARM_wR4, + UNW_ARM_wR5, + UNW_ARM_wR6, + UNW_ARM_wR7, + UNW_ARM_wR8, + UNW_ARM_wR9, + UNW_ARM_wR10, + UNW_ARM_wR11, + UNW_ARM_wR12, + UNW_ARM_wR13, + UNW_ARM_wR14, + UNW_ARM_wR15, + + /* Two-byte encodings from here on. */ + + /* SPSR. */ + UNW_ARM_SPSR = 128, + UNW_ARM_SPSR_FIQ, + UNW_ARM_SPSR_IRQ, + UNW_ARM_SPSR_ABT, + UNW_ARM_SPSR_UND, + UNW_ARM_SPSR_SVC, + + /* User mode registers. */ + UNW_ARM_R8_USR = 144, + UNW_ARM_R9_USR, + UNW_ARM_R10_USR, + UNW_ARM_R11_USR, + UNW_ARM_R12_USR, + UNW_ARM_R13_USR, + UNW_ARM_R14_USR, + + /* FIQ registers. */ + UNW_ARM_R8_FIQ = 151, + UNW_ARM_R9_FIQ, + UNW_ARM_R10_FIQ, + UNW_ARM_R11_FIQ, + UNW_ARM_R12_FIQ, + UNW_ARM_R13_FIQ, + UNW_ARM_R14_FIQ, + + /* IRQ registers. */ + UNW_ARM_R13_IRQ = 158, + UNW_ARM_R14_IRQ, + + /* ABT registers. */ + UNW_ARM_R13_ABT = 160, + UNW_ARM_R14_ABT, + + /* UND registers. */ + UNW_ARM_R13_UND = 162, + UNW_ARM_R14_UND, + + /* SVC registers. */ + UNW_ARM_R13_SVC = 164, + UNW_ARM_R14_SVC, + + /* iWMMXt control registers. */ + UNW_ARM_wC0 = 192, + UNW_ARM_wC1, + UNW_ARM_wC2, + UNW_ARM_wC3, + UNW_ARM_wC4, + UNW_ARM_wC5, + UNW_ARM_wC6, + UNW_ARM_wC7, + + /* VFPv3/Neon 64-bit registers. */ + UNW_ARM_D0 = 256, + UNW_ARM_D1, + UNW_ARM_D2, + UNW_ARM_D3, + UNW_ARM_D4, + UNW_ARM_D5, + UNW_ARM_D6, + UNW_ARM_D7, + UNW_ARM_D8, + UNW_ARM_D9, + UNW_ARM_D10, + UNW_ARM_D11, + UNW_ARM_D12, + UNW_ARM_D13, + UNW_ARM_D14, + UNW_ARM_D15, + UNW_ARM_D16, + UNW_ARM_D17, + UNW_ARM_D18, + UNW_ARM_D19, + UNW_ARM_D20, + UNW_ARM_D21, + UNW_ARM_D22, + UNW_ARM_D23, + UNW_ARM_D24, + UNW_ARM_D25, + UNW_ARM_D26, + UNW_ARM_D27, + UNW_ARM_D28, + UNW_ARM_D29, + UNW_ARM_D30, + UNW_ARM_D31, + + /* For ARM, the CFA is the value of SP (r13) at the call site in the + previous frame. */ + UNW_ARM_CFA, + + UNW_TDEP_LAST_REG = UNW_ARM_D31, + + UNW_TDEP_IP = UNW_ARM_R14, /* A little white lie. */ + UNW_TDEP_SP = UNW_ARM_R13, + UNW_TDEP_EH = UNW_ARM_R0 /* FIXME. */ + } +arm_regnum_t; + +#define UNW_TDEP_NUM_EH_REGS 2 /* FIXME for ARM. */ + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. */ + } +unw_tdep_save_loc_t; + +/* On ARM, we define our own unw_tdep_context instead of using ucontext_t. + This allows us to support systems that don't support getcontext and + therefore do not define ucontext_t. */ +typedef struct unw_tdep_context + { + unsigned long regs[16]; + } +unw_tdep_context_t; + +/* There is no getcontext() on ARM. Use a stub version which only saves GP + registers. FIXME: Not ideal, may not be sufficient for all libunwind + use cases. Stores pc+8, which is only approximately correct, really. */ +#ifndef __thumb__ +#define unw_tdep_getcontext(uc) (({ \ + unw_tdep_context_t *unw_ctx = (uc); \ + register unsigned long *unw_base asm ("r0") = unw_ctx->regs; \ + __asm__ __volatile__ ( \ + "stmia %[base], {r0-r15}" \ + : : [base] "r" (unw_base) : "memory"); \ + }), 0) +#else /* __thumb__ */ +#define unw_tdep_getcontext(uc) (({ \ + unw_tdep_context_t *unw_ctx = (uc); \ + register unsigned long *unw_base asm ("r0") = unw_ctx->regs; \ + __asm__ __volatile__ ( \ + ".align 2\nbx pc\nnop\n.code 32\n" \ + "stmia %[base], {r0-r15}\n" \ + "orr %[base], pc, #1\nbx %[base]" \ + : [base] "+r" (unw_base) : : "memory", "cc"); \ + }), 0) +#endif + +#include "libunwind-dynamic.h" + +typedef struct + { + /* no arm-specific auxiliary proc-info */ + } +unw_tdep_proc_info_t; + +#include "libunwind-common.h" + +#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) +extern int unw_tdep_is_fpreg (int); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ diff --git a/headers/libs/libunwind/libunwind-common.h b/headers/libs/libunwind/libunwind-common.h new file mode 100644 index 0000000000..b715c84c99 --- /dev/null +++ b/headers/libs/libunwind/libunwind-common.h @@ -0,0 +1,257 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#define UNW_VERSION_MAJOR 1 +#define UNW_VERSION_MINOR 1 +#define UNW_VERSION_EXTRA + +#define UNW_VERSION_CODE(maj,min) (((maj) << 16) | (min)) +#define UNW_VERSION UNW_VERSION_CODE(UNW_VERSION_MAJOR, UNW_VERSION_MINOR) + +#define UNW_PASTE2(x,y) x##y +#define UNW_PASTE(x,y) UNW_PASTE2(x,y) +#define UNW_OBJ(fn) UNW_PASTE(UNW_PREFIX, fn) +#define UNW_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_), fn) + +#ifdef UNW_LOCAL_ONLY +# define UNW_PREFIX UNW_PASTE(UNW_PASTE(_UL,UNW_TARGET),_) +#else /* !UNW_LOCAL_ONLY */ +# define UNW_PREFIX UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_) +#endif /* !UNW_LOCAL_ONLY */ + +/* Error codes. The unwind routines return the *negated* values of + these error codes on error and a non-negative value on success. */ +typedef enum + { + UNW_ESUCCESS = 0, /* no error */ + UNW_EUNSPEC, /* unspecified (general) error */ + UNW_ENOMEM, /* out of memory */ + UNW_EBADREG, /* bad register number */ + UNW_EREADONLYREG, /* attempt to write read-only register */ + UNW_ESTOPUNWIND, /* stop unwinding */ + UNW_EINVALIDIP, /* invalid IP */ + UNW_EBADFRAME, /* bad frame */ + UNW_EINVAL, /* unsupported operation or bad value */ + UNW_EBADVERSION, /* unwind info has unsupported version */ + UNW_ENOINFO /* no unwind info found */ + } +unw_error_t; + +/* The following enum defines the indices for a couple of + (pseudo-)registers which have the same meaning across all + platforms. (RO) means read-only. (RW) means read-write. General + registers (aka "integer registers") are expected to start with + index 0. The number of such registers is architecture-dependent. + The remaining indices can be used as an architecture sees fit. The + last valid register index is given by UNW_REG_LAST. */ +typedef enum + { + UNW_REG_IP = UNW_TDEP_IP, /* (rw) instruction pointer (pc) */ + UNW_REG_SP = UNW_TDEP_SP, /* (ro) stack pointer */ + UNW_REG_EH = UNW_TDEP_EH, /* (rw) exception-handling reg base */ + UNW_REG_LAST = UNW_TDEP_LAST_REG + } +unw_frame_regnum_t; + +/* Number of exception-handler argument registers: */ +#define UNW_NUM_EH_REGS UNW_TDEP_NUM_EH_REGS + +typedef enum + { + UNW_CACHE_NONE, /* no caching */ + UNW_CACHE_GLOBAL, /* shared global cache */ + UNW_CACHE_PER_THREAD /* per-thread caching */ + } +unw_caching_policy_t; + +typedef int unw_regnum_t; + +/* The unwind cursor starts at the youngest (most deeply nested) frame + and is used to track the frame state as the unwinder steps from + frame to frame. It is safe to make (shallow) copies of variables + of this type. */ +typedef struct unw_cursor + { + unw_word_t opaque[UNW_TDEP_CURSOR_LEN]; + } +unw_cursor_t; + +/* This type encapsulates the entire (preserved) machine-state. */ +typedef unw_tdep_context_t unw_context_t; + +/* unw_getcontext() fills the unw_context_t pointed to by UC with the + machine state as it exists at the call-site. For implementation + reasons, this needs to be a target-dependent macro. It's easiest + to think of unw_getcontext() as being identical to getcontext(). */ +#define unw_getcontext(uc) unw_tdep_getcontext(uc) + +/* Return 1 if register number R is a floating-point register, zero + otherwise. + This routine is signal-safe. */ +#define unw_is_fpreg(r) unw_tdep_is_fpreg(r) + +typedef unw_tdep_fpreg_t unw_fpreg_t; + +typedef struct unw_addr_space *unw_addr_space_t; + +/* Each target may define it's own set of flags, but bits 0-15 are + reserved for general libunwind-use. */ +#define UNW_PI_FLAG_FIRST_TDEP_BIT 16 +/* The information comes from a .debug_frame section. */ +#define UNW_PI_FLAG_DEBUG_FRAME 32 + +typedef struct unw_proc_info + { + unw_word_t start_ip; /* first IP covered by this procedure */ + unw_word_t end_ip; /* first IP NOT covered by this procedure */ + unw_word_t lsda; /* address of lang.-spec. data area (if any) */ + unw_word_t handler; /* optional personality routine */ + unw_word_t gp; /* global-pointer value for this procedure */ + unw_word_t flags; /* misc. flags */ + + int format; /* unwind-info format (arch-specific) */ + int unwind_info_size; /* size of the information (if applicable) */ + void *unwind_info; /* unwind-info (arch-specific) */ + unw_tdep_proc_info_t extra; /* target-dependent auxiliary proc-info */ + } +unw_proc_info_t; + +/* These are backend callback routines that provide access to the + state of a "remote" process. This can be used, for example, to + unwind another process through the ptrace() interface. */ +typedef struct unw_accessors + { + /* Look up the unwind info associated with instruction-pointer IP. + On success, the routine fills in the PROC_INFO structure. */ + int (*find_proc_info) (unw_addr_space_t, unw_word_t, unw_proc_info_t *, + int, void *); + + /* Release any resources (e.g., memory) that were allocated for + the unwind info returned in by a previous call to + find_proc_info() with NEED_UNWIND_INFO set to 1. */ + void (*put_unwind_info) (unw_addr_space_t, unw_proc_info_t *, void *); + + /* Return the list-head of the dynamically registered unwind + info. */ + int (*get_dyn_info_list_addr) (unw_addr_space_t, unw_word_t *, void *); + + /* Access aligned word at address ADDR. The value is returned + according to the endianness of the host (e.g., if the host is + little-endian and the target is big-endian, access_mem() needs + to byte-swap the value before returning it). */ + int (*access_mem) (unw_addr_space_t, unw_word_t, unw_word_t *, int, + void *); + + /* Access register number REG at address ADDR. */ + int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, int, + void *); + + /* Access register number REG at address ADDR. */ + int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, + unw_fpreg_t *, int, void *); + + int (*resume) (unw_addr_space_t, unw_cursor_t *, void *); + + /* Optional call back to obtain the name of a (static) procedure. + Dynamically generated procedures are handled automatically by + libunwind. This callback is optional and may be set to + NULL. */ + int (*get_proc_name) (unw_addr_space_t, unw_word_t, char *, size_t, + unw_word_t *, void *); + } +unw_accessors_t; + +typedef enum unw_save_loc_type + { + UNW_SLT_NONE, /* register is not saved ("not an l-value") */ + UNW_SLT_MEMORY, /* register has been saved in memory */ + UNW_SLT_REG /* register has been saved in (another) register */ + } +unw_save_loc_type_t; + +typedef struct unw_save_loc + { + unw_save_loc_type_t type; + union + { + unw_word_t addr; /* valid if type==UNW_SLT_MEMORY */ + unw_regnum_t regnum; /* valid if type==UNW_SLT_REG */ + } + u; + unw_tdep_save_loc_t extra; /* target-dependent additional information */ + } +unw_save_loc_t; + +/* These routines work both for local and remote unwinding. */ + +#define unw_local_addr_space UNW_OBJ(local_addr_space) +#define unw_create_addr_space UNW_OBJ(create_addr_space) +#define unw_destroy_addr_space UNW_OBJ(destroy_addr_space) +#define unw_get_accessors UNW_ARCH_OBJ(get_accessors) +#define unw_init_local UNW_OBJ(init_local) +#define unw_init_remote UNW_OBJ(init_remote) +#define unw_step UNW_OBJ(step) +#define unw_resume UNW_OBJ(resume) +#define unw_get_proc_info UNW_OBJ(get_proc_info) +#define unw_get_proc_info_by_ip UNW_OBJ(get_proc_info_by_ip) +#define unw_get_reg UNW_OBJ(get_reg) +#define unw_set_reg UNW_OBJ(set_reg) +#define unw_get_fpreg UNW_OBJ(get_fpreg) +#define unw_set_fpreg UNW_OBJ(set_fpreg) +#define unw_get_save_loc UNW_OBJ(get_save_loc) +#define unw_is_signal_frame UNW_OBJ(is_signal_frame) +#define unw_handle_signal_frame UNW_OBJ(handle_signal_frame) +#define unw_get_proc_name UNW_OBJ(get_proc_name) +#define unw_set_caching_policy UNW_OBJ(set_caching_policy) +#define unw_regname UNW_ARCH_OBJ(regname) +#define unw_flush_cache UNW_ARCH_OBJ(flush_cache) +#define unw_strerror UNW_ARCH_OBJ(strerror) + +extern unw_addr_space_t unw_create_addr_space (unw_accessors_t *, int); +extern void unw_destroy_addr_space (unw_addr_space_t); +extern unw_accessors_t *unw_get_accessors (unw_addr_space_t); +extern void unw_flush_cache (unw_addr_space_t, unw_word_t, unw_word_t); +extern int unw_set_caching_policy (unw_addr_space_t, unw_caching_policy_t); +extern const char *unw_regname (unw_regnum_t); + +extern int unw_init_local (unw_cursor_t *, unw_context_t *); +extern int unw_init_remote (unw_cursor_t *, unw_addr_space_t, void *); +extern int unw_step (unw_cursor_t *); +extern int unw_resume (unw_cursor_t *); +extern int unw_get_proc_info (unw_cursor_t *, unw_proc_info_t *); +extern int unw_get_proc_info_by_ip (unw_addr_space_t, unw_word_t, + unw_proc_info_t *, void *); +extern int unw_get_reg (unw_cursor_t *, int, unw_word_t *); +extern int unw_set_reg (unw_cursor_t *, int, unw_word_t); +extern int unw_get_fpreg (unw_cursor_t *, int, unw_fpreg_t *); +extern int unw_set_fpreg (unw_cursor_t *, int, unw_fpreg_t); +extern int unw_get_save_loc (unw_cursor_t *, int, unw_save_loc_t *); +extern int unw_is_signal_frame (unw_cursor_t *); +extern int unw_handle_signal_frame (unw_cursor_t *); +extern int unw_get_proc_name (unw_cursor_t *, char *, size_t, unw_word_t *); +extern const char *unw_strerror (int); +extern int unw_backtrace (void **, int); + +extern unw_addr_space_t unw_local_addr_space; diff --git a/headers/libs/libunwind/libunwind-coredump.h b/headers/libs/libunwind/libunwind-coredump.h new file mode 100644 index 0000000000..3c7814140f --- /dev/null +++ b/headers/libs/libunwind/libunwind-coredump.h @@ -0,0 +1,73 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef libunwind_coredump_h +#define libunwind_coredump_h + +#include + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* Helper routines which make it easy to use libunwind on a coredump. + They're available only if UNW_REMOTE_ONLY is _not_ defined and they + aren't really part of the libunwind API. They are implemented in a + archive library called libunwind-coredump.a. */ + +struct UCD_info; + +extern struct UCD_info *_UCD_create(const char *filename); +extern void _UCD_destroy(struct UCD_info *); + +extern int _UCD_get_num_threads(struct UCD_info *); +extern void _UCD_select_thread(struct UCD_info *, int); +extern pid_t _UCD_get_pid(struct UCD_info *); +extern int _UCD_get_cursig(struct UCD_info *); +extern int _UCD_add_backing_file_at_segment(struct UCD_info *, int phdr_no, const char *filename); +extern int _UCD_add_backing_file_at_vaddr(struct UCD_info *, + unsigned long vaddr, + const char *filename); + +extern int _UCD_find_proc_info (unw_addr_space_t, unw_word_t, + unw_proc_info_t *, int, void *); +extern void _UCD_put_unwind_info (unw_addr_space_t, unw_proc_info_t *, void *); +extern int _UCD_get_dyn_info_list_addr (unw_addr_space_t, unw_word_t *, + void *); +extern int _UCD_access_mem (unw_addr_space_t, unw_word_t, unw_word_t *, int, + void *); +extern int _UCD_access_reg (unw_addr_space_t, unw_regnum_t, unw_word_t *, + int, void *); +extern int _UCD_access_fpreg (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, + int, void *); +extern int _UCD_get_proc_name (unw_addr_space_t, unw_word_t, char *, size_t, + unw_word_t *, void *); +extern int _UCD_resume (unw_addr_space_t, unw_cursor_t *, void *); +extern unw_accessors_t _UCD_accessors; + + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* libunwind_coredump_h */ diff --git a/headers/libs/libunwind/libunwind-dynamic.h b/headers/libs/libunwind/libunwind-dynamic.h new file mode 100644 index 0000000000..8feb9de8af --- /dev/null +++ b/headers/libs/libunwind/libunwind-dynamic.h @@ -0,0 +1,210 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* This file defines the runtime-support routines for dynamically +generated code. Even though it is implemented as part of libunwind, +it is logically separate from the interface to perform the actual +unwinding. In particular, this interface is always used in the +context of the unwind target, whereas the rest of the unwind API is +used in context of the process that is doing the unwind (which may be +a debugger running on another machine, for example). + +Note that the data-structures declared here server a dual purpose: +when a program registers a dynamically generated procedure, it uses +these structures directly. On the other hand, with remote-unwinding, +the data-structures are read from the remote process's memory and +translated into internalized versions. To facilitate remote-access, +the following rules should be followed in declaring these structures: + + (1) Declare a member as a pointer only if the the information the + member points to needs to be internalized as well (e.g., a + string representing a procedure name should be declared as + "const char *", but the instruction pointer should be declared + as unw_word_t). + + (2) Provide sufficient padding to ensure that no implicit padding + will be needed on any of the supported target architectures. For + the time being, padding data structures with the assumption that + sizeof (unw_word_t) == 8 should be sufficient. (Note: it's not + impossible to internalize structures with internal padding, but + it does make the process a bit harder). + + (3) Don't declare members that contain bitfields or floating-point + values. + + (4) Don't declare members with enumeration types. Declare them as + int32_t instead. */ + +typedef enum + { + UNW_DYN_STOP = 0, /* end-of-unwind-info marker */ + UNW_DYN_SAVE_REG, /* save register to another register */ + UNW_DYN_SPILL_FP_REL, /* frame-pointer-relative register spill */ + UNW_DYN_SPILL_SP_REL, /* stack-pointer-relative register spill */ + UNW_DYN_ADD, /* add constant value to a register */ + UNW_DYN_POP_FRAMES, /* drop one or more stack frames */ + UNW_DYN_LABEL_STATE, /* name the current state */ + UNW_DYN_COPY_STATE, /* set the region's entry-state */ + UNW_DYN_ALIAS /* get unwind info from an alias */ + } +unw_dyn_operation_t; + +typedef enum + { + UNW_INFO_FORMAT_DYNAMIC, /* unw_dyn_proc_info_t */ + UNW_INFO_FORMAT_TABLE, /* unw_dyn_table_t */ + UNW_INFO_FORMAT_REMOTE_TABLE, /* unw_dyn_remote_table_t */ + UNW_INFO_FORMAT_ARM_EXIDX /* ARM specific unwind info */ + } +unw_dyn_info_format_t; + +typedef struct unw_dyn_op + { + int8_t tag; /* what operation? */ + int8_t qp; /* qualifying predicate register */ + int16_t reg; /* what register */ + int32_t when; /* when does it take effect? */ + unw_word_t val; /* auxiliary value */ + } +unw_dyn_op_t; + +typedef struct unw_dyn_region_info + { + struct unw_dyn_region_info *next; /* linked list of regions */ + int32_t insn_count; /* region length (# of instructions) */ + uint32_t op_count; /* length of op-array */ + unw_dyn_op_t op[1]; /* variable-length op-array */ + } +unw_dyn_region_info_t; + +typedef struct unw_dyn_proc_info + { + unw_word_t name_ptr; /* address of human-readable procedure name */ + unw_word_t handler; /* address of personality routine */ + uint32_t flags; + int32_t pad0; + unw_dyn_region_info_t *regions; + } +unw_dyn_proc_info_t; + +typedef struct unw_dyn_table_info + { + unw_word_t name_ptr; /* addr. of table name (e.g., library name) */ + unw_word_t segbase; /* segment base */ + unw_word_t table_len; /* must be a multiple of sizeof(unw_word_t)! */ + unw_word_t *table_data; + } +unw_dyn_table_info_t; + +typedef struct unw_dyn_remote_table_info + { + unw_word_t name_ptr; /* addr. of table name (e.g., library name) */ + unw_word_t segbase; /* segment base */ + unw_word_t table_len; /* must be a multiple of sizeof(unw_word_t)! */ + unw_word_t table_data; + } +unw_dyn_remote_table_info_t; + +typedef struct unw_dyn_info + { + /* doubly-linked list of dyn-info structures: */ + struct unw_dyn_info *next; + struct unw_dyn_info *prev; + unw_word_t start_ip; /* first IP covered by this entry */ + unw_word_t end_ip; /* first IP NOT covered by this entry */ + unw_word_t gp; /* global-pointer in effect for this entry */ + int32_t format; /* real type: unw_dyn_info_format_t */ + int32_t pad; + union + { + unw_dyn_proc_info_t pi; + unw_dyn_table_info_t ti; + unw_dyn_remote_table_info_t rti; + } + u; + } +unw_dyn_info_t; + +typedef struct unw_dyn_info_list + { + uint32_t version; + uint32_t generation; + unw_dyn_info_t *first; + } +unw_dyn_info_list_t; + +/* Return the size (in bytes) of an unw_dyn_region_info_t structure that can + hold OP_COUNT ops. */ +#define _U_dyn_region_info_size(op_count) \ + ((char *) (((unw_dyn_region_info_t *) NULL)->op + (op_count)) \ + - (char *) NULL) + +/* Register the unwind info for a single procedure. + This routine is NOT signal-safe. */ +extern void _U_dyn_register (unw_dyn_info_t *); + +/* Cancel the unwind info for a single procedure. + This routine is NOT signal-safe. */ +extern void _U_dyn_cancel (unw_dyn_info_t *); + + +/* Convenience routines. */ + +#define _U_dyn_op(_tag, _qp, _when, _reg, _val) \ + ((unw_dyn_op_t) { (_tag), (_qp), (_reg), (_when), (_val) }) + +#define _U_dyn_op_save_reg(op, qp, when, reg, dst) \ + (*(op) = _U_dyn_op (UNW_DYN_SAVE_REG, (qp), (when), (reg), (dst))) + +#define _U_dyn_op_spill_fp_rel(op, qp, when, reg, offset) \ + (*(op) = _U_dyn_op (UNW_DYN_SPILL_FP_REL, (qp), (when), (reg), \ + (offset))) + +#define _U_dyn_op_spill_sp_rel(op, qp, when, reg, offset) \ + (*(op) = _U_dyn_op (UNW_DYN_SPILL_SP_REL, (qp), (when), (reg), \ + (offset))) + +#define _U_dyn_op_add(op, qp, when, reg, value) \ + (*(op) = _U_dyn_op (UNW_DYN_ADD, (qp), (when), (reg), (value))) + +#define _U_dyn_op_pop_frames(op, qp, when, num_frames) \ + (*(op) = _U_dyn_op (UNW_DYN_POP_FRAMES, (qp), (when), 0, (num_frames))) + +#define _U_dyn_op_label_state(op, label) \ + (*(op) = _U_dyn_op (UNW_DYN_LABEL_STATE, _U_QP_TRUE, -1, 0, (label))) + +#define _U_dyn_op_copy_state(op, label) \ + (*(op) = _U_dyn_op (UNW_DYN_COPY_STATE, _U_QP_TRUE, -1, 0, (label))) + +#define _U_dyn_op_alias(op, qp, when, addr) \ + (*(op) = _U_dyn_op (UNW_DYN_ALIAS, (qp), (when), 0, (addr))) + +#define _U_dyn_op_stop(op) \ + (*(op) = _U_dyn_op (UNW_DYN_STOP, _U_QP_TRUE, -1, 0, 0)) + +/* The target-dependent qualifying predicate which is always TRUE. On + IA-64, that's p0 (0), on non-predicated architectures, the value is + ignored. */ +#define _U_QP_TRUE _U_TDEP_QP_TRUE diff --git a/headers/libs/libunwind/libunwind-hppa.h b/headers/libs/libunwind/libunwind-hppa.h new file mode 100644 index 0000000000..7013aa7726 --- /dev/null +++ b/headers/libs/libunwind/libunwind-hppa.h @@ -0,0 +1,125 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBUNWIND_H +#define LIBUNWIND_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include +#include + +#define UNW_TARGET hppa +#define UNW_TARGET_HPPA 1 + +#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ + +/* This needs to be big enough to accommodate "struct cursor", while + leaving some slack for future expansion. Changing this value will + require recompiling all users of this library. Stack allocation is + relatively cheap and unwind-state copying is relatively rare, so we + want to err on making it rather too big than too small. */ +#define UNW_TDEP_CURSOR_LEN 511 + +typedef uint32_t unw_word_t; +typedef int32_t unw_sword_t; + +typedef union + { + struct { unw_word_t bits[2]; } raw; + double val; + } +unw_tdep_fpreg_t; + +typedef enum + { + /* Note: general registers are expected to start with index 0. + This convention facilitates architecture-independent + implementation of the C++ exception handling ABI. See + _Unwind_SetGR() and _Unwind_GetGR() for details. */ + UNW_HPPA_GR = 0, + UNW_HPPA_RP = 2, /* return pointer */ + UNW_HPPA_FP = 3, /* frame pointer */ + UNW_HPPA_SP = UNW_HPPA_GR + 30, + + UNW_HPPA_FR = UNW_HPPA_GR + 32, + + UNW_HPPA_IP = UNW_HPPA_FR + 32, /* instruction pointer */ + + /* other "preserved" registers (fpsr etc.)... */ + + /* PA-RISC has 4 exception-argument registers but they're not + contiguous. To deal with this, we define 4 pseudo + exception-handling registers which we then alias to the actual + physical register. */ + + UNW_HPPA_EH0 = UNW_HPPA_IP + 1, /* alias for UNW_HPPA_GR + 20 */ + UNW_HPPA_EH1 = UNW_HPPA_EH0 + 1, /* alias for UNW_HPPA_GR + 21 */ + UNW_HPPA_EH2 = UNW_HPPA_EH1 + 1, /* alias for UNW_HPPA_GR + 22 */ + UNW_HPPA_EH3 = UNW_HPPA_EH2 + 1, /* alias for UNW_HPPA_GR + 31 */ + + /* frame info (read-only) */ + UNW_HPPA_CFA, + + UNW_TDEP_LAST_REG = UNW_HPPA_IP, + + UNW_TDEP_IP = UNW_HPPA_IP, + UNW_TDEP_SP = UNW_HPPA_SP, + UNW_TDEP_EH = UNW_HPPA_EH0 + } +hppa_regnum_t; + +#define UNW_TDEP_NUM_EH_REGS 4 + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. */ + } +unw_tdep_save_loc_t; + +/* On PA-RISC, we can directly use ucontext_t as the unwind context. */ +typedef ucontext_t unw_tdep_context_t; + +#define unw_tdep_is_fpreg(r) ((unsigned) ((r) - UNW_HPPA_FR) < 32) + +#include "libunwind-dynamic.h" + +typedef struct + { + /* no PA-RISC-specific auxiliary proc-info */ + } +unw_tdep_proc_info_t; + +#include "libunwind-common.h" + +#define unw_tdep_getcontext UNW_ARCH_OBJ (getcontext) +extern int unw_tdep_getcontext (unw_tdep_context_t *); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ diff --git a/headers/libs/libunwind/libunwind-ia64.h b/headers/libs/libunwind/libunwind-ia64.h new file mode 100644 index 0000000000..0cc4f39eaa --- /dev/null +++ b/headers/libs/libunwind/libunwind-ia64.h @@ -0,0 +1,194 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBUNWIND_H +#define LIBUNWIND_H + +#include +#include + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#ifdef ia64 + /* This works around a bug in Intel's ECC v7.0 which defines "ia64" + as "1". */ +# undef ia64 +#endif + +#ifdef __hpux + /* On HP-UX, there is no hope of supporting UNW_LOCAL_ONLY, because + it's impossible to obtain the address of the members in the + sigcontext structure. */ +# undef UNW_LOCAL_ONLY +# define UNW_GENERIC_ONLY +#endif + +#define UNW_TARGET ia64 +#define UNW_TARGET_IA64 1 + +#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ + +/* This needs to be big enough to accommodate "struct cursor", while + leaving some slack for future expansion. Changing this value will + require recompiling all users of this library. Stack allocation is + relatively cheap and unwind-state copying is relatively rare, so we + want to err on making it rather too big than too small. */ +#define UNW_TDEP_CURSOR_LEN 511 + +/* If this bit is it indicates that the procedure saved all of ar.bsp, + ar.bspstore, and ar.rnat. If, additionally, ar.bsp != saved ar.bsp, + then this procedure has performed a register-backing-store switch. */ +#define UNW_PI_FLAG_IA64_RBS_SWITCH_BIT (UNW_PI_FLAG_FIRST_TDEP_BIT + 0) + +#define UNW_PI_FLAG_IA64_RBS_SWITCH (1 << UNW_PI_FLAG_IA64_RBS_SWITCH_BIT) + +typedef uint64_t unw_word_t; +typedef int64_t unw_sword_t; + +/* On IA-64, we want to access the contents of floating-point + registers as a pair of "words", but to ensure 16-byte alignment, we + make it a union that contains a "long double". This will do the + Right Thing on all known IA-64 platforms, including HP-UX. */ +typedef union + { + struct { unw_word_t bits[2]; } raw; + long double dummy; /* dummy to force 16-byte alignment */ + } +unw_tdep_fpreg_t; + +typedef struct + { + /* no ia64-specific auxiliary proc-info */ + } +unw_tdep_proc_info_t; + +typedef enum + { + /* Note: general registers are excepted to start with index 0. + This convention facilitates architecture-independent + implementation of the C++ exception handling ABI. See + _Unwind_SetGR() and _Unwind_GetGR() for details. */ + UNW_IA64_GR = 0, /* general registers (r0..r127) */ + UNW_IA64_GP = UNW_IA64_GR + 1, + UNW_IA64_TP = UNW_IA64_GR + 13, + + UNW_IA64_NAT = UNW_IA64_GR + 128, /* NaT registers (nat0..nat127) */ + + UNW_IA64_FR = UNW_IA64_NAT + 128, /* fp registers (f0..f127) */ + + UNW_IA64_AR = UNW_IA64_FR + 128, /* application registers (ar0..r127) */ + UNW_IA64_AR_RSC = UNW_IA64_AR + 16, + UNW_IA64_AR_BSP = UNW_IA64_AR + 17, + UNW_IA64_AR_BSPSTORE = UNW_IA64_AR + 18, + UNW_IA64_AR_RNAT = UNW_IA64_AR + 19, + UNW_IA64_AR_CSD = UNW_IA64_AR + 25, + UNW_IA64_AR_26 = UNW_IA64_AR + 26, + UNW_IA64_AR_SSD = UNW_IA64_AR_26, + UNW_IA64_AR_CCV = UNW_IA64_AR + 32, + UNW_IA64_AR_UNAT = UNW_IA64_AR + 36, + UNW_IA64_AR_FPSR = UNW_IA64_AR + 40, + UNW_IA64_AR_PFS = UNW_IA64_AR + 64, + UNW_IA64_AR_LC = UNW_IA64_AR + 65, + UNW_IA64_AR_EC = UNW_IA64_AR + 66, + + UNW_IA64_BR = UNW_IA64_AR + 128, /* branch registers (b0..p7) */ + UNW_IA64_RP = UNW_IA64_BR + 0, /* return pointer (rp) */ + UNW_IA64_PR = UNW_IA64_BR + 8, /* predicate registers (p0..p63) */ + UNW_IA64_CFM, + + /* frame info: */ + UNW_IA64_BSP, + UNW_IA64_IP, + UNW_IA64_SP, + + UNW_TDEP_LAST_REG = UNW_IA64_SP, + + UNW_TDEP_IP = UNW_IA64_IP, + UNW_TDEP_SP = UNW_IA64_SP, + UNW_TDEP_EH = UNW_IA64_GR + 15 + } +ia64_regnum_t; + +#define UNW_TDEP_NUM_EH_REGS 4 /* r15-r18 are exception args */ + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. On IA-64, + we use this to provide the bit number in which a NaT bit gets + saved. */ + uint8_t nat_bitnr; + + /* Padding reserved for future use. */ + uint8_t reserved[7]; + } +unw_tdep_save_loc_t; + +/* On IA-64, we can directly use ucontext_t as the unwind context. */ +typedef ucontext_t unw_tdep_context_t; + +#define unw_tdep_is_fpreg(r) ((unsigned) ((r) - UNW_IA64_FR) < 128) + +#include "libunwind-dynamic.h" +#include "libunwind-common.h" + +#ifdef __hpux + /* In theory, we could use _Uia64_getcontext() on HP-UX as well, but + the benefit of doing so would be marginal given that it can't + support UNW_LOCAL_ONLY. */ +# define unw_tdep_getcontext getcontext +#else +# define unw_tdep_getcontext UNW_ARCH_OBJ (getcontext) + extern int unw_tdep_getcontext (unw_tdep_context_t *); +#endif + +/* This is a helper routine to search an ia64 unwind table. If the + address-space argument AS points to something other than the local + address-space, the memory for the unwind-info will be allocated + with malloc(), and should be free()d during the put_unwind_info() + callback. This routine is signal-safe for the local-address-space + case ONLY. */ +#define unw_search_ia64_unwind_table UNW_OBJ(search_unwind_table) +extern int unw_search_ia64_unwind_table (unw_addr_space_t, unw_word_t, + unw_dyn_info_t *, unw_proc_info_t *, + int, void *); + +/* This is a helper routine which the get_dyn_info_list_addr() + callback can use to locate the special dynamic-info list entry in + an IA-64 unwind table. If the entry exists in the table, the + list-address is returned. In all other cases, 0 is returned. */ +extern unw_word_t _Uia64_find_dyn_list (unw_addr_space_t, unw_dyn_info_t *, + void *); + +/* This is a helper routine to obtain the kernel-unwind info. It is + signal-safe. */ +extern int _Uia64_get_kernel_table (unw_dyn_info_t *); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ diff --git a/headers/libs/libunwind/libunwind-mips.h b/headers/libs/libunwind/libunwind-mips.h new file mode 100644 index 0000000000..4591d062b2 --- /dev/null +++ b/headers/libs/libunwind/libunwind-mips.h @@ -0,0 +1,157 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBUNWIND_H +#define LIBUNWIND_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include +#include + +#ifdef mips +# undef mips +#endif + +#define UNW_TARGET mips +#define UNW_TARGET_MIPS 1 + +#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ + +/* This needs to be big enough to accommodate "struct cursor", while + leaving some slack for future expansion. Changing this value will + require recompiling all users of this library. Stack allocation is + relatively cheap and unwind-state copying is relatively rare, so we + want to err on making it rather too big than too small. */ + +/* FIXME for MIPS. Too big? What do other things use for similar tasks? */ +#define UNW_TDEP_CURSOR_LEN 4096 + +/* The size of a "word" varies on MIPS. This type is used for memory + addresses and register values. To allow a single library to support + multiple ABIs, and to support N32 at all, we must use a 64-bit type + even when addresses are only 32 bits. */ +typedef uint64_t unw_word_t; +typedef int32_t unw_sword_t; + +/* FIXME: MIPS ABIs. */ +typedef long double unw_tdep_fpreg_t; + +typedef enum + { + UNW_MIPS_R0, + UNW_MIPS_R1, + UNW_MIPS_R2, + UNW_MIPS_R3, + UNW_MIPS_R4, + UNW_MIPS_R5, + UNW_MIPS_R6, + UNW_MIPS_R7, + UNW_MIPS_R8, + UNW_MIPS_R9, + UNW_MIPS_R10, + UNW_MIPS_R11, + UNW_MIPS_R12, + UNW_MIPS_R13, + UNW_MIPS_R14, + UNW_MIPS_R15, + UNW_MIPS_R16, + UNW_MIPS_R17, + UNW_MIPS_R18, + UNW_MIPS_R19, + UNW_MIPS_R20, + UNW_MIPS_R21, + UNW_MIPS_R22, + UNW_MIPS_R23, + UNW_MIPS_R24, + UNW_MIPS_R25, + UNW_MIPS_R26, + UNW_MIPS_R27, + UNW_MIPS_R28, + UNW_MIPS_R29, + UNW_MIPS_R30, + UNW_MIPS_R31, + + UNW_MIPS_PC = 34, + + /* FIXME: Other registers! */ + + /* For MIPS, the CFA is the value of SP (r29) at the call site in the + previous frame. */ + UNW_MIPS_CFA, + + UNW_TDEP_LAST_REG = UNW_MIPS_R31, + + UNW_TDEP_IP = UNW_MIPS_R31, + UNW_TDEP_SP = UNW_MIPS_R29, + UNW_TDEP_EH = UNW_MIPS_R0 /* FIXME. */ + } +mips_regnum_t; + +typedef enum + { + UNW_MIPS_ABI_O32, + UNW_MIPS_ABI_N32, + UNW_MIPS_ABI_N64 + } +mips_abi_t; + +#define UNW_TDEP_NUM_EH_REGS 2 /* FIXME for MIPS. */ + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. */ + } +unw_tdep_save_loc_t; + +/* On x86, we can directly use ucontext_t as the unwind context. FIXME for + MIPS. */ +typedef ucontext_t unw_tdep_context_t; + +#include "libunwind-dynamic.h" + +typedef struct + { + /* no mips-specific auxiliary proc-info */ + } +unw_tdep_proc_info_t; + +#include "libunwind-common.h" + +/* There is no getcontext() on MIPS. Use a stub version which only saves GP + registers. FIXME: Not ideal, may not be sufficient for all libunwind + use cases. */ +#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext) +extern int unw_tdep_getcontext (ucontext_t *uc); + +#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) +extern int unw_tdep_is_fpreg (int); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ diff --git a/headers/libs/libunwind/libunwind-ppc32.h b/headers/libs/libunwind/libunwind-ppc32.h new file mode 100644 index 0000000000..47ebfde5a3 --- /dev/null +++ b/headers/libs/libunwind/libunwind-ppc32.h @@ -0,0 +1,207 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + Will be replaced when libunwind is ready on ppc64 platform. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBUNWIND_H +#define LIBUNWIND_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include +#include + +#define UNW_TARGET ppc32 +#define UNW_TARGET_PPC32 1 + +#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ + +/* + * This needs to be big enough to accommodate "struct cursor", while + * leaving some slack for future expansion. Changing this value will + * require recompiling all users of this library. Stack allocation is + * relatively cheap and unwind-state copying is relatively rare, so we want + * to err on making it rather too big than too small. + * + * To simplify this whole process, we are at least initially taking the + * tack that UNW_PPC32_* map straight across to the .eh_frame column register + * numbers. These register numbers come from gcc's source in + * gcc/config/rs6000/rs6000.h + * + * UNW_TDEP_CURSOR_LEN is in terms of unw_word_t size. Since we have 115 + * elements in the loc array, each sized 2 * unw_word_t, plus the rest of + * the cursor struct, this puts us at about 2 * 115 + 40 = 270. Let's + * round that up to 280. + */ + +#define UNW_TDEP_CURSOR_LEN 280 + +#if __WORDSIZE==32 +typedef uint32_t unw_word_t; +typedef int32_t unw_sword_t; +#else +typedef uint64_t unw_word_t; +typedef int64_t unw_sword_t; +#endif + +typedef long double unw_tdep_fpreg_t; + +typedef enum + { + UNW_PPC32_R0, + UNW_PPC32_R1, /* called STACK_POINTER in gcc */ + UNW_PPC32_R2, + UNW_PPC32_R3, + UNW_PPC32_R4, + UNW_PPC32_R5, + UNW_PPC32_R6, + UNW_PPC32_R7, + UNW_PPC32_R8, + UNW_PPC32_R9, + UNW_PPC32_R10, + UNW_PPC32_R11, /* called STATIC_CHAIN in gcc */ + UNW_PPC32_R12, + UNW_PPC32_R13, + UNW_PPC32_R14, + UNW_PPC32_R15, + UNW_PPC32_R16, + UNW_PPC32_R17, + UNW_PPC32_R18, + UNW_PPC32_R19, + UNW_PPC32_R20, + UNW_PPC32_R21, + UNW_PPC32_R22, + UNW_PPC32_R23, + UNW_PPC32_R24, + UNW_PPC32_R25, + UNW_PPC32_R26, + UNW_PPC32_R27, + UNW_PPC32_R28, + UNW_PPC32_R29, + UNW_PPC32_R30, + UNW_PPC32_R31, /* called HARD_FRAME_POINTER in gcc */ + + /* Count Register */ + UNW_PPC32_CTR = 32, + /* Fixed-Point Status and Control Register */ + UNW_PPC32_XER = 33, + /* Condition Register */ + UNW_PPC32_CCR = 34, + /* Machine State Register */ + //UNW_PPC32_MSR = 35, + /* MQ or SPR0, not part of generic Power, part of MPC601 */ + //UNW_PPC32_MQ = 36, + /* Link Register */ + UNW_PPC32_LR = 36, + /* Floating Pointer Status and Control Register */ + UNW_PPC32_FPSCR = 37, + + UNW_PPC32_F0 = 48, + UNW_PPC32_F1, + UNW_PPC32_F2, + UNW_PPC32_F3, + UNW_PPC32_F4, + UNW_PPC32_F5, + UNW_PPC32_F6, + UNW_PPC32_F7, + UNW_PPC32_F8, + UNW_PPC32_F9, + UNW_PPC32_F10, + UNW_PPC32_F11, + UNW_PPC32_F12, + UNW_PPC32_F13, + UNW_PPC32_F14, + UNW_PPC32_F15, + UNW_PPC32_F16, + UNW_PPC32_F17, + UNW_PPC32_F18, + UNW_PPC32_F19, + UNW_PPC32_F20, + UNW_PPC32_F21, + UNW_PPC32_F22, + UNW_PPC32_F23, + UNW_PPC32_F24, + UNW_PPC32_F25, + UNW_PPC32_F26, + UNW_PPC32_F27, + UNW_PPC32_F28, + UNW_PPC32_F29, + UNW_PPC32_F30, + UNW_PPC32_F31, + + UNW_TDEP_LAST_REG = UNW_PPC32_F31, + + UNW_TDEP_IP = UNW_PPC32_LR, + UNW_TDEP_SP = UNW_PPC32_R1, + UNW_TDEP_EH = UNW_PPC32_R12 + } +ppc32_regnum_t; + +/* + * According to David Edelsohn, GNU gcc uses R3, R4, R5, and maybe R6 for + * passing parameters to exception handlers. + */ + +#define UNW_TDEP_NUM_EH_REGS 4 + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. */ + } +unw_tdep_save_loc_t; + +/* On ppc, we can directly use ucontext_t as the unwind context. */ +typedef ucontext_t unw_tdep_context_t; + +/* XXX this is not ideal: an application should not be prevented from + using the "getcontext" name just because it's using libunwind. We + can't just use __getcontext() either, because that isn't exported + by glibc... */ +#define unw_tdep_getcontext(uc) (getcontext (uc), 0) + +#include "libunwind-dynamic.h" + +typedef struct + { + /* no ppc32-specific auxiliary proc-info */ + } +unw_tdep_proc_info_t; + +#include "libunwind-common.h" + +#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) +extern int unw_tdep_is_fpreg (int); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ diff --git a/headers/libs/libunwind/libunwind-ppc64.h b/headers/libs/libunwind/libunwind-ppc64.h new file mode 100644 index 0000000000..9944628da0 --- /dev/null +++ b/headers/libs/libunwind/libunwind-ppc64.h @@ -0,0 +1,271 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + Will be replaced when libunwind is ready on ppc64 platform. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBUNWIND_H +#define LIBUNWIND_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include +#include + +#define UNW_TARGET ppc64 +#define UNW_TARGET_PPC64 1 + +#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ + +/* + * This needs to be big enough to accommodate "struct cursor", while + * leaving some slack for future expansion. Changing this value will + * require recompiling all users of this library. Stack allocation is + * relatively cheap and unwind-state copying is relatively rare, so we want + * to err on making it rather too big than too small. + * + * To simplify this whole process, we are at least initially taking the + * tack that UNW_PPC64_* map straight across to the .eh_frame column register + * numbers. These register numbers come from gcc's source in + * gcc/config/rs6000/rs6000.h + * + * UNW_TDEP_CURSOR_LEN is in terms of unw_word_t size. Since we have 115 + * elements in the loc array, each sized 2 * unw_word_t, plus the rest of + * the cursor struct, this puts us at about 2 * 115 + 40 = 270. Let's + * round that up to 280. + */ + +#define UNW_TDEP_CURSOR_LEN 280 + +#if __WORDSIZE==32 +typedef uint32_t unw_word_t; +typedef int32_t unw_sword_t; +#else +typedef uint64_t unw_word_t; +typedef int64_t unw_sword_t; +#endif + +typedef long double unw_tdep_fpreg_t; + +/* + * Vector register (in PowerPC64 used for AltiVec registers) + */ +typedef struct { + uint64_t halves[2]; +} unw_tdep_vreg_t; + +typedef enum + { + UNW_PPC64_R0, + UNW_PPC64_R1, /* called STACK_POINTER in gcc */ + UNW_PPC64_R2, + UNW_PPC64_R3, + UNW_PPC64_R4, + UNW_PPC64_R5, + UNW_PPC64_R6, + UNW_PPC64_R7, + UNW_PPC64_R8, + UNW_PPC64_R9, + UNW_PPC64_R10, + UNW_PPC64_R11, /* called STATIC_CHAIN in gcc */ + UNW_PPC64_R12, + UNW_PPC64_R13, + UNW_PPC64_R14, + UNW_PPC64_R15, + UNW_PPC64_R16, + UNW_PPC64_R17, + UNW_PPC64_R18, + UNW_PPC64_R19, + UNW_PPC64_R20, + UNW_PPC64_R21, + UNW_PPC64_R22, + UNW_PPC64_R23, + UNW_PPC64_R24, + UNW_PPC64_R25, + UNW_PPC64_R26, + UNW_PPC64_R27, + UNW_PPC64_R28, + UNW_PPC64_R29, + UNW_PPC64_R30, + UNW_PPC64_R31, /* called HARD_FRAME_POINTER in gcc */ + + UNW_PPC64_F0 = 32, + UNW_PPC64_F1, + UNW_PPC64_F2, + UNW_PPC64_F3, + UNW_PPC64_F4, + UNW_PPC64_F5, + UNW_PPC64_F6, + UNW_PPC64_F7, + UNW_PPC64_F8, + UNW_PPC64_F9, + UNW_PPC64_F10, + UNW_PPC64_F11, + UNW_PPC64_F12, + UNW_PPC64_F13, + UNW_PPC64_F14, + UNW_PPC64_F15, + UNW_PPC64_F16, + UNW_PPC64_F17, + UNW_PPC64_F18, + UNW_PPC64_F19, + UNW_PPC64_F20, + UNW_PPC64_F21, + UNW_PPC64_F22, + UNW_PPC64_F23, + UNW_PPC64_F24, + UNW_PPC64_F25, + UNW_PPC64_F26, + UNW_PPC64_F27, + UNW_PPC64_F28, + UNW_PPC64_F29, + UNW_PPC64_F30, + UNW_PPC64_F31, + /* Note that there doesn't appear to be an .eh_frame register column + for the FPSCR register. I don't know why this is. Since .eh_frame + info is what this implementation uses for unwinding, we have no way + to unwind this register, and so we will not expose an FPSCR register + number in the libunwind API. + */ + + UNW_PPC64_LR = 65, + UNW_PPC64_CTR = 66, + UNW_PPC64_ARG_POINTER = 67, + + UNW_PPC64_CR0 = 68, + UNW_PPC64_CR1, + UNW_PPC64_CR2, + UNW_PPC64_CR3, + UNW_PPC64_CR4, + /* CR5 .. CR7 are currently unused */ + UNW_PPC64_CR5, + UNW_PPC64_CR6, + UNW_PPC64_CR7, + + UNW_PPC64_XER = 76, + + UNW_PPC64_V0 = 77, + UNW_PPC64_V1, + UNW_PPC64_V2, + UNW_PPC64_V3, + UNW_PPC64_V4, + UNW_PPC64_V5, + UNW_PPC64_V6, + UNW_PPC64_V7, + UNW_PPC64_V8, + UNW_PPC64_V9, + UNW_PPC64_V10, + UNW_PPC64_V11, + UNW_PPC64_V12, + UNW_PPC64_V13, + UNW_PPC64_V14, + UNW_PPC64_V15, + UNW_PPC64_V16, + UNW_PPC64_V17, + UNW_PPC64_V18, + UNW_PPC64_V19, + UNW_PPC64_V20, + UNW_PPC64_V21, + UNW_PPC64_V22, + UNW_PPC64_V23, + UNW_PPC64_V24, + UNW_PPC64_V25, + UNW_PPC64_V26, + UNW_PPC64_V27, + UNW_PPC64_V28, + UNW_PPC64_V29, + UNW_PPC64_V30, + UNW_PPC64_V31, + + UNW_PPC64_VRSAVE = 109, + UNW_PPC64_VSCR = 110, + UNW_PPC64_SPE_ACC = 111, + UNW_PPC64_SPEFSCR = 112, + + /* frame info (read-only) */ + UNW_PPC64_FRAME_POINTER, + UNW_PPC64_NIP, + + + UNW_TDEP_LAST_REG = UNW_PPC64_NIP, + + UNW_TDEP_IP = UNW_PPC64_NIP, + UNW_TDEP_SP = UNW_PPC64_R1, + UNW_TDEP_EH = UNW_PPC64_R12 + } +ppc64_regnum_t; + +typedef enum + { + UNW_PPC64_ABI_ELFv1, + UNW_PPC64_ABI_ELFv2 + } +ppc64_abi_t; + +/* + * According to David Edelsohn, GNU gcc uses R3, R4, R5, and maybe R6 for + * passing parameters to exception handlers. + */ + +#define UNW_TDEP_NUM_EH_REGS 4 + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. */ + } +unw_tdep_save_loc_t; + +/* On ppc64, we can directly use ucontext_t as the unwind context. */ +typedef ucontext_t unw_tdep_context_t; + +/* XXX this is not ideal: an application should not be prevented from + using the "getcontext" name just because it's using libunwind. We + can't just use __getcontext() either, because that isn't exported + by glibc... */ +#define unw_tdep_getcontext(uc) (getcontext (uc), 0) + +#include "libunwind-dynamic.h" + +typedef struct + { + /* no ppc64-specific auxiliary proc-info */ + } +unw_tdep_proc_info_t; + +#include "libunwind-common.h" + +#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) +extern int unw_tdep_is_fpreg (int); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ diff --git a/headers/libs/libunwind/libunwind-ptrace.h b/headers/libs/libunwind/libunwind-ptrace.h new file mode 100644 index 0000000000..801325c4d4 --- /dev/null +++ b/headers/libs/libunwind/libunwind-ptrace.h @@ -0,0 +1,63 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef libunwind_ptrace_h +#define libunwind_ptrace_h + +#include + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* Helper routines which make it easy to use libunwind via ptrace(). + They're available only if UNW_REMOTE_ONLY is _not_ defined and they + aren't really part of the libunwind API. They are implemented in a + archive library called libunwind-ptrace.a. */ + +extern void *_UPT_create (pid_t); +extern void _UPT_destroy (void *); +extern int _UPT_find_proc_info (unw_addr_space_t, unw_word_t, + unw_proc_info_t *, int, void *); +extern void _UPT_put_unwind_info (unw_addr_space_t, unw_proc_info_t *, void *); +extern int _UPT_get_dyn_info_list_addr (unw_addr_space_t, unw_word_t *, + void *); +extern int _UPT_access_mem (unw_addr_space_t, unw_word_t, unw_word_t *, int, + void *); +extern int _UPT_access_reg (unw_addr_space_t, unw_regnum_t, unw_word_t *, + int, void *); +extern int _UPT_access_fpreg (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, + int, void *); +extern int _UPT_get_proc_name (unw_addr_space_t, unw_word_t, char *, size_t, + unw_word_t *, void *); +extern int _UPT_resume (unw_addr_space_t, unw_cursor_t *, void *); +extern unw_accessors_t _UPT_accessors; + + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* libunwind_ptrace_h */ diff --git a/headers/libs/libunwind/libunwind-sh.h b/headers/libs/libunwind/libunwind-sh.h new file mode 100644 index 0000000000..927f61ff42 --- /dev/null +++ b/headers/libs/libunwind/libunwind-sh.h @@ -0,0 +1,114 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBUNWIND_H +#define LIBUNWIND_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include +#include +#include + +#define UNW_TARGET sh +#define UNW_TARGET_SH 1 + +#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ + +/* This needs to be big enough to accommodate "struct cursor", while + leaving some slack for future expansion. Changing this value will + require recompiling all users of this library. Stack allocation is + relatively cheap and unwind-state copying is relatively rare, so we + want to err on making it rather too big than too small. */ + +#define UNW_TDEP_CURSOR_LEN 4096 + +typedef uint32_t unw_word_t; +typedef int32_t unw_sword_t; + +typedef long double unw_tdep_fpreg_t; + +typedef enum + { + UNW_SH_R0, + UNW_SH_R1, + UNW_SH_R2, + UNW_SH_R3, + UNW_SH_R4, + UNW_SH_R5, + UNW_SH_R6, + UNW_SH_R7, + UNW_SH_R8, + UNW_SH_R9, + UNW_SH_R10, + UNW_SH_R11, + UNW_SH_R12, + UNW_SH_R13, + UNW_SH_R14, + UNW_SH_R15, + + UNW_SH_PC, + UNW_SH_PR, + + UNW_TDEP_LAST_REG = UNW_SH_PR, + + UNW_TDEP_IP = UNW_SH_PR, + UNW_TDEP_SP = UNW_SH_R15, + UNW_TDEP_EH = UNW_SH_R0 + } +sh_regnum_t; + +#define UNW_TDEP_NUM_EH_REGS 2 + +typedef ucontext_t unw_tdep_context_t; + +#define unw_tdep_getcontext(uc) (getcontext (uc), 0) + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. */ + } +unw_tdep_save_loc_t; + +#include "libunwind-dynamic.h" + +typedef struct + { + /* no sh-specific auxiliary proc-info */ + } +unw_tdep_proc_info_t; + +#include "libunwind-common.h" + +#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) +extern int unw_tdep_is_fpreg (int); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ diff --git a/headers/libs/libunwind/libunwind-tilegx.h b/headers/libs/libunwind/libunwind-tilegx.h new file mode 100644 index 0000000000..0f84ea65ee --- /dev/null +++ b/headers/libs/libunwind/libunwind-tilegx.h @@ -0,0 +1,161 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBUNWIND_H +#define LIBUNWIND_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include +#include + +#define UNW_TARGET tilegx +#define UNW_TARGET_TILEGX 1 + +#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ + +/* This needs to be big enough to accommodate "struct cursor", while + leaving some slack for future expansion. Changing this value will + require recompiling all users of this library. Stack allocation is + relatively cheap and unwind-state copying is relatively rare, so we + want to err on making it rather too big than too small. */ + +#define UNW_TDEP_CURSOR_LEN 4096 + +/* The size of a "word" varies on TILEGX. This type is used for memory + addresses and register values. */ +typedef uint64_t unw_word_t; +typedef int64_t unw_sword_t; + +typedef long double unw_tdep_fpreg_t; + +typedef enum +{ + UNW_TILEGX_R0, + UNW_TILEGX_R1, + UNW_TILEGX_R2, + UNW_TILEGX_R3, + UNW_TILEGX_R4, + UNW_TILEGX_R5, + UNW_TILEGX_R6, + UNW_TILEGX_R7, + UNW_TILEGX_R8, + UNW_TILEGX_R9, + UNW_TILEGX_R10, + UNW_TILEGX_R11, + UNW_TILEGX_R12, + UNW_TILEGX_R13, + UNW_TILEGX_R14, + UNW_TILEGX_R15, + UNW_TILEGX_R16, + UNW_TILEGX_R17, + UNW_TILEGX_R18, + UNW_TILEGX_R19, + UNW_TILEGX_R20, + UNW_TILEGX_R21, + UNW_TILEGX_R22, + UNW_TILEGX_R23, + UNW_TILEGX_R24, + UNW_TILEGX_R25, + UNW_TILEGX_R26, + UNW_TILEGX_R27, + UNW_TILEGX_R28, + UNW_TILEGX_R29, + UNW_TILEGX_R30, + UNW_TILEGX_R31, + UNW_TILEGX_R32, + UNW_TILEGX_R33, + UNW_TILEGX_R34, + UNW_TILEGX_R35, + UNW_TILEGX_R36, + UNW_TILEGX_R37, + UNW_TILEGX_R38, + UNW_TILEGX_R39, + UNW_TILEGX_R40, + UNW_TILEGX_R41, + UNW_TILEGX_R42, + UNW_TILEGX_R43, + UNW_TILEGX_R44, + UNW_TILEGX_R45, + UNW_TILEGX_R46, + UNW_TILEGX_R47, + UNW_TILEGX_R48, + UNW_TILEGX_R49, + UNW_TILEGX_R50, + UNW_TILEGX_R51, + UNW_TILEGX_R52, + UNW_TILEGX_R53, + UNW_TILEGX_R54, + UNW_TILEGX_R55, + + /* FIXME: Other registers! */ + + UNW_TILEGX_PC, + /* For TILEGX, the CFA is the value of SP (r54) at the call site in the + previous frame. */ + UNW_TILEGX_CFA, + + UNW_TDEP_LAST_REG = UNW_TILEGX_PC, + + UNW_TDEP_IP = UNW_TILEGX_R55, /* R55 is link register for Tilegx */ + UNW_TDEP_SP = UNW_TILEGX_R54, + UNW_TDEP_EH = UNW_TILEGX_R0 /* FIXME. */ +} tilegx_regnum_t; + +typedef enum +{ + UNW_TILEGX_ABI_N64 = 2 +} tilegx_abi_t; + +#define UNW_TDEP_NUM_EH_REGS 2 /* FIXME for TILEGX. */ + +typedef struct unw_tdep_save_loc +{ + /* Additional target-dependent info on a save location. */ +} unw_tdep_save_loc_t; + +typedef ucontext_t unw_tdep_context_t; + +#include "libunwind-dynamic.h" + +typedef struct +{ + /* no tilegx-specific auxiliary proc-info */ +} unw_tdep_proc_info_t; + +#include "libunwind-common.h" + +#define unw_tdep_getcontext getcontext + +#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) +extern int unw_tdep_is_fpreg (int); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ diff --git a/headers/libs/libunwind/libunwind-x86.h b/headers/libs/libunwind/libunwind-x86.h new file mode 100644 index 0000000000..40fe0464f2 --- /dev/null +++ b/headers/libs/libunwind/libunwind-x86.h @@ -0,0 +1,187 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBUNWIND_H +#define LIBUNWIND_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include +#include +#include + +#define UNW_TARGET x86 +#define UNW_TARGET_X86 1 + +#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ + +/* This needs to be big enough to accommodate "struct cursor", while + leaving some slack for future expansion. Changing this value will + require recompiling all users of this library. Stack allocation is + relatively cheap and unwind-state copying is relatively rare, so we + want to err on making it rather too big than too small. */ +#define UNW_TDEP_CURSOR_LEN 127 + +typedef uint32_t unw_word_t; +typedef int32_t unw_sword_t; + +typedef union { + struct { uint8_t b[4]; } val32; + struct { uint8_t b[10]; } val80; + struct { uint8_t b[16]; } val128; +} unw_tdep_fpreg_t; + +typedef enum + { + /* Note: general registers are expected to start with index 0. + This convention facilitates architecture-independent + implementation of the C++ exception handling ABI. See + _Unwind_SetGR() and _Unwind_GetGR() for details. + + The described register usage convention is based on "System V + Application Binary Interface, Intel386 Architecture Processor + Supplement, Fourth Edition" at + + http://www.linuxbase.org/spec/refspecs/elf/abi386-4.pdf + + It would have been nice to use the same register numbering as + DWARF, but that doesn't work because the libunwind requires + that the exception argument registers be consecutive, which the + wouldn't be with the DWARF numbering. */ + UNW_X86_EAX, /* scratch (exception argument 1) */ + UNW_X86_EDX, /* scratch (exception argument 2) */ + UNW_X86_ECX, /* scratch */ + UNW_X86_EBX, /* preserved */ + UNW_X86_ESI, /* preserved */ + UNW_X86_EDI, /* preserved */ + UNW_X86_EBP, /* (optional) frame-register */ + UNW_X86_ESP, /* (optional) frame-register */ + UNW_X86_EIP, /* frame-register */ + UNW_X86_EFLAGS, /* scratch (except for "direction", which is fixed */ + UNW_X86_TRAPNO, /* scratch */ + + /* MMX/stacked-fp registers */ + UNW_X86_ST0, /* fp return value */ + UNW_X86_ST1, /* scratch */ + UNW_X86_ST2, /* scratch */ + UNW_X86_ST3, /* scratch */ + UNW_X86_ST4, /* scratch */ + UNW_X86_ST5, /* scratch */ + UNW_X86_ST6, /* scratch */ + UNW_X86_ST7, /* scratch */ + + UNW_X86_FCW, /* scratch */ + UNW_X86_FSW, /* scratch */ + UNW_X86_FTW, /* scratch */ + UNW_X86_FOP, /* scratch */ + UNW_X86_FCS, /* scratch */ + UNW_X86_FIP, /* scratch */ + UNW_X86_FEA, /* scratch */ + UNW_X86_FDS, /* scratch */ + + /* SSE registers */ + UNW_X86_XMM0_lo, /* scratch */ + UNW_X86_XMM0_hi, /* scratch */ + UNW_X86_XMM1_lo, /* scratch */ + UNW_X86_XMM1_hi, /* scratch */ + UNW_X86_XMM2_lo, /* scratch */ + UNW_X86_XMM2_hi, /* scratch */ + UNW_X86_XMM3_lo, /* scratch */ + UNW_X86_XMM3_hi, /* scratch */ + UNW_X86_XMM4_lo, /* scratch */ + UNW_X86_XMM4_hi, /* scratch */ + UNW_X86_XMM5_lo, /* scratch */ + UNW_X86_XMM5_hi, /* scratch */ + UNW_X86_XMM6_lo, /* scratch */ + UNW_X86_XMM6_hi, /* scratch */ + UNW_X86_XMM7_lo, /* scratch */ + UNW_X86_XMM7_hi, /* scratch */ + + UNW_X86_MXCSR, /* scratch */ + + /* segment registers */ + UNW_X86_GS, /* special */ + UNW_X86_FS, /* special */ + UNW_X86_ES, /* special */ + UNW_X86_DS, /* special */ + UNW_X86_SS, /* special */ + UNW_X86_CS, /* special */ + UNW_X86_TSS, /* special */ + UNW_X86_LDT, /* special */ + + /* frame info (read-only) */ + UNW_X86_CFA, + + UNW_X86_XMM0, /* scratch */ + UNW_X86_XMM1, /* scratch */ + UNW_X86_XMM2, /* scratch */ + UNW_X86_XMM3, /* scratch */ + UNW_X86_XMM4, /* scratch */ + UNW_X86_XMM5, /* scratch */ + UNW_X86_XMM6, /* scratch */ + UNW_X86_XMM7, /* scratch */ + + UNW_TDEP_LAST_REG = UNW_X86_XMM7, + + UNW_TDEP_IP = UNW_X86_EIP, + UNW_TDEP_SP = UNW_X86_ESP, + UNW_TDEP_EH = UNW_X86_EAX + } +x86_regnum_t; + +#define UNW_TDEP_NUM_EH_REGS 2 /* eax and edx are exception args */ + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. */ + } +unw_tdep_save_loc_t; + +/* On x86, we can directly use ucontext_t as the unwind context. */ +typedef ucontext_t unw_tdep_context_t; + +#include "libunwind-dynamic.h" + +typedef struct + { + /* no x86-specific auxiliary proc-info */ + } +unw_tdep_proc_info_t; + +#include "libunwind-common.h" + +#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext) +extern int unw_tdep_getcontext (unw_tdep_context_t *); + +#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) +extern int unw_tdep_is_fpreg (int); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ diff --git a/headers/libs/libunwind/libunwind-x86_64.h b/headers/libs/libunwind/libunwind-x86_64.h new file mode 100644 index 0000000000..78eb541afb --- /dev/null +++ b/headers/libs/libunwind/libunwind-x86_64.h @@ -0,0 +1,141 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBUNWIND_H +#define LIBUNWIND_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include +#include +#include + +#define UNW_TARGET x86_64 +#define UNW_TARGET_X86_64 1 + +#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ + +/* This needs to be big enough to accommodate "struct cursor", while + leaving some slack for future expansion. Changing this value will + require recompiling all users of this library. Stack allocation is + relatively cheap and unwind-state copying is relatively rare, so we + want to err on making it rather too big than too small. */ +#define UNW_TDEP_CURSOR_LEN 127 + +typedef uint64_t unw_word_t; +typedef int64_t unw_sword_t; + +typedef long double unw_tdep_fpreg_t; + +typedef enum + { + UNW_X86_64_RAX, + UNW_X86_64_RDX, + UNW_X86_64_RCX, + UNW_X86_64_RBX, + UNW_X86_64_RSI, + UNW_X86_64_RDI, + UNW_X86_64_RBP, + UNW_X86_64_RSP, + UNW_X86_64_R8, + UNW_X86_64_R9, + UNW_X86_64_R10, + UNW_X86_64_R11, + UNW_X86_64_R12, + UNW_X86_64_R13, + UNW_X86_64_R14, + UNW_X86_64_R15, + UNW_X86_64_RIP, +#ifdef CONFIG_MSABI_SUPPORT + UNW_X86_64_XMM0, + UNW_X86_64_XMM1, + UNW_X86_64_XMM2, + UNW_X86_64_XMM3, + UNW_X86_64_XMM4, + UNW_X86_64_XMM5, + UNW_X86_64_XMM6, + UNW_X86_64_XMM7, + UNW_X86_64_XMM8, + UNW_X86_64_XMM9, + UNW_X86_64_XMM10, + UNW_X86_64_XMM11, + UNW_X86_64_XMM12, + UNW_X86_64_XMM13, + UNW_X86_64_XMM14, + UNW_X86_64_XMM15, + UNW_TDEP_LAST_REG = UNW_X86_64_XMM15, +#else + UNW_TDEP_LAST_REG = UNW_X86_64_RIP, +#endif + + /* XXX Add other regs here */ + + /* frame info (read-only) */ + UNW_X86_64_CFA, + + UNW_TDEP_IP = UNW_X86_64_RIP, + UNW_TDEP_SP = UNW_X86_64_RSP, + UNW_TDEP_BP = UNW_X86_64_RBP, + UNW_TDEP_EH = UNW_X86_64_RAX + } +x86_64_regnum_t; + +#define UNW_TDEP_NUM_EH_REGS 2 /* XXX Not sure what this means */ + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. */ + char unused; + } +unw_tdep_save_loc_t; + +/* On x86_64, we can directly use ucontext_t as the unwind context. */ +typedef ucontext_t unw_tdep_context_t; + +typedef struct + { + /* no x86-64-specific auxiliary proc-info */ + char unused; + } +unw_tdep_proc_info_t; + +#include "libunwind-dynamic.h" +#include "libunwind-common.h" + +#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext) +#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) + +extern int unw_tdep_getcontext (unw_tdep_context_t *); +extern int unw_tdep_is_fpreg (int); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ diff --git a/headers/libs/libunwind/libunwind.h b/headers/libs/libunwind/libunwind.h new file mode 100644 index 0000000000..113e1d2251 --- /dev/null +++ b/headers/libs/libunwind/libunwind.h @@ -0,0 +1,37 @@ +/* Provide a real file - not a symlink - as it would cause multiarch conflicts + when multiple different arch releases are installed simultaneously. */ + +#ifndef UNW_REMOTE_ONLY + +#if defined __aarch64__ +#include "libunwind-aarch64.h" +#elif defined __arm__ +# include "libunwind-arm.h" +#elif defined __hppa__ +# include "libunwind-hppa.h" +#elif defined __ia64__ +# include "libunwind-ia64.h" +#elif defined __mips__ +# include "libunwind-mips.h" +#elif defined __powerpc__ && !defined __powerpc64__ +# include "libunwind-ppc32.h" +#elif defined __powerpc64__ +# include "libunwind-ppc64.h" +#elif defined __sh__ +# include "libunwind-sh.h" +#elif defined __i386__ +# include "libunwind-x86.h" +#elif defined __x86_64__ +# include "libunwind-x86_64.h" +#elif defined __tilegx__ +# include "libunwind-tilegx.h" +#else +# error "Unsupported arch" +#endif + +#else /* UNW_REMOTE_ONLY */ + +//# include "libunwind-@arch@.h" +# error "UNW_REMOTE_ONLY is unsupported" + +#endif /* UNW_REMOTE_ONLY */ diff --git a/headers/libs/libunwind/libunwind_i.h b/headers/libs/libunwind/libunwind_i.h new file mode 100644 index 0000000000..26cc97fa42 --- /dev/null +++ b/headers/libs/libunwind/libunwind_i.h @@ -0,0 +1,359 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* This files contains libunwind-internal definitions which are + subject to frequent change and are not to be exposed to + libunwind-users. */ + +#ifndef libunwind_i_h +#define libunwind_i_h + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "compiler.h" + +#ifdef HAVE___THREAD + /* For now, turn off per-thread caching. It uses up too much TLS + memory per thread even when the thread never uses libunwind at + all. */ +# undef HAVE___THREAD +#endif + +/* Platform-independent libunwind-internal declarations. */ + +#include /* HP-UX needs this before include of pthread.h */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(HAVE_ELF_H) +# include +#elif defined(HAVE_SYS_ELF_H) +# include +#else +# error Could not locate +#endif + +#if defined(HAVE_ENDIAN_H) +# include +#elif defined(HAVE_SYS_ENDIAN_H) +# include +#else +# define __LITTLE_ENDIAN 1234 +# define __BIG_ENDIAN 4321 +# if defined(__hpux) +# define __BYTE_ORDER __BIG_ENDIAN +# elif defined(__QNX__) +# if defined(__BIGENDIAN__) +# define __BYTE_ORDER __BIG_ENDIAN +# elif defined(__LITTLEENDIAN__) +# define __BYTE_ORDER __LITTLE_ENDIAN +# else +# error Host has unknown byte-order. +# endif +# elif defined(__sun) +# define __BYTE_ORDER __LITTLE_ENDIAN +# else +# error Host has unknown byte-order. +# endif +#endif + +#if defined(HAVE__BUILTIN_UNREACHABLE) +# define unreachable() __builtin_unreachable() +#else +# define unreachable() do { } while (1) +#endif + +#ifdef DEBUG +# define UNW_DEBUG 1 +#else +# define UNW_DEBUG 0 +#endif + +/* Make it easy to write thread-safe code which may or may not be + linked against libpthread. The macros below can be used + unconditionally and if -lpthread is around, they'll call the + corresponding routines otherwise, they do nothing. */ + +#pragma weak pthread_mutex_init +#pragma weak pthread_mutex_lock +#pragma weak pthread_mutex_unlock + +#define mutex_init(l) \ + (pthread_mutex_init != NULL ? pthread_mutex_init ((l), NULL) : 0) +#define mutex_lock(l) \ + (pthread_mutex_lock != NULL ? pthread_mutex_lock (l) : 0) +#define mutex_unlock(l) \ + (pthread_mutex_unlock != NULL ? pthread_mutex_unlock (l) : 0) + +#ifdef HAVE_ATOMIC_OPS_H +# include +static inline int +cmpxchg_ptr (void *addr, void *old, void *new) +{ + union + { + void *vp; + AO_t *aop; + } + u; + + u.vp = addr; + return AO_compare_and_swap(u.aop, (AO_t) old, (AO_t) new); +} +# define fetch_and_add1(_ptr) AO_fetch_and_add1(_ptr) +# define fetch_and_add(_ptr, value) AO_fetch_and_add(_ptr, value) + /* GCC 3.2.0 on HP-UX crashes on cmpxchg_ptr() */ +# if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2) +# define HAVE_CMPXCHG +# endif +# define HAVE_FETCH_AND_ADD +#elif defined(HAVE_SYNC_ATOMICS) || defined(HAVE_IA64INTRIN_H) +# ifdef HAVE_IA64INTRIN_H +# include +# endif +static inline int +cmpxchg_ptr (void *addr, void *old, void *new) +{ + union + { + void *vp; + long *vlp; + } + u; + + u.vp = addr; + return __sync_bool_compare_and_swap(u.vlp, (long) old, (long) new); +} +# define fetch_and_add1(_ptr) __sync_fetch_and_add(_ptr, 1) +# define fetch_and_add(_ptr, value) __sync_fetch_and_add(_ptr, value) +# define HAVE_CMPXCHG +# define HAVE_FETCH_AND_ADD +#endif +#define atomic_read(ptr) (*(ptr)) + +#define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn)) +#define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn) + +#define unwi_full_mask UNWI_ARCH_OBJ(full_mask) + +/* Type of a mask that can be used to inhibit preemption. At the + userlevel, preemption is caused by signals and hence sigset_t is + appropriate. In constrast, the Linux kernel uses "unsigned long" + to hold the processor "flags" instead. */ +typedef sigset_t intrmask_t; + +extern intrmask_t unwi_full_mask; + +/* Silence compiler warnings about variables which are used only if libunwind + is configured in a certain way */ +static inline void mark_as_used(void *v UNUSED) { +} + +#if defined(CONFIG_BLOCK_SIGNALS) +# define SIGPROCMASK(how, new_mask, old_mask) \ + sigprocmask((how), (new_mask), (old_mask)) +#else +# define SIGPROCMASK(how, new_mask, old_mask) mark_as_used(old_mask) +#endif + +/* Prefer adaptive mutexes if available */ +#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP +#define UNW_PTHREAD_MUTEX_INITIALIZER PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP +#else +#define UNW_PTHREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#endif + +#define define_lock(name) \ + pthread_mutex_t name = UNW_PTHREAD_MUTEX_INITIALIZER +#define lock_init(l) mutex_init (l) +#define lock_acquire(l,m) \ +do { \ + SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &(m)); \ + mutex_lock (l); \ +} while (0) +#define lock_release(l,m) \ +do { \ + mutex_unlock (l); \ + SIGPROCMASK (SIG_SETMASK, &(m), NULL); \ +} while (0) + +#define SOS_MEMORY_SIZE 16384 /* see src/mi/mempool.c */ + +#ifndef MAP_ANONYMOUS +# define MAP_ANONYMOUS MAP_ANON +#endif +#define GET_MEMORY(mem, size) \ +do { \ + /* Hopefully, mmap() goes straight through to a system call stub... */ \ + mem = mmap (NULL, size, PROT_READ | PROT_WRITE, \ + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \ + if (mem == MAP_FAILED) \ + mem = NULL; \ +} while (0) + +#define unwi_find_dynamic_proc_info UNWI_OBJ(find_dynamic_proc_info) +#define unwi_extract_dynamic_proc_info UNWI_OBJ(extract_dynamic_proc_info) +#define unwi_put_dynamic_unwind_info UNWI_OBJ(put_dynamic_unwind_info) +#define unwi_dyn_remote_find_proc_info UNWI_OBJ(dyn_remote_find_proc_info) +#define unwi_dyn_remote_put_unwind_info UNWI_OBJ(dyn_remote_put_unwind_info) +#define unwi_dyn_validate_cache UNWI_OBJ(dyn_validate_cache) + +extern int unwi_find_dynamic_proc_info (unw_addr_space_t as, + unw_word_t ip, + unw_proc_info_t *pi, + int need_unwind_info, void *arg); +extern int unwi_extract_dynamic_proc_info (unw_addr_space_t as, + unw_word_t ip, + unw_proc_info_t *pi, + unw_dyn_info_t *di, + int need_unwind_info, + void *arg); +extern void unwi_put_dynamic_unwind_info (unw_addr_space_t as, + unw_proc_info_t *pi, void *arg); + +/* These handle the remote (cross-address-space) case of accessing + dynamic unwind info. */ + +extern int unwi_dyn_remote_find_proc_info (unw_addr_space_t as, + unw_word_t ip, + unw_proc_info_t *pi, + int need_unwind_info, + void *arg); +extern void unwi_dyn_remote_put_unwind_info (unw_addr_space_t as, + unw_proc_info_t *pi, + void *arg); +extern int unwi_dyn_validate_cache (unw_addr_space_t as, void *arg); + +extern unw_dyn_info_list_t _U_dyn_info_list; +extern pthread_mutex_t _U_dyn_info_list_lock; + +#if UNW_DEBUG +#define unwi_debug_level UNWI_ARCH_OBJ(debug_level) +extern long unwi_debug_level; + +# include +# define Debug(level,format...) \ +do { \ + if (unwi_debug_level >= level) \ + { \ + int _n = level; \ + if (_n > 16) \ + _n = 16; \ + fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__); \ + fprintf (stderr, format); \ + } \ +} while (0) +# define Dprintf(format...) fprintf (stderr, format) +#else +# define Debug(level,format...) +# define Dprintf(format...) +#endif + +static ALWAYS_INLINE int +print_error (const char *string) +{ + return write (2, string, strlen (string)); +} + +#define mi_init UNWI_ARCH_OBJ(mi_init) + +extern void mi_init (void); /* machine-independent initializations */ +extern unw_word_t _U_dyn_info_list_addr (void); + +/* This is needed/used by ELF targets only. */ + +struct elf_image + { + void *image; /* pointer to mmap'd image */ + size_t size; /* (file-) size of the image */ + }; + +struct elf_dyn_info + { + struct elf_image ei; + unw_dyn_info_t di_cache; + unw_dyn_info_t di_debug; /* additional table info for .debug_frame */ +#if UNW_TARGET_IA64 + unw_dyn_info_t ktab; +#endif +#if UNW_TARGET_ARM + unw_dyn_info_t di_arm; /* additional table info for .ARM.exidx */ +#endif + }; + +static inline void invalidate_edi (struct elf_dyn_info *edi) +{ + if (edi->ei.image) + munmap (edi->ei.image, edi->ei.size); + memset (edi, 0, sizeof (*edi)); + edi->di_cache.format = -1; + edi->di_debug.format = -1; +#if UNW_TARGET_ARM + edi->di_arm.format = -1; +#endif +} + + +/* Provide a place holder for architecture to override for fast access + to memory when known not to need to validate and know the access + will be local to the process. A suitable override will improve + unw_tdep_trace() performance in particular. */ +#define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \ + do { (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); } \ + while (0) + +/* Define GNU and processor specific values for the Phdr p_type field in case + they aren't defined by . */ +#ifndef PT_GNU_EH_FRAME +# define PT_GNU_EH_FRAME 0x6474e550 +#endif /* !PT_GNU_EH_FRAME */ +#ifndef PT_ARM_EXIDX +# define PT_ARM_EXIDX 0x70000001 /* ARM unwind segment */ +#endif /* !PT_ARM_EXIDX */ + +#include "tdep/libunwind_i.h" + +#ifndef tdep_get_func_addr +# define tdep_get_func_addr(as,addr,v) (*(v) = addr, 0) +#endif + +#ifndef DWARF_VAL_LOC +# define DWARF_IS_VAL_LOC(l) 0 +# define DWARF_VAL_LOC(c,v) DWARF_NULL_LOC +#endif + +#define UNW_ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL)) + +#endif /* libunwind_i_h */ diff --git a/headers/libs/libunwind/mempool.h b/headers/libs/libunwind/mempool.h new file mode 100644 index 0000000000..1f1c770099 --- /dev/null +++ b/headers/libs/libunwind/mempool.h @@ -0,0 +1,89 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef mempool_h +#define mempool_h + +/* Memory pools provide simple memory management of fixed-size + objects. Memory pools are used for two purposes: + + o To ensure a stack can be unwound even when a process + is out of memory. + + o To ensure a stack can be unwound at any time in a + multi-threaded process (e.g., even at a time when the normal + malloc-lock is taken, possibly by the very thread that is + being unwind). + + + To achieve the second objective, memory pools allocate memory + directly via mmap() system call (or an equivalent facility). + + The first objective is accomplished by reserving memory ahead of + time. Since the memory requirements of stack unwinding generally + depends on the complexity of the procedures being unwind, there is + no absolute guarantee that unwinding will always work, but in + practice, this should not be a serious problem. */ + +#include + +#include "libunwind_i.h" + +#define sos_alloc(s) UNWI_ARCH_OBJ(_sos_alloc)(s) +#define mempool_init(p,s,r) UNWI_ARCH_OBJ(_mempool_init)(p,s,r) +#define mempool_alloc(p) UNWI_ARCH_OBJ(_mempool_alloc)(p) +#define mempool_free(p,o) UNWI_ARCH_OBJ(_mempool_free)(p,o) + +/* The mempool structure should be treated as an opaque object. It's + declared here only to enable static allocation of mempools. */ +struct mempool + { + pthread_mutex_t lock; + size_t obj_size; /* object size (rounded up for alignment) */ + size_t chunk_size; /* allocation granularity */ + unsigned int reserve; /* minimum (desired) size of the free-list */ + unsigned int num_free; /* number of objects on the free-list */ + struct object + { + struct object *next; + } + *free_list; + }; + +/* Emergency allocation for one-time stuff that doesn't fit the memory + pool model. A limited amount of memory is available in this + fashion and once allocated, there is no way to free it. */ +extern void *sos_alloc (size_t size); + +/* Initialize POOL for an object size of OBJECT_SIZE bytes. RESERVE + is the number of objects that should be reserved for use under + tight memory situations. If it is zero, mempool attempts to pick a + reasonable default value. */ +extern void mempool_init (struct mempool *pool, + size_t obj_size, size_t reserve); +extern void *mempool_alloc (struct mempool *pool); +extern void mempool_free (struct mempool *pool, void *object); + +#endif /* mempool_h */ diff --git a/headers/libs/libunwind/remote.h b/headers/libs/libunwind/remote.h new file mode 100644 index 0000000000..6fdf64c17f --- /dev/null +++ b/headers/libs/libunwind/remote.h @@ -0,0 +1,127 @@ +#ifndef REMOTE_H +#define REMOTE_H + +/* Helper functions for accessing (remote) memory. These functions + assume that all addresses are naturally aligned (e.g., 32-bit + quantity is stored at a 32-bit-aligned address. */ + +#ifdef UNW_LOCAL_ONLY + +static inline int +fetch8 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int8_t *valp, void *arg) +{ + *valp = *(int8_t *) (uintptr_t) *addr; + *addr += 1; + return 0; +} + +static inline int +fetch16 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int16_t *valp, void *arg) +{ + *valp = *(int16_t *) (uintptr_t) *addr; + *addr += 2; + return 0; +} + +static inline int +fetch32 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int32_t *valp, void *arg) +{ + *valp = *(int32_t *) (uintptr_t) *addr; + *addr += 4; + return 0; +} + +static inline int +fetchw (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, unw_word_t *valp, void *arg) +{ + *valp = *(unw_word_t *) (uintptr_t) *addr; + *addr += sizeof (unw_word_t); + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ + +#define WSIZE (sizeof (unw_word_t)) + +static inline int +fetch8 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int8_t *valp, void *arg) +{ + unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr; + int ret; + + *addr += 1; + + ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg); + +#if __BYTE_ORDER == __LITTLE_ENDIAN + val >>= 8*off; +#else + val >>= 8*(WSIZE - 1 - off); +#endif + *valp = val & 0xff; + return ret; +} + +static inline int +fetch16 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int16_t *valp, void *arg) +{ + unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr; + int ret; + + assert ((off & 0x1) == 0); + + *addr += 2; + + ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg); + +#if __BYTE_ORDER == __LITTLE_ENDIAN + val >>= 8*off; +#else + val >>= 8*(WSIZE - 2 - off); +#endif + *valp = val & 0xffff; + return ret; +} + +static inline int +fetch32 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int32_t *valp, void *arg) +{ + unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr; + int ret; + + assert ((off & 0x3) == 0); + + *addr += 4; + + ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg); + +#if __BYTE_ORDER == __LITTLE_ENDIAN + val >>= 8*off; +#else + val >>= 8*(WSIZE - 4 - off); +#endif + *valp = val & 0xffffffff; + return ret; +} + +static inline int +fetchw (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, unw_word_t *valp, void *arg) +{ + int ret; + + ret = (*a->access_mem) (as, *addr, valp, 0, arg); + *addr += WSIZE; + return ret; +} + +#endif /* !UNW_LOCAL_ONLY */ + +#endif /* REMOTE_H */ diff --git a/headers/libs/libunwind/tdep-aarch64/dwarf-config.h b/headers/libs/libunwind/tdep-aarch64/dwarf-config.h new file mode 100644 index 0000000000..f65db17ee6 --- /dev/null +++ b/headers/libs/libunwind/tdep-aarch64/dwarf-config.h @@ -0,0 +1,52 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef dwarf_config_h +#define dwarf_config_h + +/* This matches the value udes by GCC (see + gcc/config/aarch64/aarch64.h:DWARF_FRAME_REGISTERS. */ +#define DWARF_NUM_PRESERVED_REGS 97 + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 0 + +#define dwarf_to_unw_regnum(reg) (((reg) <= UNW_AARCH64_V31) ? (reg) : 0) + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/headers/libs/libunwind/tdep-aarch64/jmpbuf.h b/headers/libs/libunwind/tdep-aarch64/jmpbuf.h new file mode 100644 index 0000000000..3f01a442ba --- /dev/null +++ b/headers/libs/libunwind/tdep-aarch64/jmpbuf.h @@ -0,0 +1,33 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +/* FIXME for AArch64 */ + +#define JB_SP 13 +#define JB_RP 14 +#define JB_MASK_SAVED 15 +#define JB_MASK 16 diff --git a/headers/libs/libunwind/tdep-aarch64/libunwind_i.h b/headers/libs/libunwind/tdep-aarch64/libunwind_i.h new file mode 100644 index 0000000000..ca2815500c --- /dev/null +++ b/headers/libs/libunwind/tdep-aarch64/libunwind_i.h @@ -0,0 +1,318 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef AARCH64_LIBUNWIND_I_H +#define AARCH64_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf64.h" +#include "mempool.h" +#include "dwarf.h" + +typedef enum + { + UNW_AARCH64_FRAME_STANDARD = -2, /* regular fp, sp +/- offset */ + UNW_AARCH64_FRAME_SIGRETURN = -1, /* special sigreturn frame */ + UNW_AARCH64_FRAME_OTHER = 0, /* not cacheable (special or unrecognised) */ + UNW_AARCH64_FRAME_GUESSED = 1 /* guessed it was regular, but not known */ + } +unw_tdep_frame_type_t; + +typedef struct + { + uint64_t virtual_address; + int64_t frame_type : 2; /* unw_tdep_frame_type_t classification */ + int64_t last_frame : 1; /* non-zero if last frame in chain */ + int64_t cfa_reg_sp : 1; /* cfa dwarf base register is sp vs. fp */ + int64_t cfa_reg_offset : 30; /* cfa is at this offset from base register value */ + int64_t fp_cfa_offset : 30; /* fp saved at this offset from cfa (-1 = not saved) */ + int64_t lr_cfa_offset : 30; /* lr saved at this offset from cfa (-1 = not saved) */ + int64_t sp_cfa_offset : 30; /* sp saved at this offset from cfa (-1 = not saved) */ + } +unw_tdep_frame_t; + +#ifdef UNW_LOCAL_ONLY + +typedef unw_word_t aarch64_loc_t; + +#else /* !UNW_LOCAL_ONLY */ + +typedef struct aarch64_loc + { + unw_word_t w0, w1; + } +aarch64_loc_t; + +#endif /* !UNW_LOCAL_ONLY */ + +struct unw_addr_space + { + struct unw_accessors acc; + int big_endian; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + }; + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + + unw_tdep_frame_t frame_info; /* quick tracing assist info */ + + enum + { + AARCH64_SCF_NONE, + AARCH64_SCF_LINUX_RT_SIGFRAME, + } + sigcontext_format; + unw_word_t sigcontext_addr; + unw_word_t sigcontext_sp; + unw_word_t sigcontext_pc; + int validate; + }; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_word_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_word_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, + c->as_arg); +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, + 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + + + +#define tdep_getcontext_trace UNW_ARCH_OBJ(getcontext_trace) +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c,rs) do {} while(0) +#define tdep_reuse_frame(c,rs) do {} while(0) +#define tdep_stash_frame UNW_OBJ(tdep_stash_frame) +#define tdep_trace UNW_OBJ(tdep_trace) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) ((as)->big_endian) + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t *di, unw_proc_info_t *pi, + int need_unwind_info, void *arg); +extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); +extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n); +extern void tdep_stash_frame (struct dwarf_cursor *c, + struct dwarf_reg_state *rs); +extern int tdep_getcontext_trace (unw_tdep_context_t *); + +#endif /* AARCH64_LIBUNWIND_I_H */ diff --git a/headers/libs/libunwind/tdep-arm/dwarf-config.h b/headers/libs/libunwind/tdep-arm/dwarf-config.h new file mode 100644 index 0000000000..f50228975e --- /dev/null +++ b/headers/libs/libunwind/tdep-arm/dwarf-config.h @@ -0,0 +1,51 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef dwarf_config_h +#define dwarf_config_h + +/* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not + explicitly defined. */ +#define DWARF_NUM_PRESERVED_REGS 128 + +#define dwarf_to_unw_regnum(reg) (((reg) < 16) ? (reg) : 0) + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 0 + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/headers/libs/libunwind/tdep-arm/ex_tables.h b/headers/libs/libunwind/tdep-arm/ex_tables.h new file mode 100644 index 0000000000..9df5e0a9fa --- /dev/null +++ b/headers/libs/libunwind/tdep-arm/ex_tables.h @@ -0,0 +1,55 @@ +/* libunwind - a platform-independent unwind library + Copyright 2011 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef ARM_EX_TABLES_H +#define ARM_EX_TABLES_H + +typedef enum arm_exbuf_cmd { + ARM_EXIDX_CMD_FINISH, + ARM_EXIDX_CMD_DATA_PUSH, + ARM_EXIDX_CMD_DATA_POP, + ARM_EXIDX_CMD_REG_POP, + ARM_EXIDX_CMD_REG_TO_SP, + ARM_EXIDX_CMD_VFP_POP, + ARM_EXIDX_CMD_WREG_POP, + ARM_EXIDX_CMD_WCGR_POP, + ARM_EXIDX_CMD_RESERVED, + ARM_EXIDX_CMD_REFUSED, +} arm_exbuf_cmd_t; + +struct arm_exbuf_data +{ + arm_exbuf_cmd_t cmd; + uint32_t data; +}; + +#define arm_exidx_extract UNW_OBJ(arm_exidx_extract) +#define arm_exidx_decode UNW_OBJ(arm_exidx_decode) +#define arm_exidx_apply_cmd UNW_OBJ(arm_exidx_apply_cmd) + +int arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf); +int arm_exidx_decode (const uint8_t *buf, uint8_t len, struct dwarf_cursor *c); +int arm_exidx_apply_cmd (struct arm_exbuf_data *edata, struct dwarf_cursor *c); + +#endif // ARM_EX_TABLES_H diff --git a/headers/libs/libunwind/tdep-arm/jmpbuf.h b/headers/libs/libunwind/tdep-arm/jmpbuf.h new file mode 100644 index 0000000000..008e77f796 --- /dev/null +++ b/headers/libs/libunwind/tdep-arm/jmpbuf.h @@ -0,0 +1,32 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +/* FIXME for ARM! */ + +#define JB_SP 4 +#define JB_RP 5 +#define JB_MASK_SAVED 6 +#define JB_MASK 7 diff --git a/headers/libs/libunwind/tdep-arm/libunwind_i.h b/headers/libs/libunwind/tdep-arm/libunwind_i.h new file mode 100644 index 0000000000..d3a279c908 --- /dev/null +++ b/headers/libs/libunwind/tdep-arm/libunwind_i.h @@ -0,0 +1,321 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef ARM_LIBUNWIND_I_H +#define ARM_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf32.h" +#include "mempool.h" +#include "dwarf.h" +#include "ex_tables.h" + +typedef enum + { + UNW_ARM_FRAME_STANDARD = -2, /* regular r7, sp +/- offset */ + UNW_ARM_FRAME_SIGRETURN = -1, /* special sigreturn frame */ + UNW_ARM_FRAME_OTHER = 0, /* not cacheable (special or unrecognised) */ + UNW_ARM_FRAME_GUESSED = 1 /* guessed it was regular, but not known */ + } +unw_tdep_frame_type_t; + +typedef struct + { + uint32_t virtual_address; + int32_t frame_type : 2; /* unw_tdep_frame_type_t classification */ + int32_t last_frame : 1; /* non-zero if last frame in chain */ + int32_t cfa_reg_sp : 1; /* cfa dwarf base register is sp vs. r7 */ + int32_t cfa_reg_offset : 30; /* cfa is at this offset from base register value */ + int32_t r7_cfa_offset : 30; /* r7 saved at this offset from cfa (-1 = not saved) */ + int32_t lr_cfa_offset : 30; /* lr saved at this offset from cfa (-1 = not saved) */ + int32_t sp_cfa_offset : 30; /* sp saved at this offset from cfa (-1 = not saved) */ + } +unw_tdep_frame_t; + +struct unw_addr_space + { + struct unw_accessors acc; + int big_endian; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + }; + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + + unw_tdep_frame_t frame_info; /* quick tracing assist info */ + + enum + { + ARM_SCF_NONE, /* no signal frame */ + ARM_SCF_LINUX_SIGFRAME, /* non-RT signal frame, kernel >=2.6.18 */ + ARM_SCF_LINUX_RT_SIGFRAME, /* RT signal frame, kernel >=2.6.18 */ + ARM_SCF_LINUX_OLD_SIGFRAME, /* non-RT signal frame, kernel < 2.6.18 */ + ARM_SCF_LINUX_OLD_RT_SIGFRAME /* RT signal frame, kernel < 2.6.18 */ + } + sigcontext_format; + unw_word_t sigcontext_addr; + unw_word_t sigcontext_sp; + unw_word_t sigcontext_pc; + int validate; + }; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_word_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_word_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, + c->as_arg); +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, + 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +#define arm_find_proc_info UNW_OBJ(find_proc_info) +#define arm_put_unwind_info UNW_OBJ(put_unwind_info) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table UNW_OBJ(search_unwind_table) +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c,rs) do {} while(0) +#define tdep_reuse_frame(c,rs) do {} while(0) +#define tdep_stash_frame UNW_OBJ(tdep_stash_frame) +#define tdep_trace UNW_OBJ(tdep_trace) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + arm_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + arm_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) ((as)->big_endian) + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int arm_find_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, int need_unwind_info, + void *arg); +extern void arm_put_unwind_info (unw_addr_space_t as, + unw_proc_info_t *pi, void *arg); +extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t *di, unw_proc_info_t *pi, + int need_unwind_info, void *arg); +extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); +extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n); +extern void tdep_stash_frame (struct dwarf_cursor *c, + struct dwarf_reg_state *rs); + +/* unwinding method selection support */ +#define UNW_ARM_METHOD_ALL 0xFF +#define UNW_ARM_METHOD_DWARF 0x01 +#define UNW_ARM_METHOD_FRAME 0x02 +#define UNW_ARM_METHOD_EXIDX 0x04 + +#define unwi_unwind_method UNW_OBJ(unwind_method) +extern int unwi_unwind_method; + +#define UNW_TRY_METHOD(x) (unwi_unwind_method & x) + +#endif /* ARM_LIBUNWIND_I_H */ diff --git a/headers/libs/libunwind/tdep-hppa/dwarf-config.h b/headers/libs/libunwind/tdep-hppa/dwarf-config.h new file mode 100644 index 0000000000..fb963c7d30 --- /dev/null +++ b/headers/libs/libunwind/tdep-hppa/dwarf-config.h @@ -0,0 +1,54 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef dwarf_config_h +#define dwarf_config_h + +/* See DWARF_FRAME_REGNUM() macro in gcc/config/pa/pa32-regs.h: */ +#define dwarf_to_unw_regnum(reg) \ + (((reg) < DWARF_NUM_PRESERVED_REGS) ? (reg) : 0) + +/* This matches the value used by GCC (see + gcc/config/pa/pa32-regs.h:FIRST_PSEUDO_REGISTER), which leaves + plenty of room for expansion. */ +#define DWARF_NUM_PRESERVED_REGS 89 + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 1 + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see X86_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/headers/libs/libunwind/tdep-hppa/jmpbuf.h b/headers/libs/libunwind/tdep-hppa/jmpbuf.h new file mode 100644 index 0000000000..91f062ff7d --- /dev/null +++ b/headers/libs/libunwind/tdep-hppa/jmpbuf.h @@ -0,0 +1,33 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +#ifndef JB_SP +# define JB_SP 19 +#endif +#define JB_RP 20 +#define JB_MASK_SAVED 21 +#define JB_MASK 22 diff --git a/headers/libs/libunwind/tdep-hppa/libunwind_i.h b/headers/libs/libunwind/tdep-hppa/libunwind_i.h new file mode 100644 index 0000000000..d5cc1b9244 --- /dev/null +++ b/headers/libs/libunwind/tdep-hppa/libunwind_i.h @@ -0,0 +1,277 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef HPPA_LIBUNWIND_I_H +#define HPPA_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf32.h" +#include "mempool.h" +#include "dwarf.h" + +typedef struct + { + /* no hppa-specific fast trace */ + } +unw_tdep_frame_t; + +struct unw_addr_space + { + struct unw_accessors acc; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + }; + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + + /* Format of sigcontext structure and address at which it is + stored: */ + enum + { + HPPA_SCF_NONE, /* no signal frame encountered */ + HPPA_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ + } + sigcontext_format; + unw_word_t sigcontext_addr; + }; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_word_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_word_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, + c->as_arg); +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, + 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c,rs) do {} while(0) +#define tdep_reuse_frame(c,rs) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) 1 + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t *di, unw_proc_info_t *pi, + int need_unwind_info, void *arg); +extern void *tdep_uc_addr (ucontext_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); + +#endif /* HPPA_LIBUNWIND_I_H */ diff --git a/headers/libs/libunwind/tdep-ia64/jmpbuf.h b/headers/libs/libunwind/tdep-ia64/jmpbuf.h new file mode 100644 index 0000000000..d642af2075 --- /dev/null +++ b/headers/libs/libunwind/tdep-ia64/jmpbuf.h @@ -0,0 +1,32 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP and BSP: */ + +#define JB_SP 0 +#define JB_RP 8 +#define JB_BSP 17 +#define JB_MASK_SAVED 70 +#define JB_MASK 71 diff --git a/headers/libs/libunwind/tdep-ia64/libunwind_i.h b/headers/libs/libunwind/tdep-ia64/libunwind_i.h new file mode 100644 index 0000000000..7e57c7b6b0 --- /dev/null +++ b/headers/libs/libunwind/tdep-ia64/libunwind_i.h @@ -0,0 +1,279 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef IA64_LIBUNWIND_I_H +#define IA64_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include "elf64.h" +#include "mempool.h" + +typedef struct + { + /* no ia64-specific fast trace */ + } +unw_tdep_frame_t; + +enum ia64_pregnum + { + /* primary unat: */ + IA64_REG_PRI_UNAT_GR, + IA64_REG_PRI_UNAT_MEM, + + /* memory stack (order matters: see build_script() */ + IA64_REG_PSP, /* previous memory stack pointer */ + /* register stack */ + IA64_REG_BSP, /* register stack pointer */ + IA64_REG_BSPSTORE, + IA64_REG_PFS, /* previous function state */ + IA64_REG_RNAT, + /* instruction pointer: */ + IA64_REG_IP, + + /* preserved registers: */ + IA64_REG_R4, IA64_REG_R5, IA64_REG_R6, IA64_REG_R7, + IA64_REG_NAT4, IA64_REG_NAT5, IA64_REG_NAT6, IA64_REG_NAT7, + IA64_REG_UNAT, IA64_REG_PR, IA64_REG_LC, IA64_REG_FPSR, + IA64_REG_B1, IA64_REG_B2, IA64_REG_B3, IA64_REG_B4, IA64_REG_B5, + IA64_REG_F2, IA64_REG_F3, IA64_REG_F4, IA64_REG_F5, + IA64_REG_F16, IA64_REG_F17, IA64_REG_F18, IA64_REG_F19, + IA64_REG_F20, IA64_REG_F21, IA64_REG_F22, IA64_REG_F23, + IA64_REG_F24, IA64_REG_F25, IA64_REG_F26, IA64_REG_F27, + IA64_REG_F28, IA64_REG_F29, IA64_REG_F30, IA64_REG_F31, + IA64_NUM_PREGS + }; + +#ifdef UNW_LOCAL_ONLY + +typedef unw_word_t ia64_loc_t; + +#else /* !UNW_LOCAL_ONLY */ + +typedef struct ia64_loc + { + unw_word_t w0, w1; + } +ia64_loc_t; + +#endif /* !UNW_LOCAL_ONLY */ + +#include "script.h" + +#define ABI_UNKNOWN 0 +#define ABI_LINUX 1 +#define ABI_HPUX 2 +#define ABI_FREEBSD 3 +#define ABI_OPENVMS 4 +#define ABI_NSK 5 /* Tandem/HP Non-Stop Kernel */ +#define ABI_WINDOWS 6 + +struct unw_addr_space + { + struct unw_accessors acc; + int big_endian; + int abi; /* abi < 0 => unknown, 0 => SysV, 1 => HP-UX, 2 => Windows */ + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ +#ifndef UNW_REMOTE_ONLY + unsigned long long shared_object_removals; +#endif + + struct ia64_script_cache global_cache; + }; + +/* Note: The ABI numbers in the ABI-markers (.unwabi directive) are + not the same as the above ABI numbers. */ +#define ABI_MARKER_OLD_LINUX_SIGTRAMP ((0 << 8) | 's') +#define ABI_MARKER_OLD_LINUX_INTERRUPT ((0 << 8) | 'i') +#define ABI_MARKER_HP_UX_SIGTRAMP ((1 << 8) | 1) +#define ABI_MARKER_LINUX_SIGTRAMP ((3 << 8) | 's') +#define ABI_MARKER_LINUX_INTERRUPT ((3 << 8) | 'i') + +struct cursor + { + void *as_arg; /* argument to address-space callbacks */ + unw_addr_space_t as; /* reference to per-address-space info */ + + /* IP, CFM, and predicate cache (these are always equal to the + values stored in ip_loc, cfm_loc, and pr_loc, + respectively). */ + unw_word_t ip; /* instruction pointer value */ + unw_word_t cfm; /* current frame mask */ + unw_word_t pr; /* current predicate values */ + + /* current frame info: */ + unw_word_t bsp; /* backing store pointer value */ + unw_word_t sp; /* stack pointer value */ + unw_word_t psp; /* previous sp value */ + ia64_loc_t cfm_loc; /* cfm save location (or NULL) */ + ia64_loc_t ec_loc; /* ar.ec save location (usually cfm_loc) */ + ia64_loc_t loc[IA64_NUM_PREGS]; + + unw_word_t eh_args[4]; /* exception handler arguments */ + unw_word_t sigcontext_addr; /* address of sigcontext or 0 */ + unw_word_t sigcontext_off; /* sigcontext-offset relative to signal sp */ + + short hint; + short prev_script; + + uint8_t nat_bitnr[4]; /* NaT bit numbers for r4-r7 */ + uint16_t abi_marker; /* abi_marker for current frame (if any) */ + uint16_t last_abi_marker; /* last abi_marker encountered so far */ + uint8_t eh_valid_mask; + + unsigned int pi_valid :1; /* is proc_info valid? */ + unsigned int pi_is_dynamic :1; /* proc_info found via dynamic proc info? */ + unw_proc_info_t pi; /* info about current procedure */ + + /* In case of stack-discontiguities, such as those introduced by + signal-delivery on an alternate signal-stack (see + sigaltstack(2)), we use the following data-structure to keep + track of the register-backing-store areas across on which the + current frame may be backed up. Since there are at most 96 + stacked registers and since we only have to track the current + frame and only areas that are not empty, this puts an upper + limit on the # of backing-store areas we have to track. + + Note that the rbs-area indexed by rbs_curr identifies the + rbs-area that was in effect at the time AR.BSP had the value + c->bsp. However, this rbs area may not actually contain the + value in the register that c->bsp corresponds to because that + register may not have gotten spilled until much later, when a + possibly different rbs-area might have been in effect + already. */ + uint8_t rbs_curr; /* index of curr. rbs-area (contains c->bsp) */ + uint8_t rbs_left_edge; /* index of inner-most valid rbs-area */ + struct rbs_area + { + unw_word_t end; + unw_word_t size; + ia64_loc_t rnat_loc; + } + rbs_area[96 + 2]; /* 96 stacked regs + 1 extra stack on each side... */ +}; + +struct ia64_global_unwind_state + { + pthread_mutex_t lock; /* global data lock */ + + volatile char init_done; + + /* Table of registers that prologues can save (and order in which + they're saved). */ + const unsigned char save_order[8]; + + /* + * uc_addr() may return pointers to these variables. We need to + * make sure they don't get written via ia64_put() or + * ia64_putfp(). To make it possible to test for these variables + * quickly, we collect them in a single sub-structure. + */ + struct + { + unw_word_t r0; /* r0 is byte-order neutral */ + unw_fpreg_t f0; /* f0 is byte-order neutral */ + unw_fpreg_t f1_le, f1_be; /* f1 is byte-order dependent */ + } + read_only; + unw_fpreg_t nat_val_le, nat_val_be; + unw_fpreg_t int_val_le, int_val_be; + + struct mempool reg_state_pool; + struct mempool labeled_state_pool; + +# if UNW_DEBUG + const char *preg_name[IA64_NUM_PREGS]; +# endif + }; + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done unw.init_done +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table unw_search_ia64_unwind_table +#define tdep_find_unwind_table ia64_find_unwind_table +#define tdep_find_proc_info UNW_OBJ(find_proc_info) +#define tdep_uc_addr UNW_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c,rs) do {} while(0) +#define tdep_reuse_frame(c,rs) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) +#define tdep_get_as(c) ((c)->as) +#define tdep_get_as_arg(c) ((c)->as_arg) +#define tdep_get_ip(c) ((c)->ip) +#define tdep_big_endian(as) ((c)->as->big_endian != 0) + +#ifndef UNW_LOCAL_ONLY +# define tdep_put_unwind_info UNW_OBJ(put_unwind_info) +#endif + +/* This can't be an UNW_ARCH_OBJ() because we need separate + unw.initialized flags for the local-only and generic versions of + the library. Also, if we wanted to have a single, shared global + data structure, we couldn't declare "unw" as HIDDEN/PROTECTED. */ +#define unw UNW_OBJ(data) + +extern void tdep_init (void); +extern int tdep_find_unwind_table (struct elf_dyn_info *edi, + unw_addr_space_t as, char *path, + unw_word_t segbase, unw_word_t mapoff, + unw_word_t ip); +extern int tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, int need_unwind_info, + void *arg); +extern void tdep_put_unwind_info (unw_addr_space_t as, + unw_proc_info_t *pi, void *arg); +extern void *tdep_uc_addr (ucontext_t *uc, unw_regnum_t regnum, + uint8_t *nat_bitnr); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); + +extern struct ia64_global_unwind_state unw; + +/* In user-level, we have no reasonable way of determining the base of + an arbitrary backing-store. We default to half the + address-space. */ +#define rbs_get_base(c,bspstore,rbs_basep) \ + (*(rbs_basep) = (bspstore) - (((unw_word_t) 1) << 63), 0) + +#endif /* IA64_LIBUNWIND_I_H */ diff --git a/headers/libs/libunwind/tdep-ia64/rse.h b/headers/libs/libunwind/tdep-ia64/rse.h new file mode 100644 index 0000000000..ee521a5917 --- /dev/null +++ b/headers/libs/libunwind/tdep-ia64/rse.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 1998, 1999, 2002, 2003, 2005 Hewlett-Packard Co + * David Mosberger-Tang + * + * Register stack engine related helper functions. This file may be + * used in applications, so be careful about the name-space and give + * some consideration to non-GNU C compilers (though __inline__ is + * fine). + */ +#ifndef RSE_H +#define RSE_H + +#include + +static inline uint64_t +rse_slot_num (uint64_t addr) +{ + return (addr >> 3) & 0x3f; +} + +/* + * Return TRUE if ADDR is the address of an RNAT slot. + */ +static inline uint64_t +rse_is_rnat_slot (uint64_t addr) +{ + return rse_slot_num (addr) == 0x3f; +} + +/* + * Returns the address of the RNAT slot that covers the slot at + * address SLOT_ADDR. + */ +static inline uint64_t +rse_rnat_addr (uint64_t slot_addr) +{ + return slot_addr | (0x3f << 3); +} + +/* + * Calculate the number of registers in the dirty partition starting at + * BSPSTORE and ending at BSP. This isn't simply (BSP-BSPSTORE)/8 + * because every 64th slot stores ar.rnat. + */ +static inline uint64_t +rse_num_regs (uint64_t bspstore, uint64_t bsp) +{ + uint64_t slots = (bsp - bspstore) >> 3; + + return slots - (rse_slot_num(bspstore) + slots)/0x40; +} + +/* + * The inverse of the above: given bspstore and the number of + * registers, calculate ar.bsp. + */ +static inline uint64_t +rse_skip_regs (uint64_t addr, long num_regs) +{ + long delta = rse_slot_num(addr) + num_regs; + + if (num_regs < 0) + delta -= 0x3e; + return addr + ((num_regs + delta/0x3f) << 3); +} + +#endif /* RSE_H */ diff --git a/headers/libs/libunwind/tdep-ia64/script.h b/headers/libs/libunwind/tdep-ia64/script.h new file mode 100644 index 0000000000..fe3360bf58 --- /dev/null +++ b/headers/libs/libunwind/tdep-ia64/script.h @@ -0,0 +1,85 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#define IA64_LOG_UNW_CACHE_SIZE 7 +#define IA64_UNW_CACHE_SIZE (1 << IA64_LOG_UNW_CACHE_SIZE) + +#define IA64_LOG_UNW_HASH_SIZE (IA64_LOG_UNW_CACHE_SIZE + 1) +#define IA64_UNW_HASH_SIZE (1 << IA64_LOG_UNW_HASH_SIZE) + +typedef unsigned char unw_hash_index_t; + +struct ia64_script_insn + { + unsigned int opc; /* see enum ia64_script_insn_opcode */ + unsigned int dst; + unw_word_t val; + }; + +/* Updating each preserved register may result in one script + instruction each. At the end of the script, psp gets popped, + accounting for one more instruction. */ +#define IA64_MAX_SCRIPT_LEN (IA64_NUM_PREGS + 1) + +struct ia64_script + { + unw_word_t ip; /* ip this script is for */ + unw_word_t pr_mask; /* mask of predicates script depends on */ + unw_word_t pr_val; /* predicate values this script is for */ + unw_proc_info_t pi; /* info about underlying procedure */ + unsigned short lru_chain; /* used for least-recently-used chain */ + unsigned short coll_chain; /* used for hash collisions */ + unsigned short hint; /* hint for next script to try (or -1) */ + unsigned short count; /* number of instructions in script */ + unsigned short abi_marker; + struct ia64_script_insn insn[IA64_MAX_SCRIPT_LEN]; + }; + +struct ia64_script_cache + { +#ifdef HAVE_ATOMIC_OPS_H + AO_TS_t busy; /* is the script-cache busy? */ +#else + pthread_mutex_t lock; +#endif + unsigned short lru_head; /* index of lead-recently used script */ + unsigned short lru_tail; /* index of most-recently used script */ + + /* hash table that maps instruction pointer to script index: */ + unsigned short hash[IA64_UNW_HASH_SIZE]; + + uint32_t generation; /* generation number */ + + /* script cache: */ + struct ia64_script buckets[IA64_UNW_CACHE_SIZE]; + }; + +#define ia64_cache_proc_info UNW_OBJ(cache_proc_info) +#define ia64_get_cached_proc_info UNW_OBJ(get_cached_proc_info) + +struct cursor; /* forward declaration */ + +extern int ia64_cache_proc_info (struct cursor *c); +extern int ia64_get_cached_proc_info (struct cursor *c); diff --git a/headers/libs/libunwind/tdep-mips/dwarf-config.h b/headers/libs/libunwind/tdep-mips/dwarf-config.h new file mode 100644 index 0000000000..8006d0b8dd --- /dev/null +++ b/headers/libs/libunwind/tdep-mips/dwarf-config.h @@ -0,0 +1,54 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef dwarf_config_h +#define dwarf_config_h + +/* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not + explicitly defined. */ +#define DWARF_NUM_PRESERVED_REGS 188 + +#define dwarf_to_unw_regnum(reg) (((reg) < 32) ? (reg) : 0) + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) + +/* Return the size of an address, for DWARF purposes. */ +#define dwarf_addr_size(addr_space) ((addr_space)->addr_size) + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/headers/libs/libunwind/tdep-mips/jmpbuf.h b/headers/libs/libunwind/tdep-mips/jmpbuf.h new file mode 100644 index 0000000000..c099f9267e --- /dev/null +++ b/headers/libs/libunwind/tdep-mips/jmpbuf.h @@ -0,0 +1,32 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +/* FIXME for MIPS! */ + +#define JB_SP 4 +#define JB_RP 5 +#define JB_MASK_SAVED 6 +#define JB_MASK 7 diff --git a/headers/libs/libunwind/tdep-mips/libunwind_i.h b/headers/libs/libunwind/tdep-mips/libunwind_i.h new file mode 100644 index 0000000000..d11894d9ba --- /dev/null +++ b/headers/libs/libunwind/tdep-mips/libunwind_i.h @@ -0,0 +1,329 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef MIPS_LIBUNWIND_I_H +#define MIPS_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#if !defined(UNW_REMOTE_ONLY) && _MIPS_SIM == _ABI64 +# include "elf64.h" +#else +# include "elf32.h" +#endif +#include "mempool.h" +#include "dwarf.h" + +typedef struct + { + /* no mips-specific fast trace */ + } +unw_tdep_frame_t; + +struct unw_addr_space + { + struct unw_accessors acc; + + int big_endian; + mips_abi_t abi; + unsigned int addr_size; + + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; +}; + +#define tdep_big_endian(as) ((as)->big_endian) + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + unw_word_t sigcontext_addr; + }; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifndef UNW_REMOTE_ONLY +# if _MIPS_SIM == _ABIN32 +typedef long long mips_reg_t; +# else +typedef long mips_reg_t; +# endif +#endif + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) + +/* FIXME: Implement these for the MIPS FPU. */ +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) (intptr_t) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) (intptr_t) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(mips_reg_t *) (intptr_t) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(mips_reg_t *) (intptr_t) DWARF_GET_LOC (loc) = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +static inline int +read_s32 (struct dwarf_cursor *c, unw_word_t addr, unw_word_t *val) +{ + int offset = addr & 4; + int ret; + unw_word_t memval; + + ret = (*c->as->acc.access_mem) (c->as, addr - offset, &memval, 0, c->as_arg); + if (ret < 0) + return ret; + + if ((offset != 0) == tdep_big_endian (c->as)) + *val = (int32_t) memval; + else + *val = (int32_t) (memval >> 32); + + return 0; +} + +static inline int +write_s32 (struct dwarf_cursor *c, unw_word_t addr, const unw_word_t *val) +{ + int offset = addr & 4; + int ret; + unw_word_t memval; + + ret = (*c->as->acc.access_mem) (c->as, addr - offset, &memval, 0, c->as_arg); + if (ret < 0) + return ret; + + if ((offset != 0) == tdep_big_endian (c->as)) + memval = (memval & ~0xffffffffLL) | (uint32_t) *val; + else + memval = (memval & 0xffffffffLL) | (uint32_t) (*val << 32); + + return (*c->as->acc.access_mem) (c->as, addr - offset, &memval, 1, c->as_arg); +} + +/* FIXME: Implement these for the MIPS FPU. */ +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, + c->as_arg); +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, + 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else if (c->as->abi == UNW_MIPS_ABI_O32) + return read_s32 (c, DWARF_GET_LOC (loc), val); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else if (c->as->abi == UNW_MIPS_ABI_O32) + return write_s32 (c, DWARF_GET_LOC (loc), &val); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c,rs) do {} while(0) +#define tdep_reuse_frame(c,rs) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t *di, unw_proc_info_t *pi, + int need_unwind_info, void *arg); +extern void *tdep_uc_addr (ucontext_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); + +#endif /* MIPS_LIBUNWIND_I_H */ diff --git a/headers/libs/libunwind/tdep-ppc32/dwarf-config.h b/headers/libs/libunwind/tdep-ppc32/dwarf-config.h new file mode 100644 index 0000000000..bf6886b066 --- /dev/null +++ b/headers/libs/libunwind/tdep-ppc32/dwarf-config.h @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + Will be replaced when libunwind is ready on ppc64 platform. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef dwarf_config_h +#define dwarf_config_h + +/* For PPC64, 48 GPRs + 33 FPRs + 33 AltiVec + 1 SPE */ +#define DWARF_NUM_PRESERVED_REGS 115 + +#define DWARF_REGNUM_MAP_LENGTH 115 + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 1 + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see X86_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/headers/libs/libunwind/tdep-ppc32/jmpbuf.h b/headers/libs/libunwind/tdep-ppc32/jmpbuf.h new file mode 100644 index 0000000000..861e94d971 --- /dev/null +++ b/headers/libs/libunwind/tdep-ppc32/jmpbuf.h @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + Will be replaced when libunwind is ready on ppc64 platform. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +#define JB_SP 6 +#define JB_RP 7 +#define JB_MASK_SAVED 8 +#define JB_MASK 9 diff --git a/headers/libs/libunwind/tdep-ppc32/libunwind_i.h b/headers/libs/libunwind/tdep-ppc32/libunwind_i.h new file mode 100644 index 0000000000..cc113c56d8 --- /dev/null +++ b/headers/libs/libunwind/tdep-ppc32/libunwind_i.h @@ -0,0 +1,312 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + Will be replaced when libunwind is ready on ppc64 platform. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef PPC32_LIBUNWIND_I_H +#define PPC32_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf32.h" +#include "mempool.h" +#include "dwarf.h" + +typedef struct + { + /* no ppc32-specific fast trace */ + } +unw_tdep_frame_t; + +struct unw_addr_space +{ + struct unw_accessors acc; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + int validate; +}; + +struct cursor +{ + struct dwarf_cursor dwarf; /* must be first */ + + /* Format of sigcontext structure and address at which it is + stored: */ + enum + { + PPC_SCF_NONE, /* no signal frame encountered */ + PPC_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ + } + sigcontext_format; + unw_word_t sigcontext_addr; +}; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_IS_FP_LOC(l) 0 +# define DWARF_IS_V_LOC(l) 0 +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_VREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +#else /* !UNW_LOCAL_ONLY */ + +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_LOC_TYPE_V (1 << 2) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_IS_V_LOC(l) (((l).type & DWARF_LOC_TYPE_V) != 0) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) +# define DWARF_VREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_V)) + +#endif /* !UNW_LOCAL_ONLY */ + +static inline int +dwarf_getvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) +{ + unw_word_t *valp = (unw_word_t *) val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_V_LOC (loc)); + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 0, c->as_arg); +} + +static inline int +dwarf_putvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + unw_word_t *valp = (unw_word_t *) & val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_V_LOC (loc)); + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 1, c->as_arg); +} + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) +{ + unw_word_t *valp = (unw_word_t *) val; + unw_word_t addr; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 0, c->as_arg); + +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + unw_word_t *valp = (unw_word_t *) & val; + unw_word_t addr; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + + return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t * val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c,rs) do {} while(0) +#define tdep_reuse_frame(c,rs) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) +#define tdep_get_func_addr UNW_OBJ(get_func_addr) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +extern int tdep_fetch_proc_info_post (struct dwarf_cursor *c, unw_word_t ip, + int need_unwind_info); + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) 1 + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t * di, + unw_proc_info_t * pi, + int need_unwind_info, void *arg); +extern void *tdep_uc_addr (ucontext_t * uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t * valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t * valp, int write); +extern int tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, + unw_word_t *entry_point); + +#endif /* PPC64_LIBUNWIND_I_H */ diff --git a/headers/libs/libunwind/tdep-ppc64/dwarf-config.h b/headers/libs/libunwind/tdep-ppc64/dwarf-config.h new file mode 100644 index 0000000000..6d8ef0a940 --- /dev/null +++ b/headers/libs/libunwind/tdep-ppc64/dwarf-config.h @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + Will be replaced when libunwind is ready on ppc64 platform. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef dwarf_config_h +#define dwarf_config_h + +/* For PPC64, 48 GPRs + 33 FPRs + 33 AltiVec + 1 SPE */ +#define DWARF_NUM_PRESERVED_REGS 115 + +#define DWARF_REGNUM_MAP_LENGTH 115 + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see X86_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/headers/libs/libunwind/tdep-ppc64/jmpbuf.h b/headers/libs/libunwind/tdep-ppc64/jmpbuf.h new file mode 100644 index 0000000000..861e94d971 --- /dev/null +++ b/headers/libs/libunwind/tdep-ppc64/jmpbuf.h @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + Will be replaced when libunwind is ready on ppc64 platform. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +#define JB_SP 6 +#define JB_RP 7 +#define JB_MASK_SAVED 8 +#define JB_MASK 9 diff --git a/headers/libs/libunwind/tdep-ppc64/libunwind_i.h b/headers/libs/libunwind/tdep-ppc64/libunwind_i.h new file mode 100644 index 0000000000..5a5bddbc43 --- /dev/null +++ b/headers/libs/libunwind/tdep-ppc64/libunwind_i.h @@ -0,0 +1,367 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + Will be replaced when libunwind is ready on ppc64 platform. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef PPC64_LIBUNWIND_I_H +#define PPC64_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf64.h" +#include "mempool.h" +#include "dwarf.h" + +typedef struct + { + /* no ppc64-specific fast trace */ + } +unw_tdep_frame_t; + +struct unw_addr_space +{ + struct unw_accessors acc; + int big_endian; + ppc64_abi_t abi; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + int validate; +}; + +struct cursor +{ + struct dwarf_cursor dwarf; /* must be first */ + + /* Format of sigcontext structure and address at which it is + stored: */ + enum + { + PPC_SCF_NONE, /* no signal frame encountered */ + PPC_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ + } + sigcontext_format; + unw_word_t sigcontext_addr; +}; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_VREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) + +static inline int +dwarf_getvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_word_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_word_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ + +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_LOC_TYPE_V (1 << 2) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_IS_V_LOC(l) (((l).type & DWARF_LOC_TYPE_V) != 0) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) +# define DWARF_VREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_V)) + +static inline int +dwarf_getvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) +{ + unw_word_t *valp = (unw_word_t *) val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_V_LOC (loc)); + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 0, c->as_arg); +} + +static inline int +dwarf_putvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + unw_word_t *valp = (unw_word_t *) & val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_V_LOC (loc)); + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 1, c->as_arg); +} + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) +{ + unw_word_t *valp = (unw_word_t *) val; + unw_word_t addr; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 0, c->as_arg); + +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + unw_word_t *valp = (unw_word_t *) & val; + unw_word_t addr; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + + return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t * val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c,rs) do {} while(0) +#define tdep_reuse_frame(c,rs) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) +#define tdep_get_func_addr UNW_OBJ(get_func_addr) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +extern int tdep_fetch_proc_info_post (struct dwarf_cursor *c, unw_word_t ip, + int need_unwind_info); + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) ((as)->big_endian) + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t * di, + unw_proc_info_t * pi, + int need_unwind_info, void *arg); +extern void *tdep_uc_addr (ucontext_t * uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t * valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t * valp, int write); +extern int tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, + unw_word_t *entry_point); + +#endif /* PPC64_LIBUNWIND_I_H */ diff --git a/headers/libs/libunwind/tdep-sh/dwarf-config.h b/headers/libs/libunwind/tdep-sh/dwarf-config.h new file mode 100644 index 0000000000..2f76f5be7f --- /dev/null +++ b/headers/libs/libunwind/tdep-sh/dwarf-config.h @@ -0,0 +1,49 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef dwarf_config_h +#define dwarf_config_h + +#define DWARF_NUM_PRESERVED_REGS 18 + +#define dwarf_to_unw_regnum(reg) (((reg) <= UNW_SH_PR) ? (reg) : 0) + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/headers/libs/libunwind/tdep-sh/jmpbuf.h b/headers/libs/libunwind/tdep-sh/jmpbuf.h new file mode 100644 index 0000000000..8b44b5b219 --- /dev/null +++ b/headers/libs/libunwind/tdep-sh/jmpbuf.h @@ -0,0 +1,48 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +/* SH4 glibc jump buffer contents: + * 0. r8 + * 1. r9 + * 2. r10 + * 3. r11 + * 4. r12 + * 5. r13 + * 6. r14 + * 7. r15 + * 8. pr/pc + * 9. gbr + * 10. fpscr + * 11. fr12 + * 12. fr13 + * 13. fr14 + * 14. fr15 + */ + +#define JB_SP 7 +#define JB_RP 8 +#define JB_MASK_SAVED 15 +#define JB_MASK 16 diff --git a/headers/libs/libunwind/tdep-sh/libunwind_i.h b/headers/libs/libunwind/tdep-sh/libunwind_i.h new file mode 100644 index 0000000000..7bbb29b3dc --- /dev/null +++ b/headers/libs/libunwind/tdep-sh/libunwind_i.h @@ -0,0 +1,278 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef SH_LIBUNWIND_I_H +#define SH_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf32.h" +#include "mempool.h" +#include "dwarf.h" + +typedef struct + { + /* no sh-specific fast trace */ + } +unw_tdep_frame_t; + +struct unw_addr_space + { + struct unw_accessors acc; + int big_endian; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + }; + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + enum + { + SH_SCF_NONE, /* no signal frame */ + SH_SCF_LINUX_SIGFRAME, /* non-RT signal frame */ + SH_SCF_LINUX_RT_SIGFRAME, /* RT signal frame */ + } + sigcontext_format; + unw_word_t sigcontext_addr; + unw_word_t sigcontext_sp; + unw_word_t sigcontext_pc; + }; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_word_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_word_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, + c->as_arg); +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, + 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c,rs) do {} while(0) +#define tdep_reuse_frame(c,rs) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) ((as)->big_endian) + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t *di, unw_proc_info_t *pi, + int need_unwind_info, void *arg); +extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); + +#endif /* SH_LIBUNWIND_I_H */ diff --git a/headers/libs/libunwind/tdep-tilegx/dwarf-config.h b/headers/libs/libunwind/tdep-tilegx/dwarf-config.h new file mode 100644 index 0000000000..93bc6aaecc --- /dev/null +++ b/headers/libs/libunwind/tdep-tilegx/dwarf-config.h @@ -0,0 +1,50 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef dwarf_config_h +#define dwarf_config_h + +/* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not + explicitly defined. */ +#define DWARF_NUM_PRESERVED_REGS 188 + +#define DWARF_REGNUM_MAP_LENGTH (56 + 2) + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc +{ + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ +#endif +} dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/headers/libs/libunwind/tdep-tilegx/jmpbuf.h b/headers/libs/libunwind/tdep-tilegx/jmpbuf.h new file mode 100644 index 0000000000..3afe9e46cc --- /dev/null +++ b/headers/libs/libunwind/tdep-tilegx/jmpbuf.h @@ -0,0 +1,33 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +/* FIXME for Tilegx! */ + +#define JB_SP 4 +#define JB_RP 5 +#define JB_MASK_SAVED 6 +#define JB_MASK 7 diff --git a/headers/libs/libunwind/tdep-tilegx/libunwind_i.h b/headers/libs/libunwind/tdep-tilegx/libunwind_i.h new file mode 100644 index 0000000000..9a4ec6a5ed --- /dev/null +++ b/headers/libs/libunwind/tdep-tilegx/libunwind_i.h @@ -0,0 +1,265 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef TILEGX_LIBUNWIND_I_H +#define TILEGX_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +# include "elf64.h" +#include "mempool.h" +#include "dwarf.h" + +#ifdef HAVE___THREAD +# undef HAVE___THREAD +#endif + +typedef struct +{ + /* no Tilegx-specific fast trace */ +} unw_tdep_frame_t; + +struct unw_addr_space +{ + struct unw_accessors acc; + + int big_endian; + tilegx_abi_t abi; + unsigned int addr_size; + + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; +}; + +#define tdep_big_endian(as) ((as)->big_endian) + +struct cursor +{ + struct dwarf_cursor dwarf; /* must be first */ + unw_word_t sigcontext_addr; + unw_word_t sigcontext_sp; + unw_word_t sigcontext_pc; +}; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifndef UNW_REMOTE_ONLY +typedef long tilegx_reg_t; +#endif + +#ifdef UNW_LOCAL_ONLY +#define DWARF_NULL_LOC DWARF_LOC (0, 0) +#define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +#define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +#define DWARF_IS_REG_LOC(l) 0 +#define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +#define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +#define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) + +/* Tilegx has no FP. */ +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + Debug (1, "Tielgx has no fp!\n"); + abort(); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + Debug (1, "Tielgx has no fp!\n"); + abort(); + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + + *val = *(tilegx_reg_t *) (intptr_t) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + + *(tilegx_reg_t *) (intptr_t) DWARF_GET_LOC (loc) = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ +#define DWARF_LOC_TYPE_FP (1 << 0) +#define DWARF_LOC_TYPE_REG (1 << 1) +#define DWARF_NULL_LOC DWARF_LOC (0, 0) +#define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +#define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +#define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +#define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +#define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +#define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +#define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +/* TILEGX has no fp. */ +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + Debug (1, "Tielgx has no fp!\n"); + abort(); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + Debug (1, "Tielgx has no fp!\n"); + abort(); + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_needs_initialization UNW_OBJ(needs_initialization) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c,rs) do {} while(0) +#define tdep_reuse_frame(c,rs) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) + +#ifdef UNW_LOCAL_ONLY +#define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +#define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +#define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +#define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_search_unwind_table (unw_addr_space_t as, + unw_word_t ip, + unw_dyn_info_t *di, + unw_proc_info_t *pi, + int need_unwind_info, + void *arg); +extern void *tdep_uc_addr (ucontext_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, + pid_t pid, unw_word_t ip, + unsigned long *segbase, + unsigned long *mapoff, + char *path, size_t pathlen); +extern int tdep_access_reg (struct cursor *c, + unw_regnum_t reg, + unw_word_t *valp, + int write); +extern int tdep_access_fpreg (struct cursor *c, + unw_regnum_t reg, + unw_fpreg_t *valp, + int write); + +#endif /* TILEGX_LIBUNWIND_I_H */ diff --git a/headers/libs/libunwind/tdep-x86/dwarf-config.h b/headers/libs/libunwind/tdep-x86/dwarf-config.h new file mode 100644 index 0000000000..f76f9c1c4e --- /dev/null +++ b/headers/libs/libunwind/tdep-x86/dwarf-config.h @@ -0,0 +1,52 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef dwarf_config_h +#define dwarf_config_h + +/* This matches the value used by GCC (see + gcc/config/i386.h:DWARF_FRAME_REGISTERS), which leaves plenty of + room for expansion. */ +#define DWARF_NUM_PRESERVED_REGS 17 + +#define DWARF_REGNUM_MAP_LENGTH 19 + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 0 + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see X86_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/headers/libs/libunwind/tdep-x86/jmpbuf.h b/headers/libs/libunwind/tdep-x86/jmpbuf.h new file mode 100644 index 0000000000..521dfa6992 --- /dev/null +++ b/headers/libs/libunwind/tdep-x86/jmpbuf.h @@ -0,0 +1,42 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +#if defined __linux__ + +#define JB_SP 4 +#define JB_RP 5 +#define JB_MASK_SAVED 6 +#define JB_MASK 7 + +#elif defined __FreeBSD__ + +#define JB_SP 2 +#define JB_RP 0 +#define JB_MASK_SAVED 11 +#define JB_MASK 7 + +#endif diff --git a/headers/libs/libunwind/tdep-x86/libunwind_i.h b/headers/libs/libunwind/tdep-x86/libunwind_i.h new file mode 100644 index 0000000000..b1c8b9832f --- /dev/null +++ b/headers/libs/libunwind/tdep-x86/libunwind_i.h @@ -0,0 +1,291 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef X86_LIBUNWIND_I_H +#define X86_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf32.h" +#include "mempool.h" +#include "dwarf.h" + +typedef struct + { + /* no x86-specific fast trace */ + } +unw_tdep_frame_t; + +struct unw_addr_space + { + struct unw_accessors acc; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + }; + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + + /* Format of sigcontext structure and address at which it is + stored: */ + enum + { + X86_SCF_NONE, /* no signal frame encountered */ + X86_SCF_LINUX_SIGFRAME, /* Linux x86 sigcontext */ + X86_SCF_LINUX_RT_SIGFRAME, /* POSIX ucontext_t */ + X86_SCF_FREEBSD_SIGFRAME, /* FreeBSD x86 sigcontext */ + X86_SCF_FREEBSD_SIGFRAME4, /* FreeBSD 4.x x86 sigcontext */ + X86_SCF_FREEBSD_OSIGFRAME, /* FreeBSD pre-4.x x86 sigcontext */ + X86_SCF_FREEBSD_SYSCALL, /* FreeBSD x86 syscall */ + } + sigcontext_format; + unw_word_t sigcontext_addr; + int validate; + ucontext_t *uc; + }; + +static inline ucontext_t * +dwarf_get_uc(const struct dwarf_cursor *cursor) +{ + const struct cursor *c = (struct cursor *) cursor->as_arg; + return c->uc; +} + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#else /* !UNW_LOCAL_ONLY */ +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, + c->as_arg); +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, + 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c,rs) do {} while(0) +#define tdep_reuse_frame(c,rs) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) 0 + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t *di, unw_proc_info_t *pi, + int need_unwind_info, void *arg); +extern void *tdep_uc_addr (ucontext_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); + +#endif /* X86_LIBUNWIND_I_H */ diff --git a/headers/libs/libunwind/tdep-x86_64/dwarf-config.h b/headers/libs/libunwind/tdep-x86_64/dwarf-config.h new file mode 100644 index 0000000000..ff77808e06 --- /dev/null +++ b/headers/libs/libunwind/tdep-x86_64/dwarf-config.h @@ -0,0 +1,57 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* copy of include/tdep-x86/dwarf-config.h, modified slightly for x86-64 + some consolidation is possible here */ + +#ifndef dwarf_config_h +#define dwarf_config_h + +/* XXX need to verify if this value is correct */ +#ifdef CONFIG_MSABI_SUPPORT +#define DWARF_NUM_PRESERVED_REGS 33 +#else +#define DWARF_NUM_PRESERVED_REGS 17 +#endif + +#define DWARF_REGNUM_MAP_LENGTH DWARF_NUM_PRESERVED_REGS + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 0 + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; + unw_word_t type; /* see X86_LOC_TYPE_* macros. */ + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/headers/libs/libunwind/tdep-x86_64/jmpbuf.h b/headers/libs/libunwind/tdep-x86_64/jmpbuf.h new file mode 100644 index 0000000000..d57196676d --- /dev/null +++ b/headers/libs/libunwind/tdep-x86_64/jmpbuf.h @@ -0,0 +1,43 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#if defined __linux__ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +#define JB_SP 6 +#define JB_RP 7 +#define JB_MASK_SAVED 8 +#define JB_MASK 9 + +#elif defined __FreeBSD__ + +#define JB_SP 2 +#define JB_RP 0 +/* Pretend the ip cannot be 0 and mask is always saved */ +#define JB_MASK_SAVED 0 +#define JB_MASK 9 + +#endif diff --git a/headers/libs/libunwind/tdep-x86_64/libunwind_i.h b/headers/libs/libunwind/tdep-x86_64/libunwind_i.h new file mode 100644 index 0000000000..2f4f01b053 --- /dev/null +++ b/headers/libs/libunwind/tdep-x86_64/libunwind_i.h @@ -0,0 +1,262 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef X86_64_LIBUNWIND_I_H +#define X86_64_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf64.h" +#include "mempool.h" +#include "dwarf.h" + +typedef enum + { + UNW_X86_64_FRAME_STANDARD = -2, /* regular rbp, rsp +/- offset */ + UNW_X86_64_FRAME_SIGRETURN = -1, /* special sigreturn frame */ + UNW_X86_64_FRAME_OTHER = 0, /* not cacheable (special or unrecognised) */ + UNW_X86_64_FRAME_GUESSED = 1 /* guessed it was regular, but not known */ + } +unw_tdep_frame_type_t; + +typedef struct + { + uint64_t virtual_address; + int64_t frame_type : 2; /* unw_tdep_frame_type_t classification */ + int64_t last_frame : 1; /* non-zero if last frame in chain */ + int64_t cfa_reg_rsp : 1; /* cfa dwarf base register is rsp vs. rbp */ + int64_t cfa_reg_offset : 30; /* cfa is at this offset from base register value */ + int64_t rbp_cfa_offset : 15; /* rbp saved at this offset from cfa (-1 = not saved) */ + int64_t rsp_cfa_offset : 15; /* rsp saved at this offset from cfa (-1 = not saved) */ + } +unw_tdep_frame_t; + +struct unw_addr_space + { + struct unw_accessors acc; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + }; + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + + unw_tdep_frame_t frame_info; /* quick tracing assist info */ + + /* Format of sigcontext structure and address at which it is + stored: */ + enum + { + X86_64_SCF_NONE, /* no signal frame encountered */ + X86_64_SCF_LINUX_RT_SIGFRAME, /* Linux ucontext_t */ + X86_64_SCF_FREEBSD_SIGFRAME, /* FreeBSD signal frame */ + X86_64_SCF_FREEBSD_SYSCALL, /* FreeBSD syscall */ + } + sigcontext_format; + unw_word_t sigcontext_addr; + int validate; + ucontext_t *uc; + }; + +static inline ucontext_t * +dwarf_get_uc(const struct dwarf_cursor *cursor) +{ + const struct cursor *c = (struct cursor *) cursor->as_arg; + return c->uc; +} + +#define DWARF_GET_LOC(l) ((l).val) +# define DWARF_LOC_TYPE_MEM (0 << 0) +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_LOC_TYPE_VAL (1 << 2) + +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_IS_MEM_LOC(l) ((l).type == DWARF_LOC_TYPE_MEM) +# define DWARF_IS_VAL_LOC(l) (((l).type & DWARF_LOC_TYPE_VAL) != 0) + +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_VAL_LOC(c,v) DWARF_LOC ((v), DWARF_LOC_TYPE_VAL) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), DWARF_LOC_TYPE_MEM) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + x86_64_r_uc_addr(dwarf_get_uc(c), (r)), 0)) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + x86_64_r_uc_addr(dwarf_get_uc(c), (r)), 0)) + +#else /* !UNW_LOCAL_ONLY */ + +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +#endif /* !UNW_LOCAL_ONLY */ + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + abort (); +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + abort (); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + if (DWARF_IS_MEM_LOC (loc)) + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + assert(DWARF_IS_VAL_LOC (loc)); + *val = DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + assert(!DWARF_IS_VAL_LOC (loc)); + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#define tdep_getcontext_trace UNW_ARCH_OBJ(getcontext_trace) +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init_mem_validate UNW_OBJ(init_mem_validate) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#if defined(__linux__) || defined(__sun) +# define tdep_fetch_frame UNW_OBJ(fetch_frame) +# define tdep_cache_frame UNW_OBJ(cache_frame) +# define tdep_reuse_frame UNW_OBJ(reuse_frame) +#else +# define tdep_fetch_frame(c,ip,n) do {} while(0) +# define tdep_cache_frame(c,rs) do {} while(0) +# define tdep_reuse_frame(c,rs) do {} while(0) +#endif +#define tdep_stash_frame UNW_OBJ(stash_frame) +#define tdep_trace UNW_OBJ(tdep_trace) +#define x86_64_r_uc_addr UNW_OBJ(r_uc_addr) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) 0 + +extern int tdep_init_done; + +extern void tdep_init (void); +extern void tdep_init_mem_validate (void); +extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t *di, unw_proc_info_t *pi, + int need_unwind_info, void *arg); +extern void *x86_64_r_uc_addr (ucontext_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); +#if __linux__ +extern void tdep_fetch_frame (struct dwarf_cursor *c, unw_word_t ip, + int need_unwind_info); +extern void tdep_cache_frame (struct dwarf_cursor *c, + struct dwarf_reg_state *rs); +extern void tdep_reuse_frame (struct dwarf_cursor *c, + struct dwarf_reg_state *rs); +extern void tdep_stash_frame (struct dwarf_cursor *c, + struct dwarf_reg_state *rs); +#endif + +extern int tdep_getcontext_trace (unw_tdep_context_t *); +extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n); + +#endif /* X86_64_LIBUNWIND_I_H */ diff --git a/headers/libs/libunwind/tdep/dwarf-config.h b/headers/libs/libunwind/tdep/dwarf-config.h new file mode 100644 index 0000000000..c759a46c63 --- /dev/null +++ b/headers/libs/libunwind/tdep/dwarf-config.h @@ -0,0 +1,28 @@ +/* Provide a real file - not a symlink - as it would cause multiarch conflicts + when multiple different arch releases are installed simultaneously. */ + +#if defined __aarch64__ +# include "tdep-aarch64/dwarf-config.h" +#elif defined __arm__ +# include "tdep-arm/dwarf-config.h" +#elif defined __hppa__ +# include "tdep-hppa/dwarf-config.h" +#elif defined __ia64__ +# include "tdep-ia64/dwarf-config.h" +#elif defined __mips__ +# include "tdep-mips/dwarf-config.h" +#elif defined __powerpc__ && !defined __powerpc64__ +# include "tdep-ppc32/dwarf-config.h" +#elif defined __powerpc64__ +# include "tdep-ppc64/dwarf-config.h" +#elif defined __sh__ +# include "tdep-sh/dwarf-config.h" +#elif defined __i386__ +# include "tdep-x86/dwarf-config.h" +#elif defined __x86_64__ || defined __amd64__ +# include "tdep-x86_64/dwarf-config.h" +#elif defined __tilegx__ +# include "tdep-tilegx/dwarf-config.h" +#else +# error "Unsupported arch" +#endif diff --git a/headers/libs/libunwind/tdep/jmpbuf.h b/headers/libs/libunwind/tdep/jmpbuf.h new file mode 100644 index 0000000000..4eae183e5b --- /dev/null +++ b/headers/libs/libunwind/tdep/jmpbuf.h @@ -0,0 +1,30 @@ +/* Provide a real file - not a symlink - as it would cause multiarch conflicts + when multiple different arch releases are installed simultaneously. */ + +#ifndef UNW_REMOTE_ONLY + +#if defined __aarch64__ +# include "tdep-aarch64/jmpbuf.h" +#if defined __arm__ +# include "tdep-arm/jmpbuf.h" +#elif defined __hppa__ +# include "tdep-hppa/jmpbuf.h" +#elif defined __ia64__ +# include "tdep-ia64/jmpbuf.h" +#elif defined __mips__ +# include "tdep-mips/jmpbuf.h" +#elif defined __powerpc__ && !defined __powerpc64__ +# include "tdep-ppc32/jmpbuf.h" +#elif defined __powerpc64__ +# include "tdep-ppc64/jmpbuf.h" +#elif defined __i386__ +# include "tdep-x86/jmpbuf.h" +#elif defined __x86_64__ +# include "tdep-x86_64/jmpbuf.h" +#elif defined __tilegx__ +# include "tdep-tilegx/jmpbuf.h" +#else +# error "Unsupported arch" +#endif + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/headers/libs/libunwind/tdep/libunwind_i.h b/headers/libs/libunwind/tdep/libunwind_i.h new file mode 100644 index 0000000000..c12fd203a5 --- /dev/null +++ b/headers/libs/libunwind/tdep/libunwind_i.h @@ -0,0 +1,38 @@ +/* Provide a real file - not a symlink - as it would cause multiarch conflicts + when multiple different arch releases are installed simultaneously. */ + +#ifndef UNW_REMOTE_ONLY + +#if defined __aarch64__ +# include "tdep-aarch64/libunwind_i.h" +#elif defined __arm__ +# include "tdep-arm/libunwind_i.h" +#elif defined __hppa__ +# include "tdep-hppa/libunwind_i.h" +#elif defined __ia64__ +# include "tdep-ia64/libunwind_i.h" +#elif defined __mips__ +# include "tdep-mips/libunwind_i.h" +#elif defined __powerpc__ && !defined __powerpc64__ +# include "tdep-ppc32/libunwind_i.h" +#elif defined __powerpc64__ +# include "tdep-ppc64/libunwind_i.h" +#elif defined __sh__ +# include "tdep-sh/libunwind_i.h" +#elif defined __i386__ +# include "tdep-x86/libunwind_i.h" +#elif defined __x86_64__ +# include "tdep-x86_64/libunwind_i.h" +#elif defined __tilegx__ +# include "tdep-tilegx/libunwind_i.h" +#else +# error "Unsupported arch" +#endif + + +#else /* UNW_REMOTE_ONLY */ + +//# include "tdep-@arch@/libunwind_i.h" +# error UNW_REMOTE_ONLY is not supported + +#endif /* UNW_REMOTE_ONLY */ diff --git a/headers/libs/libunwind/unwind.h b/headers/libs/libunwind/unwind.h new file mode 100644 index 0000000000..7cf128deca --- /dev/null +++ b/headers/libs/libunwind/unwind.h @@ -0,0 +1,154 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _UNWIND_H +#define _UNWIND_H + +/* For uint64_t */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Minimal interface as per C++ ABI draft standard: + + http://www.codesourcery.com/cxx-abi/abi-eh.html */ + +typedef enum + { + _URC_NO_REASON = 0, + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + _URC_FATAL_PHASE2_ERROR = 2, + _URC_FATAL_PHASE1_ERROR = 3, + _URC_NORMAL_STOP = 4, + _URC_END_OF_STACK = 5, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8 + } +_Unwind_Reason_Code; + +typedef int _Unwind_Action; + +#define _UA_SEARCH_PHASE 1 +#define _UA_CLEANUP_PHASE 2 +#define _UA_HANDLER_FRAME 4 +#define _UA_FORCE_UNWIND 8 + +struct _Unwind_Context; /* opaque data-structure */ +struct _Unwind_Exception; /* forward-declaration */ + +typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, + struct _Unwind_Exception *); + +typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) (int, _Unwind_Action, + uint64_t, + struct _Unwind_Exception *, + struct _Unwind_Context *, + void *); + +/* The C++ ABI requires exception_class, private_1, and private_2 to + be of type uint64 and the entire structure to be + double-word-aligned. Please note that exception_class stays 64-bit + even on 32-bit machines for gcc compatibility. */ +struct _Unwind_Exception + { + uint64_t exception_class; + _Unwind_Exception_Cleanup_Fn exception_cleanup; + unsigned long private_1; + unsigned long private_2; + } __attribute__((__aligned__)); + +extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *); +extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *, + _Unwind_Stop_Fn, void *); +extern void _Unwind_Resume (struct _Unwind_Exception *); +extern void _Unwind_DeleteException (struct _Unwind_Exception *); +extern unsigned long _Unwind_GetGR (struct _Unwind_Context *, int); +extern void _Unwind_SetGR (struct _Unwind_Context *, int, unsigned long); +extern unsigned long _Unwind_GetIP (struct _Unwind_Context *); +extern unsigned long _Unwind_GetIPInfo (struct _Unwind_Context *, int *); +extern void _Unwind_SetIP (struct _Unwind_Context *, unsigned long); +extern unsigned long _Unwind_GetLanguageSpecificData (struct _Unwind_Context*); +extern unsigned long _Unwind_GetRegionStart (struct _Unwind_Context *); + +#ifdef _GNU_SOURCE + +/* Callback for _Unwind_Backtrace(). The backtrace stops immediately + if the callback returns any value other than _URC_NO_REASON. */ +typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (struct _Unwind_Context *, + void *); + +/* See http://gcc.gnu.org/ml/gcc-patches/2001-09/msg00082.html for why + _UA_END_OF_STACK exists. */ +# define _UA_END_OF_STACK 16 + +/* If the unwind was initiated due to a forced unwind, resume that + operation, else re-raise the exception. This is used by + __cxa_rethrow(). */ +extern _Unwind_Reason_Code + _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *); + +/* See http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00154.html for why + _Unwind_GetBSP() exists. */ +extern unsigned long _Unwind_GetBSP (struct _Unwind_Context *); + +/* Return the "canonical frame address" for the given context. + This is used by NPTL... */ +extern unsigned long _Unwind_GetCFA (struct _Unwind_Context *); + +/* Return the base-address for data references. */ +extern unsigned long _Unwind_GetDataRelBase (struct _Unwind_Context *); + +/* Return the base-address for text references. */ +extern unsigned long _Unwind_GetTextRelBase (struct _Unwind_Context *); + +/* Call _Unwind_Trace_Fn once for each stack-frame, without doing any + cleanup. The first frame for which the callback is invoked is the + one for the caller of _Unwind_Backtrace(). _Unwind_Backtrace() + returns _URC_END_OF_STACK when the backtrace stopped due to + reaching the end of the call-chain or _URC_FATAL_PHASE1_ERROR if it + stops for any other reason. */ +extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *); + +/* Find the start-address of the procedure containing the specified IP + or NULL if it cannot be found (e.g., because the function has no + unwind info). Note: there is not necessarily a one-to-one + correspondence between source-level functions and procedures: some + functions don't have unwind-info and others are split into multiple + procedures. */ +extern void *_Unwind_FindEnclosingFunction (void *); + +/* See also Linux Standard Base Spec: + http://www.linuxbase.org/spec/refspecs/LSB_1.3.0/gLSB/gLSB/libgcc-s.html */ + +#endif /* _GNU_SOURCE */ + +#ifdef __cplusplus +}; +#endif + +#endif /* _UNWIND_H */ diff --git a/headers/libs/libunwind/x86/jmpbuf.h b/headers/libs/libunwind/x86/jmpbuf.h new file mode 100644 index 0000000000..94d5984f08 --- /dev/null +++ b/headers/libs/libunwind/x86/jmpbuf.h @@ -0,0 +1,31 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +#define JB_SP 4 +#define JB_RP 5 +#define JB_MASK_SAVED 6 +#define JB_MASK 7 diff --git a/src/libs/libunwind/.gitignore b/src/libs/libunwind/.gitignore new file mode 100644 index 0000000000..f5fe6dca51 --- /dev/null +++ b/src/libs/libunwind/.gitignore @@ -0,0 +1,69 @@ +*.la +*.a +*.o +*.lo +*~ + +.libs/ +.deps/ + +.dirstamp +Makefile +Makefile.in + +INSTALL +aclocal.m4 +autom4te.cache/ +config.log +config.status +config/ +configure +libtool + +doc/common.tex + +src/[GL]cursor_i.h +src/mk_[GL]cursor_i.s + +include/config.h +include/config.h.in +include/libunwind-common.h +include/stamp-h1 + +tests/[GL]test-bt +tests/[GL]test-concurrent +tests/[GL]test-dyn1 +tests/[GL]test-exc +tests/[GL]test-init +tests/[GL]test-resume-sig +tests/[GL]test-resume-sig-rt +tests/[GL]perf-simple +tests/Ltest-nomalloc +tests/Ltest-nocalloc +tests/Lperf-simple +tests/check-namespace.sh +tests/crasher +tests/forker +tests/mapper +tests/rs-race +tests/test-async-sig +tests/test-coredump-unwind +tests/test-flush-cache +tests/test-init-remote +tests/test-mem +tests/test-ptrace +tests/test-setjmp +tests/test-strerror +tests/test-proc-info +tests/test-ptrace-misc +tests/test-varargs +tests/test-static-link +tests/[GL]test-trace +tests/[GL]perf-trace +tests/Ltest-cxx-exceptions +tests/[GL]ia64-test-nat +tests/[GL]ia64-test-rbs +tests/[GL]ia64-test-readonly +tests/[GL]ia64-test-stack +tests/ia64-test-dyn1 +tests/ia64-test-sig diff --git a/src/libs/libunwind/AUTHORS b/src/libs/libunwind/AUTHORS new file mode 100644 index 0000000000..719eee5c85 --- /dev/null +++ b/src/libs/libunwind/AUTHORS @@ -0,0 +1 @@ +David Mosberger diff --git a/src/libs/libunwind/COPYING b/src/libs/libunwind/COPYING new file mode 100644 index 0000000000..41e7d8a6fd --- /dev/null +++ b/src/libs/libunwind/COPYING @@ -0,0 +1,20 @@ +Copyright (c) 2002 Hewlett-Packard Co. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/libs/libunwind/ChangeLog b/src/libs/libunwind/ChangeLog new file mode 100644 index 0000000000..dfa24b957c --- /dev/null +++ b/src/libs/libunwind/ChangeLog @@ -0,0 +1,55 @@ +*********************************************************** + + Discontinued. See git log instead at + + http://www.kernel.org/git/gitweb.cgi?p=libs/libunwind/libunwind.git;a=log + +*********************************************************** + +2002-11-08 David Mosberger-Tang + + * src/ia64/unwind_i.h (ia64_getfp): Change from macro to inline + function. Check "loc" argument for being NULL before dereferencing it. + (ia64_putfp): Ditto. + (ia64_get): Ditto. + (ia64_put): Ditto. + +2002-01-18 David Mosberger-Tang + + * src/ia64/parser.c (__ia64_unw_create_state_record): Set + IA64_FLAG_HAS_HANDLER if the unwind info descriptors indicate that + there a handler. + + * src/ia64/regs.c (__ia64_access_reg): Return zero for UNW_REG_HANDLER + in frames that don't have a personality routine. + + * src/ia64/unwind_i.h (IA64_FLAG_HAS_HANDLER): New flag. + + * src/ia64/regs.c (__ia64_access_reg): When reading UNW_REG_HANDLER, + account for the fact that the personality address is gp-relative. + + * src/ia64/parser.c (__ia64_unw_create_state_record): Fix + initialization of segbase and len. + +2002-01-17 David Mosberger-Tang + + * include/unwind-ia64.h: Include via "unwind.h" to ensure + the file is picked up from same directory. + +2002-01-16 David Mosberger-Tang + + * include/unwind.h: Define UNW_ESTOPUNWIND. This error code may + be returned by acquire_unwind_info() to force termination of + unwinding. An application may want to do this when encountering a + call frame for dynamically generated code, for example. + + * unwind.h: Pass opaque argument pointer to acquire_unwind_info() + and release_unwind_info() like we do for access_mem() etc. + +2002-01-14 David Mosberger-Tang + + * Version 0.0 released. + +2002-01-11 David Mosberger-Tang + + * ChangeLog created. diff --git a/src/libs/libunwind/LICENSE b/src/libs/libunwind/LICENSE new file mode 100644 index 0000000000..c9b44cb8aa --- /dev/null +++ b/src/libs/libunwind/LICENSE @@ -0,0 +1,18 @@ +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/libs/libunwind/Makefile.am b/src/libs/libunwind/Makefile.am new file mode 100644 index 0000000000..5d87475568 --- /dev/null +++ b/src/libs/libunwind/Makefile.am @@ -0,0 +1,715 @@ +SOVERSION=8:1:0 # See comments at end of file. +SETJMP_SO_VERSION=0:0:0 +COREDUMP_SO_VERSION=0:0:0 +# +# Don't link with start-files since we don't use any constructors/destructors: +# +COMMON_SO_LDFLAGS = $(LDFLAGS_NOSTARTFILES) + +lib_LIBRARIES = +lib_LTLIBRARIES = +if !REMOTE_ONLY +lib_LTLIBRARIES += libunwind.la +if BUILD_PTRACE +lib_LTLIBRARIES += libunwind-ptrace.la +endif +if BUILD_COREDUMP +lib_LTLIBRARIES += libunwind-coredump.la +endif +endif + +noinst_HEADERS = +noinst_LTLIBRARIES = + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libunwind-generic.pc + +if !REMOTE_ONLY +pkgconfig_DATA += unwind/libunwind.pc +endif + +if BUILD_PTRACE +pkgconfig_DATA += ptrace/libunwind-ptrace.pc +endif + +if BUILD_SETJMP +pkgconfig_DATA += setjmp/libunwind-setjmp.pc +endif + +if BUILD_COREDUMP +pkgconfig_DATA += coredump/libunwind-coredump.pc +endif + +### libunwind-ptrace: +libunwind_ptrace_la_SOURCES = \ + ptrace/_UPT_elf.c \ + ptrace/_UPT_accessors.c ptrace/_UPT_access_fpreg.c \ + ptrace/_UPT_access_mem.c ptrace/_UPT_access_reg.c \ + ptrace/_UPT_create.c ptrace/_UPT_destroy.c \ + ptrace/_UPT_find_proc_info.c ptrace/_UPT_get_dyn_info_list_addr.c \ + ptrace/_UPT_put_unwind_info.c ptrace/_UPT_get_proc_name.c \ + ptrace/_UPT_reg_offset.c ptrace/_UPT_resume.c +noinst_HEADERS += ptrace/_UPT_internal.h + +### libunwind-coredump: +libunwind_coredump_la_SOURCES = \ + coredump/_UCD_accessors.c \ + coredump/_UCD_create.c \ + coredump/_UCD_destroy.c \ + coredump/_UCD_access_mem.c \ + coredump/_UCD_elf_map_image.c \ + coredump/_UCD_find_proc_info.c \ + coredump/_UCD_get_proc_name.c \ + \ + coredump/_UPT_elf.c \ + coredump/_UPT_access_fpreg.c \ + coredump/_UPT_get_dyn_info_list_addr.c \ + coredump/_UPT_put_unwind_info.c \ + coredump/_UPT_resume.c +libunwind_coredump_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \ + -version-info $(COREDUMP_SO_VERSION) +libunwind_coredump_la_LIBADD = $(LIBLZMA) +noinst_HEADERS += coredump/_UCD_internal.h coredump/_UCD_lib.h + +### libunwind-setjmp: +libunwind_setjmp_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \ + -version-info $(SETJMP_SO_VERSION) + +if USE_ELF32 +LIBUNWIND_ELF = libunwind-elf32.la +endif +if USE_ELF64 +LIBUNWIND_ELF = libunwind-elf64.la +endif +if USE_ELFXX +LIBUNWIND_ELF = libunwind-elfxx.la +endif + +libunwind_setjmp_la_LIBADD = $(LIBUNWIND_ELF) \ + libunwind-$(arch).la \ + libunwind.la -lc +libunwind_setjmp_la_SOURCES = setjmp/longjmp.c \ + setjmp/siglongjmp.c +noinst_HEADERS += setjmp/setjmp_i.h + +### libunwind: +libunwind_la_LIBADD = + +# List of arch-independent files needed by both local-only and generic +# libraries: +libunwind_la_SOURCES_common = \ + $(libunwind_la_SOURCES_os) \ + mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c + +# List of arch-independent files needed by generic library (libunwind-$ARCH): +libunwind_la_SOURCES_generic = \ + mi/Gdyn-extract.c mi/Gdyn-remote.c mi/Gfind_dynamic_proc_info.c \ + mi/Gget_accessors.c \ + mi/Gget_proc_info_by_ip.c mi/Gget_proc_name.c \ + mi/Gput_dynamic_unwind_info.c mi/Gdestroy_addr_space.c \ + mi/Gget_reg.c mi/Gset_reg.c \ + mi/Gget_fpreg.c mi/Gset_fpreg.c \ + mi/Gset_caching_policy.c + +if SUPPORT_CXX_EXCEPTIONS +libunwind_la_SOURCES_local_unwind = \ + unwind/Backtrace.c unwind/DeleteException.c \ + unwind/FindEnclosingFunction.c unwind/ForcedUnwind.c \ + unwind/GetBSP.c unwind/GetCFA.c unwind/GetDataRelBase.c \ + unwind/GetGR.c unwind/GetIP.c unwind/GetLanguageSpecificData.c \ + unwind/GetRegionStart.c unwind/GetTextRelBase.c \ + unwind/RaiseException.c unwind/Resume.c \ + unwind/Resume_or_Rethrow.c unwind/SetGR.c unwind/SetIP.c \ + unwind/GetIPInfo.c + +# _ReadULEB()/_ReadSLEB() are needed for Intel C++ 8.0 compatibility +libunwind_la_SOURCES_os_linux_local = mi/_ReadULEB.c mi/_ReadSLEB.c +endif + +# List of arch-independent files needed by local-only library (libunwind): +libunwind_la_SOURCES_local_nounwind = \ + $(libunwind_la_SOURCES_os_local) \ + mi/backtrace.c \ + mi/dyn-cancel.c mi/dyn-info-list.c mi/dyn-register.c \ + mi/Ldyn-extract.c mi/Lfind_dynamic_proc_info.c \ + mi/Lget_accessors.c \ + mi/Lget_proc_info_by_ip.c mi/Lget_proc_name.c \ + mi/Lput_dynamic_unwind_info.c mi/Ldestroy_addr_space.c \ + mi/Lget_reg.c mi/Lset_reg.c \ + mi/Lget_fpreg.c mi/Lset_fpreg.c \ + mi/Lset_caching_policy.c + +libunwind_la_SOURCES_local = \ + $(libunwind_la_SOURCES_local_nounwind) \ + $(libunwind_la_SOURCES_local_unwind) + +noinst_HEADERS += os-linux.h +libunwind_la_SOURCES_os_linux = os-linux.c + +libunwind_la_SOURCES_os_hpux = os-hpux.c + +libunwind_la_SOURCES_os_freebsd = os-freebsd.c + +libunwind_la_SOURCES_os_qnx = os-qnx.c + +libunwind_dwarf_common_la_SOURCES = dwarf/global.c + +libunwind_dwarf_local_la_SOURCES = \ + dwarf/Lexpr.c dwarf/Lfde.c dwarf/Lparser.c dwarf/Lpe.c dwarf/Lstep.c \ + dwarf/Lfind_proc_info-lsb.c \ + dwarf/Lfind_unwind_table.c +libunwind_dwarf_local_la_LIBADD = libunwind-dwarf-common.la + +libunwind_dwarf_generic_la_SOURCES = \ + dwarf/Gexpr.c dwarf/Gfde.c dwarf/Gparser.c dwarf/Gpe.c dwarf/Gstep.c \ + dwarf/Gfind_proc_info-lsb.c \ + dwarf/Gfind_unwind_table.c +libunwind_dwarf_generic_la_LIBADD = libunwind-dwarf-common.la + +if USE_DWARF + noinst_LTLIBRARIES += libunwind-dwarf-common.la libunwind-dwarf-generic.la +if !REMOTE_ONLY + noinst_LTLIBRARIES += libunwind-dwarf-local.la +endif + libunwind_la_LIBADD += libunwind-dwarf-local.la +endif + +noinst_HEADERS += elf32.h elf64.h elfxx.h + +libunwind_elf32_la_SOURCES = elf32.c +libunwind_elf64_la_SOURCES = elf64.c +libunwind_elfxx_la_SOURCES = elfxx.c +libunwind_elf32_la_LIBADD = $(LIBLZMA) +libunwind_elf64_la_LIBADD = $(LIBLZMA) +libunwind_elfxx_la_LIBADD = $(LIBLZMA) + +noinst_LTLIBRARIES += $(LIBUNWIND_ELF) +libunwind_la_LIBADD += $(LIBUNWIND_ELF) + +# The list of files that go into libunwind and libunwind-aarch64: +noinst_HEADERS += aarch64/init.h aarch64/offsets.h aarch64/unwind_i.h +libunwind_la_SOURCES_aarch64_common = $(libunwind_la_SOURCES_common) \ + aarch64/is_fpreg.c aarch64/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_aarch64 = $(libunwind_la_SOURCES_aarch64_common) \ + $(libunwind_la_SOURCES_local) \ + aarch64/Lcreate_addr_space.c aarch64/Lget_proc_info.c \ + aarch64/Lget_save_loc.c aarch64/Lglobal.c aarch64/Linit.c \ + aarch64/Linit_local.c aarch64/Linit_remote.c \ + aarch64/Lis_signal_frame.c aarch64/Lregs.c aarch64/Lresume.c \ + aarch64/Lstash_frame.c aarch64/Lstep.c aarch64/Ltrace.c \ + aarch64/getcontext.S + +libunwind_aarch64_la_SOURCES_aarch64 = $(libunwind_la_SOURCES_aarch64_common) \ + $(libunwind_la_SOURCES_generic) \ + aarch64/Gcreate_addr_space.c aarch64/Gget_proc_info.c \ + aarch64/Gget_save_loc.c aarch64/Gglobal.c aarch64/Ginit.c \ + aarch64/Ginit_local.c aarch64/Ginit_remote.c \ + aarch64/Gis_signal_frame.c aarch64/Gregs.c aarch64/Gresume.c \ + aarch64/Gstash_frame.c aarch64/Gstep.c aarch64/Gtrace.c + +# The list of files that go into libunwind and libunwind-arm: +noinst_HEADERS += arm/init.h arm/offsets.h arm/unwind_i.h +libunwind_la_SOURCES_arm_common = $(libunwind_la_SOURCES_common) \ + arm/is_fpreg.c arm/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_arm = $(libunwind_la_SOURCES_arm_common) \ + $(libunwind_la_SOURCES_local) \ + arm/getcontext.S \ + arm/Lcreate_addr_space.c arm/Lget_proc_info.c arm/Lget_save_loc.c \ + arm/Lglobal.c arm/Linit.c arm/Linit_local.c arm/Linit_remote.c \ + arm/Lis_signal_frame.c arm/Lregs.c arm/Lresume.c arm/Lstep.c \ + arm/Lex_tables.c arm/Lstash_frame.c arm/Ltrace.c + +libunwind_arm_la_SOURCES_arm = $(libunwind_la_SOURCES_arm_common) \ + $(libunwind_la_SOURCES_generic) \ + arm/Gcreate_addr_space.c arm/Gget_proc_info.c arm/Gget_save_loc.c \ + arm/Gglobal.c arm/Ginit.c arm/Ginit_local.c arm/Ginit_remote.c \ + arm/Gis_signal_frame.c arm/Gregs.c arm/Gresume.c arm/Gstep.c \ + arm/Gex_tables.c arm/Gstash_frame.c arm/Gtrace.c + +# The list of files that go both into libunwind and libunwind-ia64: +noinst_HEADERS += ia64/init.h ia64/offsets.h ia64/regs.h \ + ia64/ucontext_i.h ia64/unwind_decoder.h ia64/unwind_i.h +libunwind_la_SOURCES_ia64_common = $(libunwind_la_SOURCES_common) \ + ia64/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_ia64 = $(libunwind_la_SOURCES_ia64_common) \ + $(libunwind_la_SOURCES_local) \ + \ + ia64/dyn_info_list.S ia64/getcontext.S \ + \ + ia64/Lcreate_addr_space.c ia64/Lget_proc_info.c ia64/Lget_save_loc.c \ + ia64/Lglobal.c ia64/Linit.c ia64/Linit_local.c ia64/Linit_remote.c \ + ia64/Linstall_cursor.S ia64/Lis_signal_frame.c ia64/Lparser.c \ + ia64/Lrbs.c ia64/Lregs.c ia64/Lresume.c ia64/Lscript.c ia64/Lstep.c \ + ia64/Ltables.c ia64/Lfind_unwind_table.c + +# The list of files that go into libunwind-ia64: +libunwind_ia64_la_SOURCES_ia64 = $(libunwind_la_SOURCES_ia64_common) \ + $(libunwind_la_SOURCES_generic) \ + ia64/Gcreate_addr_space.c ia64/Gget_proc_info.c ia64/Gget_save_loc.c \ + ia64/Gglobal.c ia64/Ginit.c ia64/Ginit_local.c ia64/Ginit_remote.c \ + ia64/Ginstall_cursor.S ia64/Gis_signal_frame.c ia64/Gparser.c \ + ia64/Grbs.c ia64/Gregs.c ia64/Gresume.c ia64/Gscript.c ia64/Gstep.c \ + ia64/Gtables.c ia64/Gfind_unwind_table.c + +# The list of files that go both into libunwind and libunwind-hppa: +noinst_HEADERS += hppa/init.h hppa/offsets.h hppa/unwind_i.h +libunwind_la_SOURCES_hppa_common = $(libunwind_la_SOURCES_common) \ + hppa/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_hppa = $(libunwind_la_SOURCES_hppa_common) \ + $(libunwind_la_SOURCES_local) \ + hppa/getcontext.S hppa/setcontext.S \ + hppa/Lcreate_addr_space.c hppa/Lget_save_loc.c hppa/Lglobal.c \ + hppa/Linit.c hppa/Linit_local.c hppa/Linit_remote.c \ + hppa/Lis_signal_frame.c hppa/Lget_proc_info.c hppa/Lregs.c \ + hppa/Lresume.c hppa/Lstep.c + +# The list of files that go into libunwind-hppa: +libunwind_hppa_la_SOURCES_hppa = $(libunwind_la_SOURCES_hppa_common) \ + $(libunwind_la_SOURCES_generic) \ + hppa/Gcreate_addr_space.c hppa/Gget_save_loc.c hppa/Gglobal.c \ + hppa/Ginit.c hppa/Ginit_local.c hppa/Ginit_remote.c \ + hppa/Gis_signal_frame.c hppa/Gget_proc_info.c hppa/Gregs.c \ + hppa/Gresume.c hppa/Gstep.c + +# The list of files that go info libunwind and libunwind-mips: +noinst_HEADERS += mips/init.h mips/offsets.h +libunwind_la_SOURCES_mips_common = $(libunwind_la_SOURCES_common) \ + mips/is_fpreg.c mips/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_mips = $(libunwind_la_SOURCES_mips_common) \ + $(libunwind_la_SOURCES_local) \ + mips/getcontext.S \ + mips/Lcreate_addr_space.c mips/Lget_proc_info.c mips/Lget_save_loc.c \ + mips/Lglobal.c mips/Linit.c mips/Linit_local.c mips/Linit_remote.c \ + mips/Lis_signal_frame.c mips/Lregs.c mips/Lresume.c mips/Lstep.c + +libunwind_mips_la_SOURCES_mips = $(libunwind_la_SOURCES_mips_common) \ + $(libunwind_la_SOURCES_generic) \ + mips/Gcreate_addr_space.c mips/Gget_proc_info.c mips/Gget_save_loc.c \ + mips/Gglobal.c mips/Ginit.c mips/Ginit_local.c mips/Ginit_remote.c \ + mips/Gis_signal_frame.c mips/Gregs.c mips/Gresume.c mips/Gstep.c + +# The list of files that go info libunwind and libunwind-tilegx: +noinst_HEADERS += tilegx/init.h tilegx/offsets.h +libunwind_la_SOURCES_tilegx_common = $(libunwind_la_SOURCES_common) \ + tilegx/is_fpreg.c tilegx/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_tilegx = $(libunwind_la_SOURCES_tilegx_common) \ + $(libunwind_la_SOURCES_local) \ + tilegx/getcontext.S \ + tilegx/Lcreate_addr_space.c tilegx/Lget_proc_info.c tilegx/Lget_save_loc.c \ + tilegx/Lglobal.c tilegx/Linit.c tilegx/Linit_local.c tilegx/Linit_remote.c \ + tilegx/Lis_signal_frame.c tilegx/Lregs.c tilegx/Lresume.c tilegx/Lstep.c + +libunwind_tilegx_la_SOURCES_tilegx = $(libunwind_la_SOURCES_tilegx_common) \ + $(libunwind_la_SOURCES_generic) \ + tilegx/Gcreate_addr_space.c tilegx/Gget_proc_info.c tilegx/Gget_save_loc.c \ + tilegx/Gglobal.c tilegx/Ginit.c tilegx/Ginit_local.c tilegx/Ginit_remote.c \ + tilegx/Gis_signal_frame.c tilegx/Gregs.c tilegx/Gresume.c tilegx/Gstep.c + + +# The list of files that go both into libunwind and libunwind-x86: +noinst_HEADERS += x86/init.h x86/offsets.h x86/unwind_i.h +libunwind_la_SOURCES_x86_common = $(libunwind_la_SOURCES_common) \ + x86/is_fpreg.c x86/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common) \ + $(libunwind_la_SOURCES_x86_os_local) \ + $(libunwind_la_SOURCES_local) \ + x86/Lcreate_addr_space.c x86/Lget_save_loc.c x86/Lglobal.c \ + x86/Linit.c x86/Linit_local.c x86/Linit_remote.c \ + x86/Lget_proc_info.c x86/Lregs.c \ + x86/Lresume.c x86/Lstep.c + +# The list of files that go into libunwind-x86: +libunwind_x86_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common) \ + $(libunwind_la_SOURCES_x86_os) \ + $(libunwind_la_SOURCES_generic) \ + x86/Gcreate_addr_space.c x86/Gget_save_loc.c x86/Gglobal.c \ + x86/Ginit.c x86/Ginit_local.c x86/Ginit_remote.c \ + x86/Gget_proc_info.c x86/Gregs.c \ + x86/Gresume.c x86/Gstep.c + +# The list of files that go both into libunwind and libunwind-x86_64: +noinst_HEADERS += x86_64/offsets.h \ + x86_64/init.h x86_64/unwind_i.h x86_64/ucontext_i.h +libunwind_la_SOURCES_x86_64_common = $(libunwind_la_SOURCES_common) \ + x86_64/is_fpreg.c x86_64/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \ + $(libunwind_la_SOURCES_x86_64_os_local) \ + $(libunwind_la_SOURCES_local) \ + x86_64/setcontext.S \ + x86_64/Lcreate_addr_space.c x86_64/Lget_save_loc.c x86_64/Lglobal.c \ + x86_64/Linit.c x86_64/Linit_local.c x86_64/Linit_remote.c \ + x86_64/Lget_proc_info.c x86_64/Lregs.c x86_64/Lresume.c \ + x86_64/Lstash_frame.c x86_64/Lstep.c x86_64/Ltrace.c x86_64/getcontext.S + +# The list of files that go into libunwind-x86_64: +libunwind_x86_64_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \ + $(libunwind_la_SOURCES_x86_64_os) \ + $(libunwind_la_SOURCES_generic) \ + x86_64/Gcreate_addr_space.c x86_64/Gget_save_loc.c x86_64/Gglobal.c \ + x86_64/Ginit.c x86_64/Ginit_local.c x86_64/Ginit_remote.c \ + x86_64/Gget_proc_info.c x86_64/Gregs.c x86_64/Gresume.c \ + x86_64/Gstash_frame.c x86_64/Gstep.c x86_64/Gtrace.c + +# The list of local files that go to Power 64 and 32: +libunwind_la_SOURCES_ppc = \ + ppc/Lget_proc_info.c ppc/Lget_save_loc.c ppc/Linit_local.c \ + ppc/Linit_remote.c ppc/Lis_signal_frame.c + +# The list of generic files that go to Power 64 and 32: +libunwind_ppc_la_SOURCES_ppc_generic = \ + ppc/Gget_proc_info.c ppc/Gget_save_loc.c ppc/Ginit_local.c \ + ppc/Ginit_remote.c ppc/Gis_signal_frame.c + +# The list of files that go both into libunwind and libunwind-ppc32: +noinst_HEADERS += ppc32/init.h ppc32/unwind_i.h ppc32/ucontext_i.h +libunwind_la_SOURCES_ppc32_common = $(libunwind_la_SOURCES_common) \ + ppc32/is_fpreg.c ppc32/regname.c ppc32/get_func_addr.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \ + $(libunwind_la_SOURCES_local) \ + $(libunwind_la_SOURCES_ppc) \ + ppc32/Lcreate_addr_space.c \ + ppc32/Lglobal.c ppc32/Linit.c \ + ppc32/Lregs.c ppc32/Lresume.c ppc32/Lstep.c + +# The list of files that go into libunwind-ppc32: +libunwind_ppc32_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \ + $(libunwind_la_SOURCES_generic) \ + $(libunwind_ppc_la_SOURCES_ppc_generic) \ + ppc32/Gcreate_addr_space.c \ + ppc32/Gglobal.c ppc32/Ginit.c \ + ppc32/Gregs.c ppc32/Gresume.c ppc32/Gstep.c + +# The list of files that go both into libunwind and libunwind-ppc64: +noinst_HEADERS += ppc64/init.h ppc64/unwind_i.h ppc64/ucontext_i.h +libunwind_la_SOURCES_ppc64_common = $(libunwind_la_SOURCES_common) \ + ppc64/is_fpreg.c ppc64/regname.c ppc64/get_func_addr.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \ + $(libunwind_la_SOURCES_local) \ + $(libunwind_la_SOURCES_ppc) \ + ppc64/Lcreate_addr_space.c \ + ppc64/Lglobal.c ppc64/Linit.c \ + ppc64/Lregs.c ppc64/Lresume.c ppc64/Lstep.c + +# The list of files that go into libunwind-ppc64: +libunwind_ppc64_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \ + $(libunwind_la_SOURCES_generic) \ + $(libunwind_ppc_la_SOURCES_ppc_generic) \ + ppc64/Gcreate_addr_space.c \ + ppc64/Gglobal.c ppc64/Ginit.c \ + ppc64/Gregs.c ppc64/Gresume.c ppc64/Gstep.c + +# The list of files that go into libunwind and libunwind-sh: +noinst_HEADERS += sh/init.h sh/offsets.h sh/unwind_i.h +libunwind_la_SOURCES_sh_common = $(libunwind_la_SOURCES_common) \ + sh/is_fpreg.c sh/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \ + $(libunwind_la_SOURCES_local) \ + sh/Lcreate_addr_space.c sh/Lget_proc_info.c sh/Lget_save_loc.c \ + sh/Lglobal.c sh/Linit.c sh/Linit_local.c sh/Linit_remote.c \ + sh/Lis_signal_frame.c sh/Lregs.c sh/Lresume.c sh/Lstep.c + +libunwind_sh_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \ + $(libunwind_la_SOURCES_generic) \ + sh/Gcreate_addr_space.c sh/Gget_proc_info.c sh/Gget_save_loc.c \ + sh/Gglobal.c sh/Ginit.c sh/Ginit_local.c sh/Ginit_remote.c \ + sh/Gis_signal_frame.c sh/Gregs.c sh/Gresume.c sh/Gstep.c + +if REMOTE_ONLY +install-exec-hook: +# Nothing to do here.... +else +# +# This is not ideal, but I know of no other way to install an +# alias for a library. For the shared version, we have to do +# a file check before creating the link, because it isn't going +# to be there if the user configured with --disable-shared. +# +install-exec-hook: + cd $(DESTDIR)$(libdir) && $(LN_S) -f libunwind-$(arch).a libunwind-generic.a + if test -f $(DESTDIR)$(libdir)/libunwind-$(arch).so; then \ + cd $(DESTDIR)$(libdir) && $(LN_S) -f libunwind-$(arch).so \ + libunwind-generic.so; \ + fi +endif + +if OS_LINUX + libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_linux) + libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_linux_local) + libunwind_la_SOURCES_x86_os = x86/Gos-linux.c + libunwind_x86_la_SOURCES_os = x86/getcontext-linux.S + libunwind_la_SOURCES_x86_os_local = x86/Los-linux.c + libunwind_la_SOURCES_x86_64_os = x86_64/Gos-linux.c + libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-linux.c + libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_linux.c +endif + +if OS_HPUX + libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_hpux) + libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_hpux_local) +endif + +if OS_FREEBSD + libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_freebsd) + libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_freebsd_local) + libunwind_la_SOURCES_x86_os = x86/Gos-freebsd.c + libunwind_x86_la_SOURCES_os = x86/getcontext-freebsd.S + libunwind_la_SOURCES_x86_os_local = x86/Los-freebsd.c + libunwind_la_SOURCES_x86_64_os = x86_64/Gos-freebsd.c + libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-freebsd.c + libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_freebsd.c +endif + +if OS_QNX + libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_qnx) + libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_qnx_local) +endif + +if ARCH_AARCH64 + lib_LTLIBRARIES += libunwind-aarch64.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_aarch64) + libunwind_aarch64_la_SOURCES = $(libunwind_aarch64_la_SOURCES_aarch64) + libunwind_aarch64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_aarch64_la_LIBADD = libunwind-dwarf-generic.la + libunwind_aarch64_la_LIBADD += libunwind-elf64.la +if !REMOTE_ONLY + libunwind_aarch64_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += aarch64/siglongjmp.S +else +if ARCH_ARM + lib_LTLIBRARIES += libunwind-arm.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_arm) + libunwind_arm_la_SOURCES = $(libunwind_arm_la_SOURCES_arm) + libunwind_arm_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_arm_la_LIBADD = libunwind-dwarf-generic.la + libunwind_arm_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_arm_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += arm/siglongjmp.S +else +if ARCH_IA64 + BUILT_SOURCES = Gcursor_i.h Lcursor_i.h +mk_Gcursor_i.s: $(srcdir)/ia64/mk_Gcursor_i.c + $(COMPILE) -S "$(srcdir)/ia64/mk_Gcursor_i.c" -o mk_Gcursor_i.s +mk_Lcursor_i.s: $(srcdir)/ia64/mk_Lcursor_i.c + $(COMPILE) -S "$(srcdir)/ia64/mk_Lcursor_i.c" -o mk_Lcursor_i.s +Gcursor_i.h: mk_Gcursor_i.s + "$(srcdir)/ia64/mk_cursor_i" mk_Gcursor_i.s > Gcursor_i.h +Lcursor_i.h: mk_Lcursor_i.s + "$(srcdir)/ia64/mk_cursor_i" mk_Lcursor_i.s > Lcursor_i.h + + lib_LTLIBRARIES += libunwind-ia64.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_ia64) + libunwind_ia64_la_SOURCES = $(libunwind_ia64_la_SOURCES_ia64) + libunwind_ia64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_ia64_la_LIBADD = libunwind-elf64.la +if !REMOTE_ONLY + libunwind_ia64_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += ia64/setjmp.S ia64/sigsetjmp.S \ + ia64/longjmp.S ia64/siglongjmp.S +else +if ARCH_HPPA + lib_LTLIBRARIES += libunwind-hppa.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_hppa) + libunwind_hppa_la_SOURCES = $(libunwind_hppa_la_SOURCES_hppa) + libunwind_hppa_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_hppa_la_LIBADD = libunwind-dwarf-generic.la + libunwind_hppa_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_hppa_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += hppa/siglongjmp.S +else +if ARCH_MIPS + lib_LTLIBRARIES += libunwind-mips.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_mips) + libunwind_mips_la_SOURCES = $(libunwind_mips_la_SOURCES_mips) + libunwind_mips_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_mips_la_LIBADD = libunwind-dwarf-generic.la + libunwind_mips_la_LIBADD += libunwind-elfxx.la +if !REMOTE_ONLY + libunwind_mips_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += mips/siglongjmp.S +else +if ARCH_TILEGX + lib_LTLIBRARIES += libunwind-tilegx.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_tilegx) + libunwind_tilegx_la_SOURCES = $(libunwind_tilegx_la_SOURCES_tilegx) + libunwind_tilegx_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_tilegx_la_LIBADD = libunwind-dwarf-generic.la + libunwind_tilegx_la_LIBADD += libunwind-elfxx.la +if !REMOTE_ONLY + libunwind_tilegx_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += tilegx/siglongjmp.S +else +if ARCH_X86 + lib_LTLIBRARIES += libunwind-x86.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_x86) $(libunwind_x86_la_SOURCES_os) + libunwind_x86_la_SOURCES = $(libunwind_x86_la_SOURCES_x86) + libunwind_x86_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_x86_la_LIBADD = libunwind-dwarf-generic.la + libunwind_x86_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_x86_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += x86/longjmp.S x86/siglongjmp.S +else +if ARCH_X86_64 + lib_LTLIBRARIES += libunwind-x86_64.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_x86_64) + libunwind_x86_64_la_SOURCES = $(libunwind_x86_64_la_SOURCES_x86_64) + libunwind_x86_64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_x86_64_la_LIBADD = libunwind-dwarf-generic.la + libunwind_x86_64_la_LIBADD += libunwind-elf64.la +if !REMOTE_ONLY + libunwind_x86_64_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += x86_64/longjmp.S x86_64/siglongjmp.S +else +if ARCH_PPC32 + lib_LTLIBRARIES += libunwind-ppc32.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc32) + libunwind_ppc32_la_SOURCES = $(libunwind_ppc32_la_SOURCES_ppc32) + libunwind_ppc32_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_ppc32_la_LIBADD = libunwind-dwarf-generic.la + libunwind_ppc32_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_ppc32_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += ppc/longjmp.S ppc/siglongjmp.S +else +if ARCH_PPC64 + lib_LTLIBRARIES += libunwind-ppc64.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc64) + libunwind_ppc64_la_SOURCES = $(libunwind_ppc64_la_SOURCES_ppc64) + libunwind_ppc64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_ppc64_la_LIBADD = libunwind-dwarf-generic.la + libunwind_ppc64_la_LIBADD += libunwind-elf64.la +if !REMOTE_ONLY + libunwind_ppc64_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += ppc/longjmp.S ppc/siglongjmp.S +else +if ARCH_SH + lib_LTLIBRARIES += libunwind-sh.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_sh) + libunwind_sh_la_SOURCES = $(libunwind_sh_la_SOURCES_sh) + libunwind_sh_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_sh_la_LIBADD = libunwind-dwarf-generic.la + libunwind_sh_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_sh_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += sh/siglongjmp.S + +endif # ARCH_SH +endif # ARCH_PPC64 +endif # ARCH_PPC32 +endif # ARCH_X86_64 +endif # ARCH_X86 +endif # ARCH_TILEGX +endif # ARCH_MIPS +endif # ARCH_HPPA +endif # ARCH_IA64 +endif # ARCH_ARM +endif # ARCH_AARCH64 + +# libunwind-setjmp depends on libunwind-$(arch). Therefore must be added +# at the end. +if BUILD_SETJMP +lib_LTLIBRARIES += libunwind-setjmp.la +endif + +# +# Don't link with standard libraries, because those may mention +# libunwind already. +# +libunwind_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -XCClinker -nostdlib \ + $(LDFLAGS_STATIC_LIBCXA) -version-info $(SOVERSION) +libunwind_la_LIBADD += -lc $(LIBCRTS) +libunwind_la_LIBADD += $(LIBLZMA) + +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/tdep-$(arch) -I. +AM_CCASFLAGS = $(AM_CPPFLAGS) +noinst_HEADERS += unwind/unwind-internal.h + +EXTRA_DIST = $(libunwind_la_SOURCES_aarch64) \ + $(libunwind_la_SOURCES_arm) \ + $(libunwind_la_SOURCES_hppa) \ + $(libunwind_la_SOURCES_ia64) \ + $(libunwind_la_SOURCES_mips) \ + $(libunwind_la_SOURCES_sh) \ + $(libunwind_la_SOURCES_x86) \ + $(libunwind_la_SOURCES_os_freebsd) \ + $(libunwind_la_SOURCES_os_linux) \ + $(libunwind_la_SOURCES_os_hpux) \ + $(libunwind_la_SOURCES_os_qnx) \ + $(libunwind_la_SOURCES_common) \ + $(libunwind_la_SOURCES_local) \ + $(libunwind_la_SOURCES_generic) \ + $(libunwind_aarch64_la_SOURCES_aarch64) \ + $(libunwind_arm_la_SOURCES_arm) \ + $(libunwind_hppa_la_SOURCES_hppa) \ + $(libunwind_ia64_la_SOURCES_ia64) \ + $(libunwind_mips_la_SOURCES_mips) \ + $(libunwind_sh_la_SOURCES_sh) \ + $(libunwind_x86_la_SOURCES_x86) \ + $(libunwind_x86_64_la_SOURCES_x86_64) + +MAINTAINERCLEANFILES = Makefile.in + +# The -version-info flag accepts an argument of the form +# `current[:revision[:age]]'. So, passing `-version-info 3:12:1' sets +# current to 3, revision to 12, and age to 1. + +# If either revision or age are omitted, they default to 0. Also note +# that age must be less than or equal to the current interface number. + +# Here are a set of rules to help you update your library version +# information: + +# 1. Start with version information of `0:0:0' for each libtool +# library. + +# 2. Update the version information only immediately before a public +# release of your software. More frequent updates are unnecessary, +# and only guarantee that the current interface number gets larger +# faster. + +# 3. If the library source code has changed at all since the last +# update, then increment revision (`c:r:a' becomes `c:r+1:a'). + +# 4. If any interfaces have been added, removed, or changed since the +# last update, increment current, and set revision to 0. + +# 5. If any interfaces have been added since the last public release, +# then increment age. + +# 6. If any interfaces have been removed since the last public +# release, then set age to 0. diff --git a/src/libs/libunwind/NEWS b/src/libs/libunwind/NEWS new file mode 100644 index 0000000000..e26d1c9b55 --- /dev/null +++ b/src/libs/libunwind/NEWS @@ -0,0 +1,229 @@ +-*-Mode: outline-*- + +* News for v1.1: + +** coredump unwind support +** New arch: SuperH +** Improved support for PowerPC, ARM +** Lots of cleanups, perf tweaks +** pkg-config support + +* News for v1.0: + +** Fast unwind (rbp, rsp, rip only) on x86_64 with a fallback to + slow code path (Lassi Tuura) +** Improved local and remote unwinding on ARM (Ken Werner) +** Testing, stability and many fixes on x86 (Paul Pluzhnikov) +** FreeBSD port and clean separation of OS specific bits + (Konstantin Belousov) +** Thanks for all the bug reports, contributions and testing! + +* News for v0.99: + +** Greatly improved x86-64 support thanks to Arun Sharma. +** Support for PPC64 added by Jose Flavio Aguilar Paulino. + +* News for v0.98.6: + +** Fix address-leak triggered by invalid byte-order. Fixed by Andreas Schwab. +** On ia64, get_static_proc_name() no longer uses a weak reference to + _Uelf64_get_proc_name(), since that was causing problems with archive + libraries and no longer served any apparent purpose. Fixed by + Curt Wohlgemuth. + +* News for v0.98.5: + +** Fix a typo in the man-page of unw_create_addr_space(). +** Fix an off-by-1 bug in the handling of the dynamic ALIAS directive + for ia64. Reported by Todd L. Miller. +** Fix a bug in libunwind-ptrace which could cause crash due to extraneous + munmap() calls. + +* News for v0.98.4: + +** Fix a typo in _ReadSLEB.c which caused hangs when throwing exceptions + from Intel ICC-compiled programs. Reported by Tommy Hoffner. + +* News for v0.98.3: + +** Make it possible to link against libunwind-ia64.a only (i.e., without + requiring libunwind.a as well). This keeps apps which need only + remote unwinding cleaner, since they logically have no dependency + on libunwind.a. +** Dont link against libatomic_ops for now. Due to a packaging bug on + Debian, linking against this library causes libunwind.so to get + a dependency on libatomic_ops.so, which is not at all what we want. + Fortunately, we don't have to link against that library on x86 or + ia64 since the library is strictly needed only for platforms with + poor atomic operation support. Once the libatomic_ops package is fixed, + we can re-enable linking against libatomic_ops. + +* News for v0.98.2: + +** Fixed bug which caused _UPT_get_dyn_info_list_addr() to sometimes fail + needlessly. Found by Todd L. Miller. + +** When using GCC to build libunwind on ia64, libunwind.so had an + unresolved reference to __divdi3. This is undesirable since it + creates an implicit dependency on libgcc. This problem has been + fixed in the 0.98.2 release by explicitly linking against libgcc.a + when building libunwind. + +* News for v0.98.1: + +** Fixed a bug which caused "make install" to install libunwind-common.h.in + instead of libunwind-common.h. +** Fixed a bug in the ia64 {sig,}longjmp() which showed on + SuSE Linux 9 because it's using a newer compiler & the EPC-based system + call stubs. +** Fixed incorrect offsets in tests/ia64-test-nat-asm.S. + Warning: you'll need a GNU assembler dated later than 21-Sep-2004 to + get this file translated correctly. With an old assembler, "make check" + will get lots of failures when running Gia64-test-nat or Lia64-test-nat! +** Convert tests/bt into a full-blown test-case. It's designed to + trigger a (rarely-encountered) bug in the GNU assembler on ia64. + The assembler has been fixed and once the libraries (libc etc) + have been rebuilt, this test will pass. +** Added test-case tests/run-ptrace-misc which, on ia64, triggers a bug in + current GCC (including v3.4.2) which causes bad unwind info. + +* News for v0.98: + +** Update libunwind to be compliant with the updated/expanded + ia64 unwind specificiation by HJ Lu [1]. This is needed for + GCC 3.4 compatibility. + + [1] http://www.kernel.org/pub/linux/devel/gcc/unwind/ + +** Initial support for x86-64 has been added courtesy of Max Asbock. + Along with this came a bunch of DWARF2 unwinder fixes. + +** A new rountine unw_strerror() has been added courtesy of + Thomas Hallgren. + +** Including now defines 4 macros that can be used + to determine the version number of libunwind. Specifically, + UNW_VERSION_MAJOR, UNW_VERSION_MINOR, UNW_VERSION, and + UNW_VERSION_CODE are defined by the header now. + +** Bug fixes +*** Fix a memory-leak in _UPT_get_dyn_info_list_addr() courtesy of Ed Connell. +*** Fix a crash in libunwind-ptrace courtesy of Mark Young. +*** Fix a bug in ia64-version of unw_init_remote() which prevented + it from working correctly for the local address space. Reported by + Troy Heber. +*** Many other small and not so small fixes. + +* News for v0.97: + +** unw_get_proc_name() may now be called from signal-handler. + +** The ptrace-helper routines are now declared in libunwind-ptrace.h. + Applications which use ptrace-based unwinding should include + to get the _UPT_*() routines declared. + +** libunwind has been split into a "local-only" and a "generic" versions. + The former is optimized for local unwinding (within a process) and + is called libunwind.so (shared version) or libunwind.a (archive + version). The generic version is not limited to unwinding within a + process and is called libunwind-generic.so (shared version) + libunwind-generic.a (archive version). Similarly, the ptrace() + support has been separated out into a convenience library called + libunwind-ptrace.a. For the most part, backwards-compatibility + is retained. However, when building an application which uses + libunwind, it may be necessary to change the linker command-line + as shown in the table below: + + Application which does: Before v0.97: With v0.97: + ----------------------- ------------- ----------- + local unwinding only: -lunwind -lunwind + remote unwinding: -lunwind -lunwind-generic + cross unwinding: -lunwind-PLAT -lunwind-PLAT + ptrace-based unwinding: -lunwind -lunwind-ptrace -lunwind-generic + + The motivation for this splitting is to keep libunwind.so as minimal + as possible. This library will eventually be loaded by most (if not + all) executables and hence it is important to ensure that it can + be loaded as quickly as possible. + +** unw_getcontext() tuned on IA-64. + + The unw_getcontext() routine used to be provided by (GNU) libc + (getcontext()). This caused unnecessary overhead (e.g., an + unnecessary system-call to sigprocmask()). The new + unw_getcontext() only does the work really needed for libunwind and + hence performs much better. However, this change implies that + programs linked against libunwind v0.97 won't be + backwards-compatible with earlier versions (there would be an + unresolved symbol for _Uia64_getcontext()). + +** Fix NaT-bit handling on IA-64. + + New test-cases have been added to test the handling of the NaT bit + (and floating-point NaT values) and all discovered/known bugs have + been fixed. + +** Initial DWARF-based unwinder for x86. + + There is a beginning for a DWARF-based unwinder for x86. Work for + x86-64-support based on this DWARF unwinder is currently underway + at IBM and it is expected that this support will be merged into the + official tree soon. + + +* News for v0.96: + +** _Unwind_*() routines defined by the C++ ABI are now included in + libunwind. + + +* News for v0.95: + +** Bigger, better, faster, or so the theory goes. + + +* News for v0.93: + +** More bug-fixes & improved HP-UX support. + + +* News for v0.92: + +** Bug-fix release. IA-64 unwinder can now be built with Intel compiler (ECC). + + +* News for v0.91: + +** Lots of documentation updates +** Some portability fixes. + + +* News for v0.9: + +** The libunwind API is mostly feature-complete at this point (hence the + version jump from v0.2 to v0.9). + + +* News for v0.2: + +** Automated configuration/build with autoconf and automake. +** Added support for building libunwind as a shared library. +** Added support for remote unwinding. +** Added support for cross-building. +** Added two new routines to the API: + - unw_is_fpreg() + - unw_get_save_loc() +** Added multi-architecture supports (lets a single application use + the unwind libraries for multiple target architectures; this is useful, + e.g., useful for building a debugger that can support multiple targets + such as x86, ia64, etc.) + + +* News for v0.1: + +** Added support for exception handling. + + +* News for v0.0: + +** It's a brand new package. diff --git a/src/libs/libunwind/README b/src/libs/libunwind/README new file mode 100644 index 0000000000..cadffc172d --- /dev/null +++ b/src/libs/libunwind/README @@ -0,0 +1,214 @@ +-*- mode: Outline -*- + +This is version 1.0 of the unwind library. This library supports +several architecture/operating-system combinations: + + Linux/x86-64: Works well. + Linux/x86: Works well. + Linux/ARM: Works well. + Linux/IA-64: Fully tested and supported. + Linux/PARISC: Works well, but C library missing unwind-info. + HP-UX/IA-64: Mostly works but known to have some serious limitations. + Linux/AArch64: Newly added. + Linux/PPC64: Newly added. + Linux/SuperH: Newly added. + FreeBSD/i386: Newly added. + FreeBSD/x86-64: Newly added (FreeBSD architecture is known as amd64). + Linux/Tilegx: Newly added (64-bit mode only). + +* General Build Instructions + +In general, this library can be built and installed with the following +commands: + + $ ./autogen.sh # Needed only for building from git. Depends on libtool. + $ ./configure + $ make + $ make install prefix=PREFIX + +where PREFIX is the installation prefix. By default, a prefix of +/usr/local is used, such that libunwind.a is installed in +/usr/local/lib and unwind.h is installed in /usr/local/include. For +testing, you may want to use a prefix of /usr/local instead. + + +* Building with Intel compiler + +** Version 8 and later + +Starting with version 8, the preferred name for the IA-64 Intel +compiler is "icc" (same name as on x86). Thus, the configure-line +should look like this: + + $ ./configure CC=icc CFLAGS="-g -O3 -ip" CXX=icc CCAS=gcc CCASFLAGS=-g \ + LDFLAGS="-L$PWD/src/.libs" + + +* Building on HP-UX + +For the time being, libunwind must be built with GCC on HP-UX. + +libunwind should be configured and installed on HP-UX like this: + + $ ./configure CFLAGS="-g -O2 -mlp64" CXXFLAGS="-g -O2 -mlp64" + +Caveat: Unwinding of 32-bit (ILP32) binaries is not supported + at the moment. + +** Workaround for older versions of GCC + +GCC v3.0 and GCC v3.2 ship with a bad version of sys/types.h. The +workaround is to issue the following commands before running +"configure": + + $ mkdir $top_dir/include/sys + $ cp /usr/include/sys/types.h $top_dir/include/sys + +GCC v3.3.2 or later have been fixed and do not require this +workaround. + +* Building for PowerPC64 / Linux + +For building for power64 you should use: + + $ ./configure CFLAGS="-g -O2 -m64" CXXFLAGS="-g -O2 -m64" + +If your power support altivec registers: + $ ./configure CFLAGS="-g -O2 -m64 -maltivec" CXXFLAGS="-g -O2 -m64 -maltivec" + +To check if your processor has support for vector registers (altivec): + cat /proc/cpuinfo | grep altivec +and should have something like this: + cpu : PPC970, altivec supported + +If libunwind seems to not work (backtracing failing), try to compile +it with -O0, without optimizations. There are some compiler problems +depending on the version of your gcc. + +* Building on FreeBSD + +General building instructions apply. To build and execute several tests, +you need libexecinfo library available in ports as devel/libexecinfo. + +Development of the port was done of FreeBSD 8.0-STABLE. The library +was build with the system compiler that is modified version of gcc 4.2.1, +as well as the gcc 4.4.3. + +* Regression Testing + +After building the library, you can run a set of regression tests with: + + $ make check + +** Expected results on IA-64 Linux + +Unless you have a very recent C library and compiler installed, it is +currently expected to have the following tests fail on IA-64 Linux: + + Gtest-init (should pass starting with glibc-2.3.x/gcc-3.4) + Ltest-init (should pass starting with glibc-2.3.x/gcc-3.4) + test-ptrace (should pass starting with glibc-2.3.x/gcc-3.4) + run-ia64-test-dyn1 (should pass starting with glibc-2.3.x) + +This does not mean that libunwind cannot be used with older compilers +or C libraries, it just means that for certain corner cases, unwinding +will fail. Since they're corner cases, it is not likely for +applications to trigger them. + +Note: If you get lots of errors in Gia64-test-nat and Lia64-test-nat, it's + almost certainly a sign of an old assembler. The GNU assembler used + to encode previous-stack-pointer-relative offsets incorrectly. + This bug was fixed on 21-Sep-2004 so any later assembler will be + fine. + +** Expected results on x86 Linux + +The following tests are expected to fail on x86 Linux: + + Gtest-resume-sig (fails to get SIGUSR2) + Ltest-resume-sig (likewise) + Gtest-dyn1 (no dynamic unwind info support yet) + Ltest-dyn1 (no dynamic unwind info support yet) + test-setjmp (longjmp() not implemented yet) + run-check-namespace (no _Ux86_getcontext yet) + test-ptrace + +** Expected results on x86-64 Linux + +The following tests are expected to fail on x86-64 Linux: + + Gtest-dyn1 (no dynamic unwind info support yet) + Ltest-dyn1 (no dynamic unwind info support yet) + Gtest-init (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18743) + Ltest-init (likewise) + test-async-sig (crashes due to bad unwind-info?) + test-setjmp (longjmp() not implemented yet) + run-check-namespace (no _Ux86_64_getcontext yet) + run-ptrace-mapper (??? investigate) + run-ptrace-misc (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18748 + and http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18749) + +** Expected results on PARISC Linux + +Caveat: GCC v3.4 or newer is needed on PA-RISC Linux. Earlier +versions of the compiler failed to generate the exception-handling +program header (GNU_EH_FRAME) needed for unwinding. + +The following tests are expected to fail on x86-64 Linux: + + Gtest-bt (backtrace truncated at kill() due to lack of unwind-info) + Ltest-bt (likewise) + Gtest-resume-sig (Gresume.c:my_rt_sigreturn() is wrong somehow) + Ltest-resume-sig (likewise) + Gtest-init (likewise) + Ltest-init (likewise) + Gtest-dyn1 (no dynamic unwind info support yet) + Ltest-dyn1 (no dynamic unwind info support yet) + test-setjmp (longjmp() not implemented yet) + run-check-namespace (toolchain doesn't support HIDDEN yet) + +** Expected results on HP-UX + +"make check" is currently unsupported for HP-UX. You can try to run +it, but most tests will fail (and some may fail to terminate). The +only test programs that are known to work at this time are: + + tests/bt + tests/Gperf-simple + tests/test-proc-info + tests/test-static-link + tests/Gtest-init + tests/Ltest-init + tests/Gtest-resume-sig + tests/Ltest-resume-sig + +** Expected results on PPC64 Linux + +"make check" should run with no more than 10 out of 24 tests failed. + + +* Performance Testing + +This distribution includes a few simple performance tests which give +some idea of the basic cost of various libunwind operations. After +building the library, you can run these tests with the following +commands: + + $ cd tests + $ make perf + +* Contacting the Developers + +Please direct all questions regarding this library to: + + libunwind-devel@nongnu.org + +You can do this by sending a mail to libunwind-request@nongnu.org with +a body of: + + subscribe libunwind-devel + +or you can subscribe and manage your subscription via the +web-interface at: + + https://savannah.nongnu.org/mail/?group=libunwind diff --git a/src/libs/libunwind/TODO b/src/libs/libunwind/TODO new file mode 100644 index 0000000000..8b2e0262b0 --- /dev/null +++ b/src/libs/libunwind/TODO @@ -0,0 +1,97 @@ +- Update the libunwind man page for the new/fixed cache-flushing behavior. + Effectively, that unw_flush_cache() doesn't have to be called by + applications except for extraordinary circumstances (e.g., if application + implements its own runtime loader). +- document split local-only/generic libraries and separate libunwind-ptrace.a + convenience-library +- document new "tdep" member in unw_proc_info_t structure +- for DWARF 2, use a dummy CIE entry with an augmentation that + provides the dyn-info-list-address + +=== taken care of: + +Testing: + + ensure that saving r4-r7 in a stacked register properly preserves + the NaT bit, even in the face of register-rotation + + ensure that IA64_INSN_MOVE_STACKED works correctly in the face of + register rotation + + on Linux, test access to f32-f127 in a signal handler (e.g., verify + that fph partition gets initialized properly) ++ According to Nicholas S. Wourms , adding this to the + Makefile.am: + AUTOMAKE_OPTIONS = 1.6 subdir-objects + ensures that object-files are build in separate subdirectories and that + in turn makes it possible for source files in different directories to + have the same filename, thus avoiding the need for those ugly -x86, -ia64, + etc., postfixes. ++ Switch ia64 (and rest over) to using Debug() instead of debug() ++ implement non-local versions of dwarf_readXX() ++ consolidate mostly architecture-independent code such as + unw_get_accessors() into shared files ++ caching is pretty fundamentally broken, what should happen is this: + o On unw_init_local()/unw_init_remote(), libunwind should validate + that the cached information is still valid and, if not, flush the + cache on its own. Rationale: once unw_init_local() has been + called, it is clear that the unwind info for the calling thread + cannot change (otherwise the program would be buggy anyhow) and + hence it is sufficient to validate the cache at this point. + Similarly, once unw_init_remote() has been called, the target + address space must have been stopped, because the unwinding would + otherwise be unreliable anyhow. + o glibc currently lacks a feature for dl_iterate_phdr() to support + safe caching; I proposed on 12/16/2003 that glibc maintain two + atomic counters which get inremented whenever something is added + to/removed from the dl_iterate_phdr-list. Once we have such counters, + we can use them in libunwind to implement an efficient version of a + cache-validation routine. + Once this has been fixed, update the libunwind man page accordingly. + Effectively, what this means is that unw_flush_cache() doesn't have + to be called by applications except for extraordinary circumstances + (e.g., if application implements its own runtime loader). ++ man-page for unw_is_fpreg() ++ man-page for _U_dyn_cancel() ++ man-page for _U_dyn_register() ++ global data is not protected by a lock; causes problems if two threads + call ia64_init() at almost the same time ++ cache the value of *cfm_loc; each rotate_FOO() call needs it! ++ implement the remote-lookup of the dynamic registration list ++ when doing sigreturn, must restore fp regs (and perhaps other regs) the same + way as the (user-level) gate.S sigreturn path does! ++ unw_resume() must at least restore gp (r1)! consider restoring all + scratch regs (but what's the performance impact on exception handling?); + alternative: restore scratch regs that may be used during procedure + call/return (e.g., r8-r11, f8-f11) ++ implement unw_resume() for the case where the current register frame is split + across multiple backing stores ++ document restricions on using unw_resume(): ++ implement remote cases of unw_resume() ++ test both with UNW_LOCAL_ONLY and without where this makes sense ++ allow region-length (insn_count) in unw_dyn_region_info_t to be negative + to indicate counting from the end of the procedure (to make it possible + for differently-sized procedures to share the same region list if they + share the same prologue/epilogue). ++ it appears that it is currently not possible to read register UNW_IA64_TP; + fix that => no, attempts to access r13 will result in access_reg() callbacks, + as desired; for local-case, access to r13 will fail though (since + getcontext() doesn't, and shouldn't, capture r13) ++ document the special nature of UNW_IA64_GP: read-only, but adjusted + automatically if the IP is changed ++ use pthread-mutexes where necessary, atomic ops where possible ++ man-page for unw_init_local() ++ man-page for unw_init_remote() ++ man-page for unw_create_addr_space() ++ man-page for unw_destroy_addr_space() ++ man-page for unw_get_proc_info() ++ man-page for unw_get_proc_name() ++ man-page for unw_get_accessors() ++ man-page for unw_regname() ++ man-page for unw_flush_cache() ++ man-page for unw_set_caching_policy() ++ man-page for unw_getcontext() ++ man-page for unw_is_signal_frame() ++ man-page for unw_step() ++ man-page for unw_get_reg() ++ man-page for unw_set_reg() ++ man-page for unw_get_fpreg() ++ man-page for unw_set_fpreg() ++ test with Intel compiler diff --git a/src/libs/libunwind/aarch64/Gcreate_addr_space.c b/src/libs/libunwind/aarch64/Gcreate_addr_space.c new file mode 100644 index 0000000000..b0f2b0488c --- /dev/null +++ b/src/libs/libunwind/aarch64/Gcreate_addr_space.c @@ -0,0 +1,60 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "unwind_i.h" + +PROTECTED unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* AArch64 supports little-endian and big-endian. */ + if (byte_order != 0 && byte_order != __LITTLE_ENDIAN + && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + /* Default to little-endian for AArch64. */ + if (byte_order == 0 || byte_order == __LITTLE_ENDIAN) + as->big_endian = 0; + else + as->big_endian = 1; + + return as; +#endif +} diff --git a/src/libs/libunwind/aarch64/Gget_proc_info.c b/src/libs/libunwind/aarch64/Gget_proc_info.c new file mode 100644 index 0000000000..de9199f995 --- /dev/null +++ b/src/libs/libunwind/aarch64/Gget_proc_info.c @@ -0,0 +1,39 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + ret = dwarf_make_proc_info (&c->dwarf); + if (ret < 0) + return ret; + + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/libs/libunwind/aarch64/Gget_save_loc.c b/src/libs/libunwind/aarch64/Gget_save_loc.c new file mode 100644 index 0000000000..5ccf5cfdb9 --- /dev/null +++ b/src/libs/libunwind/aarch64/Gget_save_loc.c @@ -0,0 +1,100 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + switch (reg) + { + case UNW_AARCH64_X0: + case UNW_AARCH64_X1: + case UNW_AARCH64_X2: + case UNW_AARCH64_X3: + case UNW_AARCH64_X4: + case UNW_AARCH64_X5: + case UNW_AARCH64_X6: + case UNW_AARCH64_X7: + case UNW_AARCH64_X8: + case UNW_AARCH64_X9: + case UNW_AARCH64_X10: + case UNW_AARCH64_X11: + case UNW_AARCH64_X12: + case UNW_AARCH64_X13: + case UNW_AARCH64_X14: + case UNW_AARCH64_X15: + case UNW_AARCH64_X16: + case UNW_AARCH64_X17: + case UNW_AARCH64_X18: + case UNW_AARCH64_X19: + case UNW_AARCH64_X20: + case UNW_AARCH64_X21: + case UNW_AARCH64_X22: + case UNW_AARCH64_X23: + case UNW_AARCH64_X24: + case UNW_AARCH64_X25: + case UNW_AARCH64_X26: + case UNW_AARCH64_X27: + case UNW_AARCH64_X28: + case UNW_AARCH64_X29: + case UNW_AARCH64_X30: + case UNW_AARCH64_SP: + case UNW_AARCH64_PC: + case UNW_AARCH64_PSTATE: + loc = c->dwarf.loc[reg]; + break; + + default: + loc = DWARF_NULL_LOC; /* default to "not saved" */ + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/libs/libunwind/aarch64/Gglobal.c b/src/libs/libunwind/aarch64/Gglobal.c new file mode 100644 index 0000000000..72e36b2d4d --- /dev/null +++ b/src/libs/libunwind/aarch64/Gglobal.c @@ -0,0 +1,57 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (aarch64_lock); +HIDDEN int tdep_init_done; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&aarch64_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + aarch64_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&aarch64_lock, saved_mask); +} diff --git a/src/libs/libunwind/aarch64/Ginit.c b/src/libs/libunwind/aarch64/Ginit.c new file mode 100644 index 0000000000..af0359a69c --- /dev/null +++ b/src/libs/libunwind/aarch64/Ginit.c @@ -0,0 +1,190 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +PROTECTED unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static inline void * +uc_addr (ucontext_t *uc, int reg) +{ + if (reg >= UNW_AARCH64_X0 && reg < UNW_AARCH64_V0) + return &uc->uc_mcontext.regs[reg]; + else if (reg >= UNW_AARCH64_V0 && reg <= UNW_AARCH64_V31) + return &GET_FPCTX(uc)->vregs[reg - UNW_AARCH64_V0]; + else + return NULL; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (16, "mem[%lx] <- %lx\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + *val = *(unw_word_t *) addr; + Debug (16, "mem[%lx] -> %lx\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = arg; + + if (unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %lx\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %lx\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + unw_fpreg_t *addr; + + if (!unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +aarch64_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = aarch64_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/aarch64/Ginit_local.c b/src/libs/libunwind/aarch64/Ginit_local.c new file mode 100644 index 0000000000..dee6fd3b80 --- /dev/null +++ b/src/libs/libunwind/aarch64/Ginit_local.c @@ -0,0 +1,55 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2011-2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = uc; + + return common_init (c, 1); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/aarch64/Ginit_remote.c b/src/libs/libunwind/aarch64/Ginit_remote.c new file mode 100644 index 0000000000..f284e994f4 --- /dev/null +++ b/src/libs/libunwind/aarch64/Ginit_remote.c @@ -0,0 +1,45 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +PROTECTED int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/libs/libunwind/aarch64/Gis_signal_frame.c b/src/libs/libunwind/aarch64/Gis_signal_frame.c new file mode 100644 index 0000000000..53e32de131 --- /dev/null +++ b/src/libs/libunwind/aarch64/Gis_signal_frame.c @@ -0,0 +1,64 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* The restorer stub will always have the form: + + d2801168 movz x8, #0x8b + d4000001 svc #0x0 +*/ + +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors (as); + arg = c->dwarf.as_arg; + + ip = c->dwarf.ip; + + ret = (*a->access_mem) (as, ip, &w0, 0, arg); + if (ret < 0) + return ret; + + /* FIXME: distinguish 32bit insn vs 64bit registers. */ + if (w0 != 0xd4000001d2801168) + return 0; + + return 1; + +#else + return -UNW_ENOINFO; +#endif +} diff --git a/src/libs/libunwind/aarch64/Gregs.c b/src/libs/libunwind/aarch64/Gregs.c new file mode 100644 index 0000000000..e9ec85f936 --- /dev/null +++ b/src/libs/libunwind/aarch64/Gregs.c @@ -0,0 +1,116 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + unsigned int mask; + + switch (reg) + { + case UNW_AARCH64_X0: + case UNW_AARCH64_X1: + case UNW_AARCH64_X2: + case UNW_AARCH64_X3: + mask = 1 << reg; + if (write) + { + c->dwarf.eh_args[reg] = *valp; + c->dwarf.eh_valid_mask |= mask; + return 0; + } + else if ((c->dwarf.eh_valid_mask & mask) != 0) + { + *valp = c->dwarf.eh_args[reg]; + return 0; + } + else + loc = c->dwarf.loc[reg]; + break; + + case UNW_AARCH64_X4: + case UNW_AARCH64_X5: + case UNW_AARCH64_X6: + case UNW_AARCH64_X7: + case UNW_AARCH64_X8: + case UNW_AARCH64_X9: + case UNW_AARCH64_X10: + case UNW_AARCH64_X11: + case UNW_AARCH64_X12: + case UNW_AARCH64_X13: + case UNW_AARCH64_X14: + case UNW_AARCH64_X15: + case UNW_AARCH64_X16: + case UNW_AARCH64_X17: + case UNW_AARCH64_X18: + case UNW_AARCH64_X19: + case UNW_AARCH64_X20: + case UNW_AARCH64_X21: + case UNW_AARCH64_X22: + case UNW_AARCH64_X23: + case UNW_AARCH64_X24: + case UNW_AARCH64_X25: + case UNW_AARCH64_X26: + case UNW_AARCH64_X27: + case UNW_AARCH64_X28: + case UNW_AARCH64_X29: + case UNW_AARCH64_X30: + case UNW_AARCH64_PC: + case UNW_AARCH64_PSTATE: + loc = c->dwarf.loc[reg]; + break; + + case UNW_AARCH64_SP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + dwarf_loc_t loc = c->dwarf.loc[reg]; + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); +} diff --git a/src/libs/libunwind/aarch64/Gresume.c b/src/libs/libunwind/aarch64/Gresume.c new file mode 100644 index 0000000000..65517a252d --- /dev/null +++ b/src/libs/libunwind/aarch64/Gresume.c @@ -0,0 +1,198 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2011-2013 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_tdep_context_t *uc = c->dwarf.as_arg; + + if (c->sigcontext_format == AARCH64_SCF_NONE) + { + /* Since there are no signals involved here we restore EH and non scratch + registers only. */ + unsigned long regs[24]; + regs[0] = uc->uc_mcontext.regs[0]; + regs[1] = uc->uc_mcontext.regs[1]; + regs[2] = uc->uc_mcontext.regs[2]; + regs[3] = uc->uc_mcontext.regs[3]; + regs[4] = uc->uc_mcontext.regs[19]; + regs[5] = uc->uc_mcontext.regs[20]; + regs[6] = uc->uc_mcontext.regs[21]; + regs[7] = uc->uc_mcontext.regs[22]; + regs[8] = uc->uc_mcontext.regs[23]; + regs[9] = uc->uc_mcontext.regs[24]; + regs[10] = uc->uc_mcontext.regs[25]; + regs[11] = uc->uc_mcontext.regs[26]; + regs[12] = uc->uc_mcontext.regs[27]; + regs[13] = uc->uc_mcontext.regs[28]; + regs[14] = uc->uc_mcontext.regs[29]; /* FP */ + regs[15] = uc->uc_mcontext.regs[30]; /* LR */ + regs[16] = GET_FPCTX(uc)->vregs[8]; + regs[17] = GET_FPCTX(uc)->vregs[9]; + regs[18] = GET_FPCTX(uc)->vregs[10]; + regs[19] = GET_FPCTX(uc)->vregs[11]; + regs[20] = GET_FPCTX(uc)->vregs[12]; + regs[21] = GET_FPCTX(uc)->vregs[13]; + regs[22] = GET_FPCTX(uc)->vregs[14]; + regs[23] = GET_FPCTX(uc)->vregs[15]; + unsigned long sp = uc->uc_mcontext.sp; + + struct regs_overlay { + char x[sizeof(regs)]; + }; + + asm volatile ( + "mov x4, %0\n" + "mov x5, %1\n" + "ldp x0, x1, [x4]\n" + "ldp x2, x3, [x4,16]\n" + "ldp x19, x20, [x4,32]\n" + "ldp x21, x22, [x4,48]\n" + "ldp x23, x24, [x4,64]\n" + "ldp x25, x26, [x4,80]\n" + "ldp x27, x28, [x4,96]\n" + "ldp x29, x30, [x4,112]\n" + "ldp d8, d9, [x4,128]\n" + "ldp d10, d11, [x4,144]\n" + "ldp d12, d13, [x4,160]\n" + "ldp d14, d15, [x4,176]\n" + "mov sp, x5\n" + "ret \n" + : + : "r" (regs), + "r" (sp), + "m" (*(struct regs_overlay *)regs) + ); + } + else + { + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + + if (c->dwarf.eh_valid_mask & 0x1) sc->regs[0] = c->dwarf.eh_args[0]; + if (c->dwarf.eh_valid_mask & 0x2) sc->regs[1] = c->dwarf.eh_args[1]; + if (c->dwarf.eh_valid_mask & 0x4) sc->regs[2] = c->dwarf.eh_args[2]; + if (c->dwarf.eh_valid_mask & 0x8) sc->regs[3] = c->dwarf.eh_args[3]; + + sc->regs[4] = uc->uc_mcontext.regs[4]; + sc->regs[5] = uc->uc_mcontext.regs[5]; + sc->regs[6] = uc->uc_mcontext.regs[6]; + sc->regs[7] = uc->uc_mcontext.regs[7]; + sc->regs[8] = uc->uc_mcontext.regs[8]; + sc->regs[9] = uc->uc_mcontext.regs[9]; + sc->regs[10] = uc->uc_mcontext.regs[10]; + sc->regs[11] = uc->uc_mcontext.regs[11]; + sc->regs[12] = uc->uc_mcontext.regs[12]; + sc->regs[13] = uc->uc_mcontext.regs[13]; + sc->regs[14] = uc->uc_mcontext.regs[14]; + sc->regs[15] = uc->uc_mcontext.regs[15]; + sc->regs[16] = uc->uc_mcontext.regs[16]; + sc->regs[17] = uc->uc_mcontext.regs[17]; + sc->regs[18] = uc->uc_mcontext.regs[18]; + sc->regs[19] = uc->uc_mcontext.regs[19]; + sc->regs[20] = uc->uc_mcontext.regs[20]; + sc->regs[21] = uc->uc_mcontext.regs[21]; + sc->regs[22] = uc->uc_mcontext.regs[22]; + sc->regs[23] = uc->uc_mcontext.regs[23]; + sc->regs[24] = uc->uc_mcontext.regs[24]; + sc->regs[25] = uc->uc_mcontext.regs[25]; + sc->regs[26] = uc->uc_mcontext.regs[26]; + sc->regs[27] = uc->uc_mcontext.regs[27]; + sc->regs[28] = uc->uc_mcontext.regs[28]; + sc->regs[29] = uc->uc_mcontext.regs[29]; + sc->regs[30] = uc->uc_mcontext.regs[30]; + sc->sp = uc->uc_mcontext.sp; + sc->pc = uc->uc_mcontext.pc; + sc->pstate = uc->uc_mcontext.pstate; + + asm volatile ( + "mov sp, %0\n" + "ret %1\n" + : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) + ); + } + unreachable(); +#else + printf ("%s: implement me\n", __FUNCTION__); +#endif + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +static inline void +establish_machine_state (struct cursor *c) +{ + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_AARCH64_V31; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + as->acc.access_fpreg (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + as->acc.access_reg (as, reg, &val, 1, arg); + } + } +} + +PROTECTED int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + + Debug (1, "(cursor=%p)\n", c); + + if (!c->dwarf.ip) + { + /* This can happen easily when the frame-chain gets truncated + due to bad or missing unwind-info. */ + Debug (1, "refusing to resume execution at address 0\n"); + return -UNW_EINVAL; + } + + establish_machine_state (c); + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/libs/libunwind/aarch64/Gstash_frame.c b/src/libs/libunwind/aarch64/Gstash_frame.c new file mode 100644 index 0000000000..9c1a54d4ad --- /dev/null +++ b/src/libs/libunwind/aarch64/Gstash_frame.c @@ -0,0 +1,89 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY + Copyright (C) 2014 CERN and Aalto University + Contributed by Filip Nyback + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN void +tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) +{ + struct cursor *c = (struct cursor *) dwarf_to_cursor (d); + unw_tdep_frame_t *f = &c->frame_info; + + Debug (4, "ip=0x%lx cfa=0x%lx type %d cfa [where=%d val=%ld] cfaoff=%ld" + " ra=0x%lx fp [where=%d val=%ld @0x%lx] lr [where=%d val=%ld @0x%lx] " + "sp [where=%d val=%ld @0x%lx]\n", + d->ip, d->cfa, f->frame_type, + rs->reg[DWARF_CFA_REG_COLUMN].where, + rs->reg[DWARF_CFA_REG_COLUMN].val, + rs->reg[DWARF_CFA_OFF_COLUMN].val, + DWARF_GET_LOC(d->loc[d->ret_addr_column]), + rs->reg[FP].where, rs->reg[FP].val, DWARF_GET_LOC(d->loc[FP]), + rs->reg[LR].where, rs->reg[LR].val, DWARF_GET_LOC(d->loc[LR]), + rs->reg[SP].where, rs->reg[SP].val, DWARF_GET_LOC(d->loc[SP])); + + /* A standard frame is defined as: + - CFA is register-relative offset off FP or SP; + - Return address is saved in LR; + - FP is unsaved or saved at CFA+offset, offset != -1; + - LR is unsaved or saved at CFA+offset, offset != -1; + - SP is unsaved or saved at CFA+offset, offset != -1. */ + if (f->frame_type == UNW_AARCH64_FRAME_OTHER + && (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_REG) + && (rs->reg[DWARF_CFA_REG_COLUMN].val == FP + || rs->reg[DWARF_CFA_REG_COLUMN].val == SP) + && labs(rs->reg[DWARF_CFA_OFF_COLUMN].val) < (1 << 29) + && d->ret_addr_column == LR + && (rs->reg[FP].where == DWARF_WHERE_UNDEF + || rs->reg[FP].where == DWARF_WHERE_SAME + || (rs->reg[FP].where == DWARF_WHERE_CFAREL + && labs(rs->reg[FP].val) < (1 << 29) + && rs->reg[FP].val+1 != 0)) + && (rs->reg[LR].where == DWARF_WHERE_UNDEF + || rs->reg[LR].where == DWARF_WHERE_SAME + || (rs->reg[LR].where == DWARF_WHERE_CFAREL + && labs(rs->reg[LR].val) < (1 << 29) + && rs->reg[LR].val+1 != 0)) + && (rs->reg[SP].where == DWARF_WHERE_UNDEF + || rs->reg[SP].where == DWARF_WHERE_SAME + || (rs->reg[SP].where == DWARF_WHERE_CFAREL + && labs(rs->reg[SP].val) < (1 << 29) + && rs->reg[SP].val+1 != 0))) + { + /* Save information for a standard frame. */ + f->frame_type = UNW_AARCH64_FRAME_STANDARD; + f->cfa_reg_sp = (rs->reg[DWARF_CFA_REG_COLUMN].val == SP); + f->cfa_reg_offset = rs->reg[DWARF_CFA_OFF_COLUMN].val; + if (rs->reg[FP].where == DWARF_WHERE_CFAREL) + f->fp_cfa_offset = rs->reg[FP].val; + if (rs->reg[LR].where == DWARF_WHERE_CFAREL) + f->lr_cfa_offset = rs->reg[LR].val; + if (rs->reg[SP].where == DWARF_WHERE_CFAREL) + f->sp_cfa_offset = rs->reg[SP].val; + Debug (4, " standard frame\n"); + } + else + Debug (4, " unusual frame\n"); +} diff --git a/src/libs/libunwind/aarch64/Gstep.c b/src/libs/libunwind/aarch64/Gstep.c new file mode 100644 index 0000000000..0c35f986c4 --- /dev/null +++ b/src/libs/libunwind/aarch64/Gstep.c @@ -0,0 +1,131 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2011-2013 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +PROTECTED int +unw_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; + struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); + + if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) + return -UNW_EUNSPEC; + + ret = unw_is_signal_frame (cursor); + Debug(1, "unw_is_signal_frame()=%d\n", ret); + + /* Save the SP and PC to be able to return execution at this point + later in time (unw_resume). */ + c->sigcontext_sp = c->dwarf.cfa; + c->sigcontext_pc = c->dwarf.ip; + + if (ret) + { + c->sigcontext_format = AARCH64_SCF_LINUX_RT_SIGFRAME; + sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; + } + else + return -UNW_EUNSPEC; + + c->sigcontext_addr = sc_addr; + c->frame_info.frame_type = UNW_AARCH64_FRAME_SIGRETURN; + c->frame_info.cfa_reg_offset = sc_addr - sp_addr; + + /* Update the dwarf cursor. + Set the location of the registers to the corresponding addresses of the + uc_mcontext / sigcontext structure contents. */ + c->dwarf.loc[UNW_AARCH64_X0] = DWARF_LOC (sc_addr + LINUX_SC_X0_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X1] = DWARF_LOC (sc_addr + LINUX_SC_X1_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X2] = DWARF_LOC (sc_addr + LINUX_SC_X2_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X3] = DWARF_LOC (sc_addr + LINUX_SC_X3_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X4] = DWARF_LOC (sc_addr + LINUX_SC_X4_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X5] = DWARF_LOC (sc_addr + LINUX_SC_X5_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X6] = DWARF_LOC (sc_addr + LINUX_SC_X6_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X7] = DWARF_LOC (sc_addr + LINUX_SC_X7_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X8] = DWARF_LOC (sc_addr + LINUX_SC_X8_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X9] = DWARF_LOC (sc_addr + LINUX_SC_X9_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X10] = DWARF_LOC (sc_addr + LINUX_SC_X10_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X11] = DWARF_LOC (sc_addr + LINUX_SC_X11_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X12] = DWARF_LOC (sc_addr + LINUX_SC_X12_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X13] = DWARF_LOC (sc_addr + LINUX_SC_X13_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X14] = DWARF_LOC (sc_addr + LINUX_SC_X14_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X15] = DWARF_LOC (sc_addr + LINUX_SC_X15_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X16] = DWARF_LOC (sc_addr + LINUX_SC_X16_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X17] = DWARF_LOC (sc_addr + LINUX_SC_X17_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X18] = DWARF_LOC (sc_addr + LINUX_SC_X18_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X19] = DWARF_LOC (sc_addr + LINUX_SC_X19_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X20] = DWARF_LOC (sc_addr + LINUX_SC_X20_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X21] = DWARF_LOC (sc_addr + LINUX_SC_X21_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X22] = DWARF_LOC (sc_addr + LINUX_SC_X22_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X23] = DWARF_LOC (sc_addr + LINUX_SC_X23_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X24] = DWARF_LOC (sc_addr + LINUX_SC_X24_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X25] = DWARF_LOC (sc_addr + LINUX_SC_X25_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X26] = DWARF_LOC (sc_addr + LINUX_SC_X26_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X27] = DWARF_LOC (sc_addr + LINUX_SC_X27_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X28] = DWARF_LOC (sc_addr + LINUX_SC_X28_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X29] = DWARF_LOC (sc_addr + LINUX_SC_X29_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X30] = DWARF_LOC (sc_addr + LINUX_SC_X30_OFF, 0); + c->dwarf.loc[UNW_AARCH64_SP] = DWARF_LOC (sc_addr + LINUX_SC_SP_OFF, 0); + c->dwarf.loc[UNW_AARCH64_PC] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0); + c->dwarf.loc[UNW_AARCH64_PSTATE] = DWARF_LOC (sc_addr + LINUX_SC_PSTATE_OFF, 0); + + /* Set SP/CFA and PC/IP. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_SP], &c->dwarf.cfa); + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip); + + c->dwarf.pi_valid = 0; + + return 1; +} + +PROTECTED int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx))\n", + c, c->dwarf.ip, c->dwarf.cfa); + + /* Check if this is a signal frame. */ + if (unw_is_signal_frame (cursor)) + return unw_handle_signal_frame (cursor); + + ret = dwarf_step (&c->dwarf); + Debug(1, "dwarf_step()=%d\n", ret); + + if (unlikely (ret == -UNW_ESTOPUNWIND)) + return ret; + + if (unlikely (ret < 0)) + return 0; + + return (c->dwarf.ip == 0) ? 0 : 1; +} diff --git a/src/libs/libunwind/aarch64/Gtrace.c b/src/libs/libunwind/aarch64/Gtrace.c new file mode 100644 index 0000000000..c67faf0e35 --- /dev/null +++ b/src/libs/libunwind/aarch64/Gtrace.c @@ -0,0 +1,548 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY + Copyright (C) 2014 CERN and Aalto University + Contributed by Filip Nyback + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" +#include +#include + +#pragma weak pthread_once +#pragma weak pthread_key_create +#pragma weak pthread_getspecific +#pragma weak pthread_setspecific + +/* Initial hash table size. Table expands by 2 bits (times four). */ +#define HASH_MIN_BITS 14 + +typedef struct +{ + unw_tdep_frame_t *frames; + size_t log_size; + size_t used; + size_t dtor_count; /* Counts how many times our destructor has already + been called. */ +} unw_trace_cache_t; + +static const unw_tdep_frame_t empty_frame = { 0, UNW_AARCH64_FRAME_OTHER, -1, -1, 0, -1, -1, -1 }; +static define_lock (trace_init_lock); +static pthread_once_t trace_cache_once = PTHREAD_ONCE_INIT; +static sig_atomic_t trace_cache_once_happen; +static pthread_key_t trace_cache_key; +static struct mempool trace_cache_pool; +static __thread unw_trace_cache_t *tls_cache; +static __thread int tls_cache_destroyed; + +/* Free memory for a thread's trace cache. */ +static void +trace_cache_free (void *arg) +{ + unw_trace_cache_t *cache = arg; + if (++cache->dtor_count < PTHREAD_DESTRUCTOR_ITERATIONS) + { + /* Not yet our turn to get destroyed. Re-install ourselves into the key. */ + pthread_setspecific(trace_cache_key, cache); + Debug(5, "delayed freeing cache %p (%zx to go)\n", cache, + PTHREAD_DESTRUCTOR_ITERATIONS - cache->dtor_count); + return; + } + tls_cache_destroyed = 1; + tls_cache = NULL; + munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); + mempool_free (&trace_cache_pool, cache); + Debug(5, "freed cache %p\n", cache); +} + +/* Initialise frame tracing for threaded use. */ +static void +trace_cache_init_once (void) +{ + pthread_key_create (&trace_cache_key, &trace_cache_free); + mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); + trace_cache_once_happen = 1; +} + +static unw_tdep_frame_t * +trace_cache_buckets (size_t n) +{ + unw_tdep_frame_t *frames; + size_t i; + + GET_MEMORY(frames, n * sizeof (unw_tdep_frame_t)); + if (likely(frames != NULL)) + for (i = 0; i < n; ++i) + frames[i] = empty_frame; + + return frames; +} + +/* Allocate and initialise hash table for frame cache lookups. + Returns the cache initialised with (1u << HASH_LOW_BITS) hash + buckets, or NULL if there was a memory allocation problem. */ +static unw_trace_cache_t * +trace_cache_create (void) +{ + unw_trace_cache_t *cache; + + if (tls_cache_destroyed) + { + /* The current thread is in the process of exiting. Don't recreate + cache, as we wouldn't have another chance to free it. */ + Debug(5, "refusing to reallocate cache: " + "thread-locals are being deallocated\n"); + return NULL; + } + + if (! (cache = mempool_alloc(&trace_cache_pool))) + { + Debug(5, "failed to allocate cache\n"); + return NULL; + } + + if (! (cache->frames = trace_cache_buckets(1u << HASH_MIN_BITS))) + { + Debug(5, "failed to allocate buckets\n"); + mempool_free(&trace_cache_pool, cache); + return NULL; + } + + cache->log_size = HASH_MIN_BITS; + cache->used = 0; + cache->dtor_count = 0; + tls_cache_destroyed = 0; /* Paranoia: should already be 0. */ + Debug(5, "allocated cache %p\n", cache); + return cache; +} + +/* Expand the hash table in the frame cache if possible. This always + quadruples the hash size, and clears all previous frame entries. */ +static int +trace_cache_expand (unw_trace_cache_t *cache) +{ + size_t old_size = (1u << cache->log_size); + size_t new_log_size = cache->log_size + 2; + unw_tdep_frame_t *new_frames = trace_cache_buckets (1u << new_log_size); + + if (unlikely(! new_frames)) + { + Debug(5, "failed to expand cache to 2^%lu buckets\n", new_log_size); + return -UNW_ENOMEM; + } + + Debug(5, "expanded cache from 2^%lu to 2^%lu buckets\n", cache->log_size, new_log_size); + munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); + cache->frames = new_frames; + cache->log_size = new_log_size; + cache->used = 0; + return 0; +} + +static unw_trace_cache_t * +trace_cache_get_unthreaded (void) +{ + unw_trace_cache_t *cache; + intrmask_t saved_mask; + static unw_trace_cache_t *global_cache = NULL; + lock_acquire (&trace_init_lock, saved_mask); + if (! global_cache) + { + mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); + global_cache = trace_cache_create (); + } + cache = global_cache; + lock_release (&trace_init_lock, saved_mask); + Debug(5, "using cache %p\n", cache); + return cache; +} + +/* Get the frame cache for the current thread. Create it if there is none. */ +static unw_trace_cache_t * +trace_cache_get (void) +{ + unw_trace_cache_t *cache; + if (likely (pthread_once != NULL)) + { + pthread_once(&trace_cache_once, &trace_cache_init_once); + if (!trace_cache_once_happen) + { + return trace_cache_get_unthreaded(); + } + if (! (cache = tls_cache)) + { + cache = trace_cache_create(); + pthread_setspecific(trace_cache_key, cache); + tls_cache = cache; + } + Debug(5, "using cache %p\n", cache); + return cache; + } + else + { + return trace_cache_get_unthreaded(); + } +} + +/* Initialise frame properties for address cache slot F at address + PC using current CFA, FP and SP values. Modifies CURSOR to + that location, performs one unw_step(), and fills F with what + was discovered about the location. Returns F. + + FIXME: This probably should tell DWARF handling to never evaluate + or use registers other than FP, SP and PC in case there is + highly unusual unwind info which uses these creatively. */ +static unw_tdep_frame_t * +trace_init_addr (unw_tdep_frame_t *f, + unw_cursor_t *cursor, + unw_word_t cfa, + unw_word_t pc, + unw_word_t fp, + unw_word_t sp) +{ + struct cursor *c = (struct cursor *) cursor; + struct dwarf_cursor *d = &c->dwarf; + int ret = -UNW_EINVAL; + + /* Initialise frame properties: unknown, not last. */ + f->virtual_address = pc; + f->frame_type = UNW_AARCH64_FRAME_OTHER; + f->last_frame = 0; + f->cfa_reg_sp = -1; + f->cfa_reg_offset = 0; + f->fp_cfa_offset = -1; + f->lr_cfa_offset = -1; + f->sp_cfa_offset = -1; + + /* Reinitialise cursor to this instruction - but undo next/prev PC + adjustment because unw_step will redo it - and force PC, FP and + SP into register locations (=~ ucontext we keep), then set + their desired values. Then perform the step. */ + d->ip = pc + d->use_prev_instr; + d->cfa = cfa; + d->loc[UNW_AARCH64_X29] = DWARF_REG_LOC (d, UNW_AARCH64_X29); + d->loc[UNW_AARCH64_SP] = DWARF_REG_LOC (d, UNW_AARCH64_SP); + d->loc[UNW_AARCH64_PC] = DWARF_REG_LOC (d, UNW_AARCH64_PC); + c->frame_info = *f; + + if (likely(dwarf_put (d, d->loc[UNW_AARCH64_X29], fp) >= 0) + && likely(dwarf_put (d, d->loc[UNW_AARCH64_SP], sp) >= 0) + && likely(dwarf_put (d, d->loc[UNW_AARCH64_PC], pc) >= 0) + && likely((ret = unw_step (cursor)) >= 0)) + *f = c->frame_info; + + /* If unw_step() stopped voluntarily, remember that, even if it + otherwise could not determine anything useful. This avoids + failing trace if we hit frames without unwind info, which is + common for the outermost frame (CRT stuff) on many systems. + This avoids failing trace in very common circumstances; failing + to unw_step() loop wouldn't produce any better result. */ + if (ret == 0) + f->last_frame = -1; + + Debug (3, "frame va %lx type %d last %d cfa %s+%d fp @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n", + f->virtual_address, f->frame_type, f->last_frame, + f->cfa_reg_sp ? "sp" : "fp", f->cfa_reg_offset, + f->fp_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset); + + return f; +} + +/* Look up and if necessary fill in frame attributes for address PC + in CACHE using current CFA, FP and SP values. Uses CURSOR to + perform any unwind steps necessary to fill the cache. Returns the + frame cache slot which describes RIP. */ +static unw_tdep_frame_t * +trace_lookup (unw_cursor_t *cursor, + unw_trace_cache_t *cache, + unw_word_t cfa, + unw_word_t pc, + unw_word_t fp, + unw_word_t sp) +{ + /* First look up for previously cached information using cache as + linear probing hash table with probe step of 1. Majority of + lookups should be completed within few steps, but it is very + important the hash table does not fill up, or performance falls + off the cliff. */ + uint64_t i, addr; + uint64_t cache_size = 1u << cache->log_size; + uint64_t slot = ((pc * 0x9e3779b97f4a7c16) >> 43) & (cache_size-1); + unw_tdep_frame_t *frame; + + for (i = 0; i < 16; ++i) + { + frame = &cache->frames[slot]; + addr = frame->virtual_address; + + /* Return if we found the address. */ + if (likely(addr == pc)) + { + Debug (4, "found address after %ld steps\n", i); + return frame; + } + + /* If slot is empty, reuse it. */ + if (likely(! addr)) + break; + + /* Linear probe to next slot candidate, step = 1. */ + if (++slot >= cache_size) + slot -= cache_size; + } + + /* If we collided after 16 steps, or if the hash is more than half + full, force the hash to expand. Fill the selected slot, whether + it's free or collides. Note that hash expansion drops previous + contents; further lookups will refill the hash. */ + Debug (4, "updating slot %lu after %ld steps, replacing 0x%lx\n", slot, i, addr); + if (unlikely(addr || cache->used >= cache_size / 2)) + { + if (unlikely(trace_cache_expand (cache) < 0)) + return NULL; + + cache_size = 1u << cache->log_size; + slot = ((pc * 0x9e3779b97f4a7c16) >> 43) & (cache_size-1); + frame = &cache->frames[slot]; + addr = frame->virtual_address; + } + + if (! addr) + ++cache->used; + + return trace_init_addr (frame, cursor, cfa, pc, fp, sp); +} + +/* Fast stack backtrace for AArch64. + + This is used by backtrace() implementation to accelerate frequent + queries for current stack, without any desire to unwind. It fills + BUFFER with the call tree from CURSOR upwards for at most SIZE + stack levels. The first frame, backtrace itself, is omitted. When + called, SIZE should give the maximum number of entries that can be + stored into BUFFER. Uses an internal thread-specific cache to + accelerate queries. + + The caller should fall back to a unw_step() loop if this function + fails by returning -UNW_ESTOPUNWIND, meaning the routine hit a + stack frame that is too complex to be traced in the fast path. + + This function is tuned for clients which only need to walk the + stack to get the call tree as fast as possible but without any + other details, for example profilers sampling the stack thousands + to millions of times per second. The routine handles the most + common AArch64 ABI stack layouts: CFA is FP or SP plus/minus + constant offset, return address is in LR, and FP, LR and SP are + either unchanged or saved on stack at constant offset from the CFA; + the signal return frame; and frames without unwind info provided + they are at the outermost (final) frame or can conservatively be + assumed to be frame-pointer based. + + Any other stack layout will cause the routine to give up. There + are only a handful of relatively rarely used functions which do + not have a stack in the standard form: vfork, longjmp, setcontext + and _dl_runtime_profile on common linux systems for example. + + On success BUFFER and *SIZE reflect the trace progress up to *SIZE + stack levels or the outermost frame, which ever is less. It may + stop short of outermost frame if unw_step() loop would also do so, + e.g. if there is no more unwind information; this is not reported + as an error. + + The function returns a negative value for errors, -UNW_ESTOPUNWIND + if tracing stopped because of an unusual frame unwind info. The + BUFFER and *SIZE reflect tracing progress up to the error frame. + + Callers of this function would normally look like this: + + unw_cursor_t cur; + unw_context_t ctx; + void addrs[128]; + int depth = 128; + int ret; + + unw_getcontext(&ctx); + unw_init_local(&cur, &ctx); + if ((ret = unw_tdep_trace(&cur, addrs, &depth)) < 0) + { + depth = 0; + unw_getcontext(&ctx); + unw_init_local(&cur, &ctx); + while ((ret = unw_step(&cur)) > 0 && depth < 128) + { + unw_word_t ip; + unw_get_reg(&cur, UNW_REG_IP, &ip); + addresses[depth++] = (void *) ip; + } + } +*/ +HIDDEN int +tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) +{ + struct cursor *c = (struct cursor *) cursor; + struct dwarf_cursor *d = &c->dwarf; + unw_trace_cache_t *cache; + unw_word_t fp, sp, pc, cfa, lr; + int maxdepth = 0; + int depth = 0; + int ret; + + /* Check input parametres. */ + if (unlikely(! cursor || ! buffer || ! size || (maxdepth = *size) <= 0)) + return -UNW_EINVAL; + + Debug (1, "begin ip 0x%lx cfa 0x%lx\n", d->ip, d->cfa); + + /* Tell core dwarf routines to call back to us. */ + d->stash_frames = 1; + + /* Determine initial register values. These are direct access safe + because we know they come from the initial machine context. */ + pc = d->ip; + sp = cfa = d->cfa; + ACCESS_MEM_FAST(ret, 0, d, DWARF_GET_LOC(d->loc[UNW_AARCH64_X29]), fp); + assert(ret == 0); + lr = 0; + + /* Get frame cache. */ + if (unlikely(! (cache = trace_cache_get()))) + { + Debug (1, "returning %d, cannot get trace cache\n", -UNW_ENOMEM); + *size = 0; + d->stash_frames = 0; + return -UNW_ENOMEM; + } + + /* Trace the stack upwards, starting from current RIP. Adjust + the RIP address for previous/next instruction as the main + unwinding logic would also do. We undo this before calling + back into unw_step(). */ + while (depth < maxdepth) + { + pc -= d->use_prev_instr; + Debug (2, "depth %d cfa 0x%lx pc 0x%lx sp 0x%lx fp 0x%lx\n", + depth, cfa, pc, sp, fp); + + /* See if we have this address cached. If not, evaluate enough of + the dwarf unwind information to fill the cache line data, or to + decide this frame cannot be handled in fast trace mode. We + cache negative results too to prevent unnecessary dwarf parsing + for common failures. */ + unw_tdep_frame_t *f = trace_lookup (cursor, cache, cfa, pc, fp, sp); + + /* If we don't have information for this frame, give up. */ + if (unlikely(! f)) + { + ret = -UNW_ENOINFO; + break; + } + + Debug (3, "frame va %lx type %d last %d cfa %s+%d fp @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n", + f->virtual_address, f->frame_type, f->last_frame, + f->cfa_reg_sp ? "sp" : "fp", f->cfa_reg_offset, + f->fp_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset); + + assert (f->virtual_address == pc); + + /* Stop if this was the last frame. In particular don't evaluate + new register values as it may not be safe - we don't normally + run with full validation on, and do not want to - and there's + enough bad unwind info floating around that we need to trust + what unw_step() previously said, in potentially bogus frames. */ + if (f->last_frame) + break; + + /* Evaluate CFA and registers for the next frame. */ + switch (f->frame_type) + { + case UNW_AARCH64_FRAME_GUESSED: + /* Fall thru to standard processing after forcing validation. */ + c->validate = 1; + + case UNW_AARCH64_FRAME_STANDARD: + /* Advance standard traceable frame. */ + cfa = (f->cfa_reg_sp ? sp : fp) + f->cfa_reg_offset; + if (likely(f->lr_cfa_offset != -1)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->lr_cfa_offset, pc); + else if (lr != 0) + { + /* Use the saved link register as the new pc. */ + pc = lr; + lr = 0; + } + if (likely(ret >= 0) && likely(f->fp_cfa_offset != -1)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->fp_cfa_offset, fp); + + /* Don't bother reading SP from DWARF, CFA becomes new SP. */ + sp = cfa; + + /* Next frame needs to back up for unwind info lookup. */ + d->use_prev_instr = 1; + break; + + case UNW_AARCH64_FRAME_SIGRETURN: + cfa = cfa + f->cfa_reg_offset; /* cfa now points to ucontext_t. */ + + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_PC_OFF, pc); + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_X29_OFF, fp); + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_SP_OFF, sp); + /* Save the link register here in case we end up in a function that + doesn't save the link register in the prologue, e.g. kill. */ + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_X30_OFF, lr); + + /* Resume stack at signal restoration point. The stack is not + necessarily continuous here, especially with sigaltstack(). */ + cfa = sp; + + /* Next frame should not back up. */ + d->use_prev_instr = 0; + break; + + default: + /* We cannot trace through this frame, give up and tell the + caller we had to stop. Data collected so far may still be + useful to the caller, so let it know how far we got. */ + ret = -UNW_ESTOPUNWIND; + break; + } + + Debug (4, "new cfa 0x%lx pc 0x%lx sp 0x%lx fp 0x%lx\n", + cfa, pc, sp, fp); + + /* If we failed or ended up somewhere bogus, stop. */ + if (unlikely(ret < 0 || pc < 0x4000)) + break; + + /* Record this address in stack trace. We skipped the first address. */ + buffer[depth++] = (void *) (pc - d->use_prev_instr); + } + +#if UNW_DEBUG + Debug (1, "returning %d, depth %d\n", ret, depth); +#endif + *size = depth; + return ret; +} diff --git a/src/libs/libunwind/aarch64/Lcreate_addr_space.c b/src/libs/libunwind/aarch64/Lcreate_addr_space.c new file mode 100644 index 0000000000..0f2dc6be90 --- /dev/null +++ b/src/libs/libunwind/aarch64/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/libs/libunwind/aarch64/Lget_proc_info.c b/src/libs/libunwind/aarch64/Lget_proc_info.c new file mode 100644 index 0000000000..69028b019f --- /dev/null +++ b/src/libs/libunwind/aarch64/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/libs/libunwind/aarch64/Lget_save_loc.c b/src/libs/libunwind/aarch64/Lget_save_loc.c new file mode 100644 index 0000000000..9ea048a907 --- /dev/null +++ b/src/libs/libunwind/aarch64/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/libs/libunwind/aarch64/Lglobal.c b/src/libs/libunwind/aarch64/Lglobal.c new file mode 100644 index 0000000000..6d7b489e14 --- /dev/null +++ b/src/libs/libunwind/aarch64/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/libs/libunwind/aarch64/Linit.c b/src/libs/libunwind/aarch64/Linit.c new file mode 100644 index 0000000000..e9abfdd46a --- /dev/null +++ b/src/libs/libunwind/aarch64/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/libs/libunwind/aarch64/Linit_local.c b/src/libs/libunwind/aarch64/Linit_local.c new file mode 100644 index 0000000000..68a1687e85 --- /dev/null +++ b/src/libs/libunwind/aarch64/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/libs/libunwind/aarch64/Linit_remote.c b/src/libs/libunwind/aarch64/Linit_remote.c new file mode 100644 index 0000000000..58cb04ab7c --- /dev/null +++ b/src/libs/libunwind/aarch64/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/libs/libunwind/aarch64/Lis_signal_frame.c b/src/libs/libunwind/aarch64/Lis_signal_frame.c new file mode 100644 index 0000000000..b9a7c4f51a --- /dev/null +++ b/src/libs/libunwind/aarch64/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/libs/libunwind/aarch64/Lregs.c b/src/libs/libunwind/aarch64/Lregs.c new file mode 100644 index 0000000000..2c9c75cd7d --- /dev/null +++ b/src/libs/libunwind/aarch64/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/libs/libunwind/aarch64/Lresume.c b/src/libs/libunwind/aarch64/Lresume.c new file mode 100644 index 0000000000..41a8cf003d --- /dev/null +++ b/src/libs/libunwind/aarch64/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/libs/libunwind/aarch64/Lstash_frame.c b/src/libs/libunwind/aarch64/Lstash_frame.c new file mode 100644 index 0000000000..77587803d0 --- /dev/null +++ b/src/libs/libunwind/aarch64/Lstash_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstash_frame.c" +#endif diff --git a/src/libs/libunwind/aarch64/Lstep.c b/src/libs/libunwind/aarch64/Lstep.c new file mode 100644 index 0000000000..c1ac3c7547 --- /dev/null +++ b/src/libs/libunwind/aarch64/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/libs/libunwind/aarch64/Ltrace.c b/src/libs/libunwind/aarch64/Ltrace.c new file mode 100644 index 0000000000..fcd3f239c9 --- /dev/null +++ b/src/libs/libunwind/aarch64/Ltrace.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gtrace.c" +#endif diff --git a/src/libs/libunwind/aarch64/gen-offsets.c b/src/libs/libunwind/aarch64/gen-offsets.c new file mode 100644 index 0000000000..eadc2377d8 --- /dev/null +++ b/src/libs/libunwind/aarch64/gen-offsets.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +#define UC(N,X) \ + printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) + +#define SC(N,X) \ + printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) + +int +main (void) +{ + printf ( +"/* Linux-specific definitions: */\n\n" + +"/* Define various structure offsets to simplify cross-compilation. */\n\n" + +"/* Offsets for AArch64 Linux \"ucontext_t\": */\n\n"); + + UC ("FLAGS", uc_flags); + UC ("LINK", uc_link); + UC ("STACK", uc_stack); + UC ("MCONTEXT", uc_mcontext); + UC ("SIGMASK", uc_sigmask); + + printf ("\n/* Offsets for AArch64 Linux \"struct sigcontext\": */\n\n"); + + SC ("R0", regs[0]); + SC ("R1", regs[1]); + SC ("R2", regs[2]); + SC ("R3", regs[3]); + SC ("R4", regs[4]); + SC ("R5", regs[5]); + SC ("R6", regs[6]); + SC ("R7", regs[7]); + SC ("R8", regs[8]); + SC ("R9", regs[9]); + SC ("R10", regs[10]); + SC ("R11", regs[11]); + SC ("R12", regs[12]); + SC ("R13", regs[13]); + SC ("R14", regs[14]); + SC ("R15", regs[15]); + SC ("R16", regs[16]); + SC ("R17", regs[17]); + SC ("R18", regs[18]); + SC ("R19", regs[19]); + SC ("R20", regs[20]); + SC ("R21", regs[21]); + SC ("R22", regs[22]); + SC ("R23", regs[23]); + SC ("R24", regs[24]); + SC ("R25", regs[25]); + SC ("R26", regs[26]); + SC ("R27", regs[27]); + SC ("R28", regs[28]); + SC ("R29", regs[29]); + SC ("R30", regs[30]); + SC ("R31", regs[31]); + + SC ("PC", pc); + SC ("SP", sp); + SC ("Fault", fault_address); + SC ("state", pstate); + return 0; +} diff --git a/src/libs/libunwind/aarch64/getcontext.S b/src/libs/libunwind/aarch64/getcontext.S new file mode 100644 index 0000000000..25ed5b66be --- /dev/null +++ b/src/libs/libunwind/aarch64/getcontext.S @@ -0,0 +1,52 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 Google, Inc + Contributed by Paul Pluzhnikov + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" + +/* int _Uaarch64_getcontext_trace (unw_tdep_context_t *ucp) + + Saves limited machine context in UCP necessary for fast trace. If fast trace + fails, caller will have to get the full context. +*/ + + .global _Uaarch64_getcontext_trace + .hidden _Uaarch64_getcontext_trace + .type _Uaarch64_getcontext_trace, @function +_Uaarch64_getcontext_trace: + .cfi_startproc + + /* Save only FP, SP, PC - exclude this call. */ + str x29, [x0, #(LINUX_UC_MCONTEXT_OFF + LINUX_SC_X29_OFF)] + mov x9, sp + str x9, [x0, #(LINUX_UC_MCONTEXT_OFF + LINUX_SC_SP_OFF)] + str x30, [x0, #(LINUX_UC_MCONTEXT_OFF + LINUX_SC_PC_OFF)] + + ret + .cfi_endproc + .size _Uaarch64_getcontext_trace, . - _Uaarch64_getcontext_trace + + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/libs/libunwind/aarch64/init.h b/src/libs/libunwind/aarch64/init.h new file mode 100644 index 0000000000..0cedc1af2a --- /dev/null +++ b/src/libs/libunwind/aarch64/init.h @@ -0,0 +1,127 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret, i; + + c->dwarf.loc[UNW_AARCH64_X0] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X0); + c->dwarf.loc[UNW_AARCH64_X1] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X1); + c->dwarf.loc[UNW_AARCH64_X2] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X2); + c->dwarf.loc[UNW_AARCH64_X3] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X3); + c->dwarf.loc[UNW_AARCH64_X4] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X4); + c->dwarf.loc[UNW_AARCH64_X5] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X5); + c->dwarf.loc[UNW_AARCH64_X6] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X6); + c->dwarf.loc[UNW_AARCH64_X7] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X7); + c->dwarf.loc[UNW_AARCH64_X8] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X8); + c->dwarf.loc[UNW_AARCH64_X9] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X9); + c->dwarf.loc[UNW_AARCH64_X10] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X10); + c->dwarf.loc[UNW_AARCH64_X11] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X11); + c->dwarf.loc[UNW_AARCH64_X12] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X12); + c->dwarf.loc[UNW_AARCH64_X13] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X13); + c->dwarf.loc[UNW_AARCH64_X14] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X14); + c->dwarf.loc[UNW_AARCH64_X15] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X15); + c->dwarf.loc[UNW_AARCH64_X16] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X16); + c->dwarf.loc[UNW_AARCH64_X17] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X17); + c->dwarf.loc[UNW_AARCH64_X18] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X18); + c->dwarf.loc[UNW_AARCH64_X19] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X19); + c->dwarf.loc[UNW_AARCH64_X20] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X20); + c->dwarf.loc[UNW_AARCH64_X21] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X21); + c->dwarf.loc[UNW_AARCH64_X22] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X22); + c->dwarf.loc[UNW_AARCH64_X23] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X23); + c->dwarf.loc[UNW_AARCH64_X24] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X24); + c->dwarf.loc[UNW_AARCH64_X25] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X25); + c->dwarf.loc[UNW_AARCH64_X26] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X26); + c->dwarf.loc[UNW_AARCH64_X27] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X27); + c->dwarf.loc[UNW_AARCH64_X28] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X28); + c->dwarf.loc[UNW_AARCH64_X29] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X29); + c->dwarf.loc[UNW_AARCH64_X30] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X30); + c->dwarf.loc[UNW_AARCH64_SP] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_SP); + c->dwarf.loc[UNW_AARCH64_PC] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_PC); + c->dwarf.loc[UNW_AARCH64_PSTATE] = DWARF_REG_LOC (&c->dwarf, + UNW_AARCH64_PSTATE); + c->dwarf.loc[UNW_AARCH64_V0] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V0); + c->dwarf.loc[UNW_AARCH64_V1] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V1); + c->dwarf.loc[UNW_AARCH64_V2] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V2); + c->dwarf.loc[UNW_AARCH64_V3] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V3); + c->dwarf.loc[UNW_AARCH64_V4] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V4); + c->dwarf.loc[UNW_AARCH64_V5] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V5); + c->dwarf.loc[UNW_AARCH64_V6] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V6); + c->dwarf.loc[UNW_AARCH64_V7] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V7); + c->dwarf.loc[UNW_AARCH64_V8] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V8); + c->dwarf.loc[UNW_AARCH64_V9] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V9); + c->dwarf.loc[UNW_AARCH64_V10] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V10); + c->dwarf.loc[UNW_AARCH64_V11] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V11); + c->dwarf.loc[UNW_AARCH64_V12] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V12); + c->dwarf.loc[UNW_AARCH64_V13] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V13); + c->dwarf.loc[UNW_AARCH64_V14] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V14); + c->dwarf.loc[UNW_AARCH64_V15] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V15); + c->dwarf.loc[UNW_AARCH64_V16] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V16); + c->dwarf.loc[UNW_AARCH64_V17] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V17); + c->dwarf.loc[UNW_AARCH64_V18] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V18); + c->dwarf.loc[UNW_AARCH64_V19] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V19); + c->dwarf.loc[UNW_AARCH64_V20] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V20); + c->dwarf.loc[UNW_AARCH64_V21] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V21); + c->dwarf.loc[UNW_AARCH64_V22] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V22); + c->dwarf.loc[UNW_AARCH64_V23] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V23); + c->dwarf.loc[UNW_AARCH64_V24] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V24); + c->dwarf.loc[UNW_AARCH64_V25] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V25); + c->dwarf.loc[UNW_AARCH64_V26] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V26); + c->dwarf.loc[UNW_AARCH64_V27] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V27); + c->dwarf.loc[UNW_AARCH64_V28] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V28); + c->dwarf.loc[UNW_AARCH64_V29] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V29); + c->dwarf.loc[UNW_AARCH64_V30] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V30); + c->dwarf.loc[UNW_AARCH64_V31] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V31); + + for (i = UNW_AARCH64_PSTATE + 1; i < UNW_AARCH64_V0; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_SP], &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = AARCH64_SCF_NONE; + c->sigcontext_addr = 0; + c->sigcontext_sp = 0; + c->sigcontext_pc = 0; + + c->dwarf.args_size = 0; + c->dwarf.ret_addr_column = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/libs/libunwind/aarch64/is_fpreg.c b/src/libs/libunwind/aarch64/is_fpreg.c new file mode 100644 index 0000000000..7c32693281 --- /dev/null +++ b/src/libs/libunwind/aarch64/is_fpreg.c @@ -0,0 +1,32 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED int +unw_is_fpreg (int regnum) +{ + return (regnum >= UNW_AARCH64_V0 && regnum <= UNW_AARCH64_V31); +} diff --git a/src/libs/libunwind/aarch64/offsets.h b/src/libs/libunwind/aarch64/offsets.h new file mode 100644 index 0000000000..e78251d0a8 --- /dev/null +++ b/src/libs/libunwind/aarch64/offsets.h @@ -0,0 +1,49 @@ +/* Linux-specific definitions: */ + +/* Define various structure offsets to simplify cross-compilation. */ + +/* Offsets for AArch64 Linux "ucontext_t": */ + +#define LINUX_UC_FLAGS_OFF 0x0 +#define LINUX_UC_LINK_OFF 0x8 +#define LINUX_UC_STACK_OFF 0x10 +#define LINUX_UC_SIGMASK_OFF 0x28 +#define LINUX_UC_MCONTEXT_OFF 0xb0 + +/* Offsets for AArch64 Linux "struct sigcontext": */ + +#define LINUX_SC_FAULTADDRESS_OFF 0x00 +#define LINUX_SC_X0_OFF 0x008 +#define LINUX_SC_X1_OFF 0x010 +#define LINUX_SC_X2_OFF 0x018 +#define LINUX_SC_X3_OFF 0x020 +#define LINUX_SC_X4_OFF 0x028 +#define LINUX_SC_X5_OFF 0x030 +#define LINUX_SC_X6_OFF 0x038 +#define LINUX_SC_X7_OFF 0x040 +#define LINUX_SC_X8_OFF 0x048 +#define LINUX_SC_X9_OFF 0x050 +#define LINUX_SC_X10_OFF 0x058 +#define LINUX_SC_X11_OFF 0x060 +#define LINUX_SC_X12_OFF 0x068 +#define LINUX_SC_X13_OFF 0x070 +#define LINUX_SC_X14_OFF 0x078 +#define LINUX_SC_X15_OFF 0x080 +#define LINUX_SC_X16_OFF 0x088 +#define LINUX_SC_X17_OFF 0x090 +#define LINUX_SC_X18_OFF 0x098 +#define LINUX_SC_X19_OFF 0x0a0 +#define LINUX_SC_X20_OFF 0x0a8 +#define LINUX_SC_X21_OFF 0x0b0 +#define LINUX_SC_X22_OFF 0x0b8 +#define LINUX_SC_X23_OFF 0x0c0 +#define LINUX_SC_X24_OFF 0x0c8 +#define LINUX_SC_X25_OFF 0x0d0 +#define LINUX_SC_X26_OFF 0x0d8 +#define LINUX_SC_X27_OFF 0x0e0 +#define LINUX_SC_X28_OFF 0x0e8 +#define LINUX_SC_X29_OFF 0x0f0 +#define LINUX_SC_X30_OFF 0x0f8 +#define LINUX_SC_SP_OFF 0x100 +#define LINUX_SC_PC_OFF 0x108 +#define LINUX_SC_PSTATE_OFF 0x110 diff --git a/src/libs/libunwind/aarch64/regname.c b/src/libs/libunwind/aarch64/regname.c new file mode 100644 index 0000000000..8c9734285d --- /dev/null +++ b/src/libs/libunwind/aarch64/regname.c @@ -0,0 +1,106 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *const regname[] = + { + [UNW_AARCH64_X0] = "x0", + [UNW_AARCH64_X1] = "x1", + [UNW_AARCH64_X2] = "x2", + [UNW_AARCH64_X3] = "x3", + [UNW_AARCH64_X4] = "x4", + [UNW_AARCH64_X5] = "x5", + [UNW_AARCH64_X6] = "x6", + [UNW_AARCH64_X7] = "x7", + [UNW_AARCH64_X8] = "x8", + [UNW_AARCH64_X9] = "x9", + [UNW_AARCH64_X10] = "x10", + [UNW_AARCH64_X11] = "x11", + [UNW_AARCH64_X12] = "x12", + [UNW_AARCH64_X13] = "x13", + [UNW_AARCH64_X14] = "x14", + [UNW_AARCH64_X15] = "x15", + [UNW_AARCH64_X16] = "ip0", + [UNW_AARCH64_X17] = "ip1", + [UNW_AARCH64_X18] = "x18", + [UNW_AARCH64_X19] = "x19", + [UNW_AARCH64_X20] = "x20", + [UNW_AARCH64_X21] = "x21", + [UNW_AARCH64_X22] = "x22", + [UNW_AARCH64_X23] = "x23", + [UNW_AARCH64_X24] = "x24", + [UNW_AARCH64_X25] = "x25", + [UNW_AARCH64_X26] = "x26", + [UNW_AARCH64_X27] = "x27", + [UNW_AARCH64_X28] = "x28", + [UNW_AARCH64_X29] = "fp", + [UNW_AARCH64_X30] = "lr", + [UNW_AARCH64_SP] = "sp", + [UNW_AARCH64_PC] = "pc", + [UNW_AARCH64_V0] = "v0", + [UNW_AARCH64_V1] = "v1", + [UNW_AARCH64_V2] = "v2", + [UNW_AARCH64_V3] = "v3", + [UNW_AARCH64_V4] = "v4", + [UNW_AARCH64_V5] = "v5", + [UNW_AARCH64_V6] = "v6", + [UNW_AARCH64_V7] = "v7", + [UNW_AARCH64_V8] = "v8", + [UNW_AARCH64_V9] = "v9", + [UNW_AARCH64_V10] = "v10", + [UNW_AARCH64_V11] = "v11", + [UNW_AARCH64_V12] = "v12", + [UNW_AARCH64_V13] = "v13", + [UNW_AARCH64_V14] = "v14", + [UNW_AARCH64_V15] = "v15", + [UNW_AARCH64_V16] = "v16", + [UNW_AARCH64_V17] = "v17", + [UNW_AARCH64_V18] = "v18", + [UNW_AARCH64_V19] = "v19", + [UNW_AARCH64_V20] = "v20", + [UNW_AARCH64_V21] = "v21", + [UNW_AARCH64_V22] = "v22", + [UNW_AARCH64_V23] = "v23", + [UNW_AARCH64_V24] = "v24", + [UNW_AARCH64_V25] = "v25", + [UNW_AARCH64_V26] = "v26", + [UNW_AARCH64_V27] = "v27", + [UNW_AARCH64_V28] = "v28", + [UNW_AARCH64_V29] = "v29", + [UNW_AARCH64_V30] = "v30", + [UNW_AARCH64_V31] = "v31", + [UNW_AARCH64_FPSR] = "fpsr", + [UNW_AARCH64_FPCR] = "fpcr", + }; + +PROTECTED const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname) && regname[reg] != NULL) + return regname[reg]; + else + return "???"; +} diff --git a/src/libs/libunwind/aarch64/siglongjmp.S b/src/libs/libunwind/aarch64/siglongjmp.S new file mode 100644 index 0000000000..9985c4b4aa --- /dev/null +++ b/src/libs/libunwind/aarch64/siglongjmp.S @@ -0,0 +1,12 @@ + /* Dummy implementation for now. */ + + .global _UI_siglongjmp_cont + .global _UI_longjmp_cont + +_UI_siglongjmp_cont: +_UI_longjmp_cont: + ret +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",%progbits +#endif diff --git a/src/libs/libunwind/aarch64/unwind_i.h b/src/libs/libunwind/aarch64/unwind_i.h new file mode 100644 index 0000000000..3d324c2b08 --- /dev/null +++ b/src/libs/libunwind/aarch64/unwind_i.h @@ -0,0 +1,64 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include + +#include + +#include "libunwind_i.h" + +/* DWARF column numbers for AArch64: */ +#define X29 29 +#define FP 29 +#define X30 30 +#define LR 30 +#define SP 31 + +#define aarch64_lock UNW_OBJ(lock) +#define aarch64_local_resume UNW_OBJ(local_resume) +#define aarch64_local_addr_space_init UNW_OBJ(local_addr_space_init) + +extern void aarch64_local_addr_space_init (void); +extern int aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); + +/* By-pass calls to access_mem() when known to be safe. */ +#ifdef UNW_LOCAL_ONLY +# undef ACCESS_MEM_FAST +# define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \ + do { \ + if (unlikely(validate)) \ + (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); \ + else \ + (ret) = 0, (to) = *(unw_word_t *)(addr); \ + } while (0) +#endif + +#define GET_FPCTX(uc) ((struct fpsimd_context *)(&uc->uc_mcontext.__reserved)) + +#endif /* unwind_i_h */ diff --git a/src/libs/libunwind/arm/Gcreate_addr_space.c b/src/libs/libunwind/arm/Gcreate_addr_space.c new file mode 100644 index 0000000000..4d59a20a7e --- /dev/null +++ b/src/libs/libunwind/arm/Gcreate_addr_space.c @@ -0,0 +1,60 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +PROTECTED unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * ARM supports little-endian and big-endian. + */ + if (byte_order != 0 && byte_order != __LITTLE_ENDIAN + && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + /* Default to little-endian for ARM. */ + if (byte_order == 0 || byte_order == __LITTLE_ENDIAN) + as->big_endian = 0; + else + as->big_endian = 1; + + return as; +#endif +} diff --git a/src/libs/libunwind/arm/Gex_tables.c b/src/libs/libunwind/arm/Gex_tables.c new file mode 100644 index 0000000000..34706cf416 --- /dev/null +++ b/src/libs/libunwind/arm/Gex_tables.c @@ -0,0 +1,569 @@ +/* libunwind - a platform-independent unwind library + Copyright 2011 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* This file contains functionality for parsing and interpreting the ARM +specific unwind information. Documentation about the exception handling +ABI for the ARM architecture can be found at: +http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038a/IHI0038A_ehabi.pdf +*/ + +#include "libunwind_i.h" + +#define ARM_EXBUF_START(x) (((x) >> 4) & 0x0f) +#define ARM_EXBUF_COUNT(x) ((x) & 0x0f) +#define ARM_EXBUF_END(x) (ARM_EXBUF_START(x) + ARM_EXBUF_COUNT(x)) + +#define ARM_EXIDX_CANT_UNWIND 0x00000001 +#define ARM_EXIDX_COMPACT 0x80000000 + +#define ARM_EXTBL_OP_FINISH 0xb0 + +enum arm_exbuf_cmd_flags { + ARM_EXIDX_VFP_SHIFT_16 = 1 << 16, + ARM_EXIDX_VFP_DOUBLE = 1 << 17, +}; + +struct arm_cb_data + { + /* in: */ + unw_word_t ip; /* instruction-pointer we're looking for */ + unw_proc_info_t *pi; /* proc-info pointer */ + /* out: */ + unw_dyn_info_t di; /* info about the ARM exidx segment */ + }; + +static inline uint32_t CONST_ATTR +prel31_read (uint32_t prel31) +{ + return ((int32_t)prel31 << 1) >> 1; +} + +static inline int +prel31_to_addr (unw_addr_space_t as, void *arg, unw_word_t prel31, + unw_word_t *val) +{ + unw_word_t offset; + + if ((*as->acc.access_mem)(as, prel31, &offset, 0, arg) < 0) + return -UNW_EINVAL; + + offset = ((long)offset << 1) >> 1; + *val = prel31 + offset; + + return 0; +} + +/** + * Applies the given command onto the new state to the given dwarf_cursor. + */ +HIDDEN int +arm_exidx_apply_cmd (struct arm_exbuf_data *edata, struct dwarf_cursor *c) +{ + int ret = 0; + unsigned i; + + switch (edata->cmd) + { + case ARM_EXIDX_CMD_FINISH: + /* Set LR to PC if not set already. */ + if (DWARF_IS_NULL_LOC (c->loc[UNW_ARM_R15])) + c->loc[UNW_ARM_R15] = c->loc[UNW_ARM_R14]; + /* Set IP. */ + dwarf_get (c, c->loc[UNW_ARM_R15], &c->ip); + break; + case ARM_EXIDX_CMD_DATA_PUSH: + Debug (2, "vsp = vsp - %d\n", edata->data); + c->cfa -= edata->data; + break; + case ARM_EXIDX_CMD_DATA_POP: + Debug (2, "vsp = vsp + %d\n", edata->data); + c->cfa += edata->data; + break; + case ARM_EXIDX_CMD_REG_POP: + for (i = 0; i < 16; i++) + if (edata->data & (1 << i)) + { + Debug (2, "pop {r%d}\n", i); + c->loc[UNW_ARM_R0 + i] = DWARF_LOC (c->cfa, 0); + c->cfa += 4; + } + /* Set cfa in case the SP got popped. */ + if (edata->data & (1 << 13)) + dwarf_get (c, c->loc[UNW_ARM_R13], &c->cfa); + break; + case ARM_EXIDX_CMD_REG_TO_SP: + assert (edata->data < 16); + Debug (2, "vsp = r%d\n", edata->data); + c->loc[UNW_ARM_R13] = c->loc[UNW_ARM_R0 + edata->data]; + dwarf_get (c, c->loc[UNW_ARM_R13], &c->cfa); + break; + case ARM_EXIDX_CMD_VFP_POP: + /* Skip VFP registers, but be sure to adjust stack */ + for (i = ARM_EXBUF_START (edata->data); i <= ARM_EXBUF_END (edata->data); + i++) + c->cfa += 8; + if (!(edata->data & ARM_EXIDX_VFP_DOUBLE)) + c->cfa += 4; + break; + case ARM_EXIDX_CMD_WREG_POP: + for (i = ARM_EXBUF_START (edata->data); i <= ARM_EXBUF_END (edata->data); + i++) + c->cfa += 8; + break; + case ARM_EXIDX_CMD_WCGR_POP: + for (i = 0; i < 4; i++) + if (edata->data & (1 << i)) + c->cfa += 4; + break; + case ARM_EXIDX_CMD_REFUSED: + case ARM_EXIDX_CMD_RESERVED: + ret = -1; + break; + } + return ret; +} + +/** + * Decodes the given unwind instructions into arm_exbuf_data and calls + * arm_exidx_apply_cmd that applies the command onto the dwarf_cursor. + */ +HIDDEN int +arm_exidx_decode (const uint8_t *buf, uint8_t len, struct dwarf_cursor *c) +{ +#define READ_OP() *buf++ + const uint8_t *end = buf + len; + int ret; + struct arm_exbuf_data edata; + + assert(buf != NULL); + assert(len > 0); + + while (buf < end) + { + uint8_t op = READ_OP (); + if ((op & 0xc0) == 0x00) + { + edata.cmd = ARM_EXIDX_CMD_DATA_POP; + edata.data = (((int)op & 0x3f) << 2) + 4; + } + else if ((op & 0xc0) == 0x40) + { + edata.cmd = ARM_EXIDX_CMD_DATA_PUSH; + edata.data = (((int)op & 0x3f) << 2) + 4; + } + else if ((op & 0xf0) == 0x80) + { + uint8_t op2 = READ_OP (); + if (op == 0x80 && op2 == 0x00) + edata.cmd = ARM_EXIDX_CMD_REFUSED; + else + { + edata.cmd = ARM_EXIDX_CMD_REG_POP; + edata.data = ((op & 0xf) << 8) | op2; + edata.data = edata.data << 4; + } + } + else if ((op & 0xf0) == 0x90) + { + if (op == 0x9d || op == 0x9f) + edata.cmd = ARM_EXIDX_CMD_RESERVED; + else + { + edata.cmd = ARM_EXIDX_CMD_REG_TO_SP; + edata.data = op & 0x0f; + } + } + else if ((op & 0xf0) == 0xa0) + { + unsigned end = (op & 0x07); + edata.data = (1 << (end + 1)) - 1; + edata.data = edata.data << 4; + if (op & 0x08) + edata.data |= 1 << 14; + edata.cmd = ARM_EXIDX_CMD_REG_POP; + } + else if (op == ARM_EXTBL_OP_FINISH) + { + edata.cmd = ARM_EXIDX_CMD_FINISH; + buf = end; + } + else if (op == 0xb1) + { + uint8_t op2 = READ_OP (); + if (op2 == 0 || (op2 & 0xf0)) + edata.cmd = ARM_EXIDX_CMD_RESERVED; + else + { + edata.cmd = ARM_EXIDX_CMD_REG_POP; + edata.data = op2 & 0x0f; + } + } + else if (op == 0xb2) + { + uint32_t offset = 0; + uint8_t byte, shift = 0; + do + { + byte = READ_OP (); + offset |= (byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + edata.data = offset * 4 + 0x204; + edata.cmd = ARM_EXIDX_CMD_DATA_POP; + } + else if (op == 0xb3 || op == 0xc8 || op == 0xc9) + { + edata.cmd = ARM_EXIDX_CMD_VFP_POP; + edata.data = READ_OP (); + if (op == 0xc8) + edata.data |= ARM_EXIDX_VFP_SHIFT_16; + if (op != 0xb3) + edata.data |= ARM_EXIDX_VFP_DOUBLE; + } + else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0) + { + edata.cmd = ARM_EXIDX_CMD_VFP_POP; + edata.data = 0x80 | (op & 0x07); + if ((op & 0xf8) == 0xd0) + edata.data |= ARM_EXIDX_VFP_DOUBLE; + } + else if (op >= 0xc0 && op <= 0xc5) + { + edata.cmd = ARM_EXIDX_CMD_WREG_POP; + edata.data = 0xa0 | (op & 0x07); + } + else if (op == 0xc6) + { + edata.cmd = ARM_EXIDX_CMD_WREG_POP; + edata.data = READ_OP (); + } + else if (op == 0xc7) + { + uint8_t op2 = READ_OP (); + if (op2 == 0 || (op2 & 0xf0)) + edata.cmd = ARM_EXIDX_CMD_RESERVED; + else + { + edata.cmd = ARM_EXIDX_CMD_WCGR_POP; + edata.data = op2 & 0x0f; + } + } + else + edata.cmd = ARM_EXIDX_CMD_RESERVED; + + ret = arm_exidx_apply_cmd (&edata, c); + if (ret < 0) + return ret; + } + return 0; +} + +/** + * Reads the entry from the given cursor and extracts the unwind instructions + * into buf. Returns the number of the extracted unwind insns or + * -UNW_ESTOPUNWIND if the special bit pattern ARM_EXIDX_CANT_UNWIND (0x1) was + * found. + */ +HIDDEN int +arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf) +{ + int nbuf = 0; + unw_word_t entry = (unw_word_t) c->pi.unwind_info; + unw_word_t addr; + uint32_t data; + + /* An ARM unwind entry consists of a prel31 offset to the start of a + function followed by 31bits of data: + * if set to 0x1: the function cannot be unwound (EXIDX_CANTUNWIND) + * if bit 31 is one: this is a table entry itself (ARM_EXIDX_COMPACT) + * if bit 31 is zero: this is a prel31 offset of the start of the + table entry for this function */ + if (prel31_to_addr(c->as, c->as_arg, entry, &addr) < 0) + return -UNW_EINVAL; + + if ((*c->as->acc.access_mem)(c->as, entry + 4, &data, 0, c->as_arg) < 0) + return -UNW_EINVAL; + + if (data == ARM_EXIDX_CANT_UNWIND) + { + Debug (2, "0x1 [can't unwind]\n"); + nbuf = -UNW_ESTOPUNWIND; + } + else if (data & ARM_EXIDX_COMPACT) + { + Debug (2, "%p compact model %d [%8.8x]\n", (void *)addr, + (data >> 24) & 0x7f, data); + buf[nbuf++] = data >> 16; + buf[nbuf++] = data >> 8; + buf[nbuf++] = data; + } + else + { + unw_word_t extbl_data; + unsigned int n_table_words = 0; + + if (prel31_to_addr(c->as, c->as_arg, entry + 4, &extbl_data) < 0) + return -UNW_EINVAL; + + if ((*c->as->acc.access_mem)(c->as, extbl_data, &data, 0, c->as_arg) < 0) + return -UNW_EINVAL; + + if (data & ARM_EXIDX_COMPACT) + { + int pers = (data >> 24) & 0x0f; + Debug (2, "%p compact model %d [%8.8x]\n", (void *)addr, pers, data); + if (pers == 1 || pers == 2) + { + n_table_words = (data >> 16) & 0xff; + extbl_data += 4; + } + else + buf[nbuf++] = data >> 16; + buf[nbuf++] = data >> 8; + buf[nbuf++] = data; + } + else + { + unw_word_t pers; + if (prel31_to_addr (c->as, c->as_arg, extbl_data, &pers) < 0) + return -UNW_EINVAL; + Debug (2, "%p Personality routine: %8p\n", (void *)addr, + (void *)pers); + if ((*c->as->acc.access_mem)(c->as, extbl_data + 4, &data, 0, + c->as_arg) < 0) + return -UNW_EINVAL; + n_table_words = data >> 24; + buf[nbuf++] = data >> 16; + buf[nbuf++] = data >> 8; + buf[nbuf++] = data; + extbl_data += 8; + } + assert (n_table_words <= 5); + unsigned j; + for (j = 0; j < n_table_words; j++) + { + if ((*c->as->acc.access_mem)(c->as, extbl_data, &data, 0, + c->as_arg) < 0) + return -UNW_EINVAL; + extbl_data += 4; + buf[nbuf++] = data >> 24; + buf[nbuf++] = data >> 16; + buf[nbuf++] = data >> 8; + buf[nbuf++] = data >> 0; + } + } + + if (nbuf > 0 && buf[nbuf - 1] != ARM_EXTBL_OP_FINISH) + buf[nbuf++] = ARM_EXTBL_OP_FINISH; + + return nbuf; +} + +PROTECTED int +tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t *di, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX) + && di->format == UNW_INFO_FORMAT_ARM_EXIDX) + { + /* The .ARM.exidx section contains a sorted list of key-value pairs - + the unwind entries. The 'key' is a prel31 offset to the start of a + function. We binary search this section in order to find the + appropriate unwind entry. */ + unw_word_t first = di->u.rti.table_data; + unw_word_t last = di->u.rti.table_data + di->u.rti.table_len - 8; + unw_word_t entry, val; + + if (prel31_to_addr (as, arg, first, &val) < 0 || ip < val) + return -UNW_ENOINFO; + + if (prel31_to_addr (as, arg, last, &val) < 0) + return -UNW_EINVAL; + + if (ip >= val) + { + entry = last; + + if (prel31_to_addr (as, arg, last, &pi->start_ip) < 0) + return -UNW_EINVAL; + + pi->end_ip = di->end_ip -1; + } + else + { + while (first < last - 8) + { + entry = first + (((last - first) / 8 + 1) >> 1) * 8; + + if (prel31_to_addr (as, arg, entry, &val) < 0) + return -UNW_EINVAL; + + if (ip < val) + last = entry; + else + first = entry; + } + + entry = first; + + if (prel31_to_addr (as, arg, entry, &pi->start_ip) < 0) + return -UNW_EINVAL; + + if (prel31_to_addr (as, arg, entry + 8, &pi->end_ip) < 0) + return -UNW_EINVAL; + + pi->end_ip--; + } + + if (need_unwind_info) + { + pi->unwind_info_size = 8; + pi->unwind_info = (void *) entry; + pi->format = UNW_INFO_FORMAT_ARM_EXIDX; + } + return 0; + } + else if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) + && di->format != UNW_INFO_FORMAT_ARM_EXIDX) + return dwarf_search_unwind_table (as, ip, di, pi, need_unwind_info, arg); + + return -UNW_ENOINFO; +} + +#ifndef UNW_REMOTE_ONLY +/** + * Callback to dl_iterate_phdr to find infos about the ARM exidx segment. + */ +static int +arm_phdr_cb (struct dl_phdr_info *info, size_t size, void *data) +{ + struct arm_cb_data *cb_data = data; + const Elf_W(Phdr) *p_text = NULL; + const Elf_W(Phdr) *p_arm_exidx = NULL; + const Elf_W(Phdr) *phdr = info->dlpi_phdr; + long n; + + for (n = info->dlpi_phnum; --n >= 0; phdr++) + { + switch (phdr->p_type) + { + case PT_LOAD: + if (cb_data->ip >= phdr->p_vaddr + info->dlpi_addr && + cb_data->ip < phdr->p_vaddr + info->dlpi_addr + phdr->p_memsz) + p_text = phdr; + break; + + case PT_ARM_EXIDX: + p_arm_exidx = phdr; + break; + + default: + break; + } + } + + if (p_text && p_arm_exidx) + { + cb_data->di.format = UNW_INFO_FORMAT_ARM_EXIDX; + cb_data->di.start_ip = p_text->p_vaddr + info->dlpi_addr; + cb_data->di.end_ip = cb_data->di.start_ip + p_text->p_memsz; + cb_data->di.u.rti.name_ptr = (unw_word_t) info->dlpi_name; + cb_data->di.u.rti.table_data = p_arm_exidx->p_vaddr + info->dlpi_addr; + cb_data->di.u.rti.table_len = p_arm_exidx->p_memsz; + return 1; + } + + return 0; +} + +HIDDEN int +arm_find_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, int need_unwind_info, void *arg) +{ + int ret = -1; + intrmask_t saved_mask; + + Debug (14, "looking for IP=0x%lx\n", (long) ip); + + if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF)) + { + struct dwarf_callback_data cb_data; + + memset (&cb_data, 0, sizeof (cb_data)); + cb_data.ip = ip; + cb_data.pi = pi; + cb_data.need_unwind_info = need_unwind_info; + cb_data.di.format = -1; + cb_data.di_debug.format = -1; + + SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); + ret = dl_iterate_phdr (dwarf_callback, &cb_data); + SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); + + if (cb_data.single_fde) + /* already got the result in *pi */ + return 0; + + if (cb_data.di_debug.format != -1) + ret = tdep_search_unwind_table (as, ip, &cb_data.di_debug, pi, + need_unwind_info, arg); + else + ret = -UNW_ENOINFO; + } + + if (ret < 0 && UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)) + { + struct arm_cb_data cb_data; + + memset (&cb_data, 0, sizeof (cb_data)); + cb_data.ip = ip; + cb_data.pi = pi; + cb_data.di.format = -1; + + SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); + ret = dl_iterate_phdr (arm_phdr_cb, &cb_data); + SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); + + if (cb_data.di.format != -1) + ret = tdep_search_unwind_table (as, ip, &cb_data.di, pi, + need_unwind_info, arg); + else + ret = -UNW_ENOINFO; + } + + if (ret < 0) + Debug (14, "IP=0x%lx not found\n", (long) ip); + + return ret; +} + +HIDDEN void +arm_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} +#endif /* !UNW_REMOTE_ONLY */ + diff --git a/src/libs/libunwind/arm/Gget_proc_info.c b/src/libs/libunwind/arm/Gget_proc_info.c new file mode 100644 index 0000000000..acb78a4644 --- /dev/null +++ b/src/libs/libunwind/arm/Gget_proc_info.c @@ -0,0 +1,41 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + /* We can only unwind using Dwarf into on ARM: return failure code + if it's not present. */ + ret = dwarf_make_proc_info (&c->dwarf); + if (ret < 0) + return ret; + + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/libs/libunwind/arm/Gget_save_loc.c b/src/libs/libunwind/arm/Gget_save_loc.c new file mode 100644 index 0000000000..63b711d855 --- /dev/null +++ b/src/libs/libunwind/arm/Gget_save_loc.c @@ -0,0 +1,81 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + + switch (reg) + { + case UNW_ARM_R0: + case UNW_ARM_R1: + case UNW_ARM_R2: + case UNW_ARM_R3: + case UNW_ARM_R4: + case UNW_ARM_R5: + case UNW_ARM_R6: + case UNW_ARM_R7: + case UNW_ARM_R8: + case UNW_ARM_R9: + case UNW_ARM_R10: + case UNW_ARM_R11: + case UNW_ARM_R12: + case UNW_ARM_R13: + case UNW_ARM_R14: + case UNW_ARM_R15: + loc = c->dwarf.loc[reg - UNW_ARM_R0]; + break; + + default: + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/libs/libunwind/arm/Gglobal.c b/src/libs/libunwind/arm/Gglobal.c new file mode 100644 index 0000000000..7b93fbd89a --- /dev/null +++ b/src/libs/libunwind/arm/Gglobal.c @@ -0,0 +1,65 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (arm_lock); +HIDDEN int tdep_init_done; + +/* Unwinding methods to use. See UNW_METHOD_ enums */ +HIDDEN int unwi_unwind_method = UNW_ARM_METHOD_ALL; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&arm_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + /* read ARM unwind method setting */ + const char* str = getenv ("UNW_ARM_UNWIND_METHOD"); + if (str) + { + unwi_unwind_method = atoi (str); + } + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + arm_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&arm_lock, saved_mask); +} diff --git a/src/libs/libunwind/arm/Ginit.c b/src/libs/libunwind/arm/Ginit.c new file mode 100644 index 0000000000..1ed3dbfc50 --- /dev/null +++ b/src/libs/libunwind/arm/Ginit.c @@ -0,0 +1,235 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +PROTECTED unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static inline void * +uc_addr (unw_tdep_context_t *uc, int reg) +{ + if (reg >= UNW_ARM_R0 && reg < UNW_ARM_R0 + 16) + return &uc->regs[reg - UNW_ARM_R0]; + else + return NULL; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (unw_tdep_context_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; + return 0; +} + +#define PAGE_SIZE 4096 +#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) + +/* Cache of already validated addresses */ +#define NLGA 4 +static unw_word_t last_good_addr[NLGA]; +static int lga_victim; + +static int +validate_mem (unw_word_t addr) +{ + int i, victim; + size_t len; + + if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) + len = PAGE_SIZE; + else + len = PAGE_SIZE * 2; + + addr = PAGE_START(addr); + + if (addr == 0) + return -1; + + for (i = 0; i < NLGA; i++) + { + if (last_good_addr[i] && (addr == last_good_addr[i])) + return 0; + } + + if (msync ((void *) addr, len, MS_ASYNC) == -1) + return -1; + + victim = lga_victim; + for (i = 0; i < NLGA; i++) { + if (!last_good_addr[victim]) { + last_good_addr[victim++] = addr; + return 0; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + last_good_addr[victim] = addr; + victim = (victim + 1) % NLGA; + lga_victim = victim; + + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (16, "mem[%x] <- %x\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + /* validate address */ + const struct cursor *c = (const struct cursor *) arg; + if (c && validate_mem(addr)) + return -1; + + *val = *(unw_word_t *) addr; + Debug (16, "mem[%x] -> %x\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + unw_tdep_context_t *uc = arg; + + if (unw_is_fpreg (reg)) + goto badreg; + +Debug (16, "reg = %s\n", unw_regname (reg)); + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %x\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %x\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + unw_tdep_context_t *uc = arg; + unw_fpreg_t *addr; + + if (!unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +arm_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.acc.find_proc_info = arm_find_proc_info; + local_addr_space.acc.put_unwind_info = arm_put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = arm_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/arm/Ginit_local.c b/src/libs/libunwind/arm/Ginit_local.c new file mode 100644 index 0000000000..e1cc30c60f --- /dev/null +++ b/src/libs/libunwind/arm/Ginit_local.c @@ -0,0 +1,55 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = uc; + + return common_init (c, 1); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/arm/Ginit_remote.c b/src/libs/libunwind/arm/Ginit_remote.c new file mode 100644 index 0000000000..f284e994f4 --- /dev/null +++ b/src/libs/libunwind/arm/Ginit_remote.c @@ -0,0 +1,45 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +PROTECTED int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/libs/libunwind/arm/Gis_signal_frame.c b/src/libs/libunwind/arm/Gis_signal_frame.c new file mode 100644 index 0000000000..e8efe7f4a8 --- /dev/null +++ b/src/libs/libunwind/arm/Gis_signal_frame.c @@ -0,0 +1,87 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include "unwind_i.h" + +#ifdef __linux__ +#define ARM_NR_sigreturn 119 +#define ARM_NR_rt_sigreturn 173 +#define ARM_NR_OABI_SYSCALL_BASE 0x900000 + +/* ARM EABI sigreturn (the syscall number is loaded into r7) */ +#define MOV_R7_SIGRETURN (0xe3a07000UL | ARM_NR_sigreturn) +#define MOV_R7_RT_SIGRETURN (0xe3a07000UL | ARM_NR_rt_sigreturn) + +/* ARM OABI sigreturn (using SWI) */ +#define ARM_SIGRETURN \ + (0xef000000UL | ARM_NR_sigreturn | ARM_NR_OABI_SYSCALL_BASE) +#define ARM_RT_SIGRETURN \ + (0xef000000UL | ARM_NR_rt_sigreturn | ARM_NR_OABI_SYSCALL_BASE) + +/* Thumb sigreturn (two insns, syscall number is loaded into r7) */ +#define THUMB_SIGRETURN (0xdf00UL << 16 | 0x2700 | ARM_NR_sigreturn) +#define THUMB_RT_SIGRETURN (0xdf00UL << 16 | 0x2700 | ARM_NR_rt_sigreturn) +#endif /* __linux__ */ + +/* Returns 1 in case of a non-RT signal frame and 2 in case of a RT signal + frame. */ +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors (as); + arg = c->dwarf.as_arg; + + ip = c->dwarf.ip; + + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) + return ret; + + /* Return 1 if the IP points to a non-RT sigreturn sequence. */ + if (w0 == MOV_R7_SIGRETURN || w0 == ARM_SIGRETURN || w0 == THUMB_SIGRETURN) + return 1; + /* Return 2 if the IP points to a RT sigreturn sequence. */ + else if (w0 == MOV_R7_RT_SIGRETURN || w0 == ARM_RT_SIGRETURN + || w0 == THUMB_RT_SIGRETURN) + return 2; + + return 0; +#elif defined(__QNX__) + /* Not supported yet */ + return 0; +#else + printf ("%s: implement me\n", __FUNCTION__); + return -UNW_ENOINFO; +#endif +} diff --git a/src/libs/libunwind/arm/Gregs.c b/src/libs/libunwind/arm/Gregs.c new file mode 100644 index 0000000000..688771f31e --- /dev/null +++ b/src/libs/libunwind/arm/Gregs.c @@ -0,0 +1,81 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + + switch (reg) + { + case UNW_ARM_R0: + case UNW_ARM_R1: + case UNW_ARM_R2: + case UNW_ARM_R3: + case UNW_ARM_R4: + case UNW_ARM_R5: + case UNW_ARM_R6: + case UNW_ARM_R7: + case UNW_ARM_R8: + case UNW_ARM_R9: + case UNW_ARM_R10: + case UNW_ARM_R11: + case UNW_ARM_R12: + case UNW_ARM_R14: + case UNW_ARM_R15: + loc = c->dwarf.loc[reg - UNW_ARM_R0]; + break; + + case UNW_ARM_R13: + case UNW_ARM_CFA: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + /* FIXME: Initialise coprocessor & shadow registers? */ + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +/* FIXME for ARM. */ + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} diff --git a/src/libs/libunwind/arm/Gresume.c b/src/libs/libunwind/arm/Gresume.c new file mode 100644 index 0000000000..9fe264ea22 --- /dev/null +++ b/src/libs/libunwind/arm/Gresume.c @@ -0,0 +1,154 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_tdep_context_t *uc = c->dwarf.as_arg; + + if (c->sigcontext_format == ARM_SCF_NONE) + { + /* Since there are no signals involved here we restore the non scratch + registers only. */ + unsigned long regs[10]; + regs[0] = uc->regs[4]; + regs[1] = uc->regs[5]; + regs[2] = uc->regs[6]; + regs[3] = uc->regs[7]; + regs[4] = uc->regs[8]; + regs[5] = uc->regs[9]; + regs[6] = uc->regs[10]; + regs[7] = uc->regs[11]; /* FP */ + regs[8] = uc->regs[13]; /* SP */ + regs[9] = uc->regs[14]; /* LR */ + + struct regs_overlay { + char x[sizeof(regs)]; + }; + + asm __volatile__ ( + "ldmia %0, {r4-r12, lr}\n" + "mov sp, r12\n" + "bx lr\n" + : : "r" (regs), + "m" (*(struct regs_overlay *)regs) + ); + } + else + { + /* In case a signal frame is involved, we're using its trampoline which + calls sigreturn. */ + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + sc->arm_r0 = uc->regs[0]; + sc->arm_r1 = uc->regs[1]; + sc->arm_r2 = uc->regs[2]; + sc->arm_r3 = uc->regs[3]; + sc->arm_r4 = uc->regs[4]; + sc->arm_r5 = uc->regs[5]; + sc->arm_r6 = uc->regs[6]; + sc->arm_r7 = uc->regs[7]; + sc->arm_r8 = uc->regs[8]; + sc->arm_r9 = uc->regs[9]; + sc->arm_r10 = uc->regs[10]; + sc->arm_fp = uc->regs[11]; /* FP */ + sc->arm_ip = uc->regs[12]; /* IP */ + sc->arm_sp = uc->regs[13]; /* SP */ + sc->arm_lr = uc->regs[14]; /* LR */ + sc->arm_pc = uc->regs[15]; /* PC */ + /* clear the ITSTATE bits. */ + sc->arm_cpsr &= 0xf9ff03ffUL; + + /* Set the SP and the PC in order to continue execution at the modified + trampoline which restores the signal mask and the registers. */ + asm __volatile__ ( + "mov sp, %0\n" + "bx %1\n" + : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) + ); + } + unreachable(); +#else + printf ("%s: implement me\n", __FUNCTION__); +#endif + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +static inline void +establish_machine_state (struct cursor *c) +{ + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + as->acc.access_fpreg (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + as->acc.access_reg (as, reg, &val, 1, arg); + } + } +} + +PROTECTED int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + + Debug (1, "(cursor=%p)\n", c); + + if (!c->dwarf.ip) + { + /* This can happen easily when the frame-chain gets truncated + due to bad or missing unwind-info. */ + Debug (1, "refusing to resume execution at address 0\n"); + return -UNW_EINVAL; + } + + establish_machine_state (c); + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/libs/libunwind/arm/Gstash_frame.c b/src/libs/libunwind/arm/Gstash_frame.c new file mode 100644 index 0000000000..2cce409d53 --- /dev/null +++ b/src/libs/libunwind/arm/Gstash_frame.c @@ -0,0 +1,90 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY + Copyright (C) 2014 CERN and Aalto University + Contributed by Filip Nyback + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN void +tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) +{ + struct cursor *c = (struct cursor *) dwarf_to_cursor (d); + unw_tdep_frame_t *f = &c->frame_info; + + Debug (4, "ip=0x%x cfa=0x%x type %d cfa [where=%d val=%d] cfaoff=%d" + " ra=0x%x r7 [where=%d val=%d @0x%x] lr [where=%d val=%d @0x%x] " + "sp [where=%d val=%d @0x%x]\n", + d->ip, d->cfa, f->frame_type, + rs->reg[DWARF_CFA_REG_COLUMN].where, + rs->reg[DWARF_CFA_REG_COLUMN].val, + rs->reg[DWARF_CFA_OFF_COLUMN].val, + DWARF_GET_LOC(d->loc[d->ret_addr_column]), + rs->reg[R7].where, rs->reg[R7].val, DWARF_GET_LOC(d->loc[R7]), + rs->reg[LR].where, rs->reg[LR].val, DWARF_GET_LOC(d->loc[LR]), + rs->reg[SP].where, rs->reg[SP].val, DWARF_GET_LOC(d->loc[SP])); + + /* A standard frame is defined as: + - CFA is register-relative offset off R7 or SP; + - Return address is saved in LR; + - R7 is unsaved or saved at CFA+offset, offset != -1; + - LR is unsaved or saved at CFA+offset, offset != -1; + - SP is unsaved or saved at CFA+offset, offset != -1. */ + if (f->frame_type == UNW_ARM_FRAME_OTHER + && (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_REG) + && (rs->reg[DWARF_CFA_REG_COLUMN].val == R7 + || rs->reg[DWARF_CFA_REG_COLUMN].val == SP) + && labs(rs->reg[DWARF_CFA_OFF_COLUMN].val) < (1 << 29) + && d->ret_addr_column == LR + && (rs->reg[R7].where == DWARF_WHERE_UNDEF + || rs->reg[R7].where == DWARF_WHERE_SAME + || (rs->reg[R7].where == DWARF_WHERE_CFAREL + && labs(rs->reg[R7].val) < (1 << 29) + && rs->reg[R7].val+1 != 0)) + && (rs->reg[LR].where == DWARF_WHERE_UNDEF + || rs->reg[LR].where == DWARF_WHERE_SAME + || (rs->reg[LR].where == DWARF_WHERE_CFAREL + && labs(rs->reg[LR].val) < (1 << 29) + && rs->reg[LR].val+1 != 0)) + && (rs->reg[SP].where == DWARF_WHERE_UNDEF + || rs->reg[SP].where == DWARF_WHERE_SAME + || (rs->reg[SP].where == DWARF_WHERE_CFAREL + && labs(rs->reg[SP].val) < (1 << 29) + && rs->reg[SP].val+1 != 0))) + { + /* Save information for a standard frame. */ + f->frame_type = UNW_ARM_FRAME_STANDARD; + f->cfa_reg_sp = (rs->reg[DWARF_CFA_REG_COLUMN].val == SP); + f->cfa_reg_offset = rs->reg[DWARF_CFA_OFF_COLUMN].val; + if (rs->reg[R7].where == DWARF_WHERE_CFAREL) + f->r7_cfa_offset = rs->reg[R7].val; + if (rs->reg[LR].where == DWARF_WHERE_CFAREL) + f->lr_cfa_offset = rs->reg[LR].val; + if (rs->reg[SP].where == DWARF_WHERE_CFAREL) + f->sp_cfa_offset = rs->reg[SP].val; + Debug (4, " standard frame\n"); + } + else + Debug (4, " unusual frame\n"); +} + diff --git a/src/libs/libunwind/arm/Gstep.c b/src/libs/libunwind/arm/Gstep.c new file mode 100644 index 0000000000..79f2dd2204 --- /dev/null +++ b/src/libs/libunwind/arm/Gstep.c @@ -0,0 +1,272 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" +#include "ex_tables.h" + +#include + +#define arm_exidx_step UNW_OBJ(arm_exidx_step) + +static inline int +arm_exidx_step (struct cursor *c) +{ + unw_word_t old_ip, old_cfa; + uint8_t buf[32]; + int ret; + + old_ip = c->dwarf.ip; + old_cfa = c->dwarf.cfa; + + /* mark PC unsaved */ + c->dwarf.loc[UNW_ARM_R15] = DWARF_NULL_LOC; + + if ((ret = tdep_find_proc_info (&c->dwarf, c->dwarf.ip, 1)) < 0) + return ret; + + if (c->dwarf.pi.format != UNW_INFO_FORMAT_ARM_EXIDX) + return -UNW_ENOINFO; + + ret = arm_exidx_extract (&c->dwarf, buf); + if (ret == -UNW_ESTOPUNWIND) + return 0; + else if (ret < 0) + return ret; + + ret = arm_exidx_decode (buf, ret, &c->dwarf); + if (ret < 0) + return ret; + + if (c->dwarf.ip == old_ip && c->dwarf.cfa == old_cfa) + { + Dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n", + __FUNCTION__, (long) c->dwarf.ip); + return -UNW_EBADFRAME; + } + + c->dwarf.pi_valid = 0; + + return (c->dwarf.ip == 0) ? 0 : 1; +} + +PROTECTED int +unw_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; + struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); + + if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) + return -UNW_EUNSPEC; + + /* Obtain signal frame type (non-RT or RT). */ + ret = unw_is_signal_frame (cursor); + + /* Save the SP and PC to be able to return execution at this point + later in time (unw_resume). */ + c->sigcontext_sp = c->dwarf.cfa; + c->sigcontext_pc = c->dwarf.ip; + + /* Since kernel version 2.6.18 the non-RT signal frame starts with a + ucontext while the RT signal frame starts with a siginfo, followed + by a sigframe whose first element is an ucontext. + Prior 2.6.18 the non-RT signal frame starts with a sigcontext while + the RT signal frame starts with two pointers followed by a siginfo + and an ucontext. The first pointer points to the start of the siginfo + structure and the second one to the ucontext structure. */ + + if (ret == 1) + { + /* Handle non-RT signal frames. Check if the first word on the stack + is the magic number. */ + if (sp == 0x5ac3c35a) + { + c->sigcontext_format = ARM_SCF_LINUX_SIGFRAME; + sc_addr = sp_addr + LINUX_UC_MCONTEXT_OFF; + } + else + { + c->sigcontext_format = ARM_SCF_LINUX_OLD_SIGFRAME; + sc_addr = sp_addr; + } + } + else if (ret == 2) + { + /* Handle RT signal frames. Check if the first word on the stack is a + pointer to the siginfo structure. */ + if (sp == sp_addr + 8) + { + c->sigcontext_format = ARM_SCF_LINUX_OLD_RT_SIGFRAME; + sc_addr = sp_addr + 8 + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; + } + else + { + c->sigcontext_format = ARM_SCF_LINUX_RT_SIGFRAME; + sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; + } + } + else + return -UNW_EUNSPEC; + + c->sigcontext_addr = sc_addr; + c->frame_info.frame_type = UNW_ARM_FRAME_SIGRETURN; + c->frame_info.cfa_reg_offset = sc_addr - sp_addr; + + /* Update the dwarf cursor. + Set the location of the registers to the corresponding addresses of the + uc_mcontext / sigcontext structure contents. */ + c->dwarf.loc[UNW_ARM_R0] = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0); + c->dwarf.loc[UNW_ARM_R1] = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0); + c->dwarf.loc[UNW_ARM_R2] = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0); + c->dwarf.loc[UNW_ARM_R3] = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0); + c->dwarf.loc[UNW_ARM_R4] = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0); + c->dwarf.loc[UNW_ARM_R5] = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0); + c->dwarf.loc[UNW_ARM_R6] = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0); + c->dwarf.loc[UNW_ARM_R7] = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0); + c->dwarf.loc[UNW_ARM_R8] = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0); + c->dwarf.loc[UNW_ARM_R9] = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0); + c->dwarf.loc[UNW_ARM_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0); + c->dwarf.loc[UNW_ARM_R11] = DWARF_LOC (sc_addr + LINUX_SC_FP_OFF, 0); + c->dwarf.loc[UNW_ARM_R12] = DWARF_LOC (sc_addr + LINUX_SC_IP_OFF, 0); + c->dwarf.loc[UNW_ARM_R13] = DWARF_LOC (sc_addr + LINUX_SC_SP_OFF, 0); + c->dwarf.loc[UNW_ARM_R14] = DWARF_LOC (sc_addr + LINUX_SC_LR_OFF, 0); + c->dwarf.loc[UNW_ARM_R15] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0); + + /* Set SP/CFA and PC/IP. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R13], &c->dwarf.cfa); + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R15], &c->dwarf.ip); + + c->dwarf.pi_valid = 0; + + return 1; +} + +PROTECTED int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret = -UNW_EUNSPEC; + + Debug (1, "(cursor=%p)\n", c); + + /* Check if this is a signal frame. */ + if (unw_is_signal_frame (cursor)) + return unw_handle_signal_frame (cursor); + +#ifdef CONFIG_DEBUG_FRAME + /* First, try DWARF-based unwinding. */ + if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF)) + { + ret = dwarf_step (&c->dwarf); + Debug(1, "dwarf_step()=%d\n", ret); + + if (likely (ret > 0)) + return 1; + else if (unlikely (ret == -UNW_ESTOPUNWIND)) + return ret; + + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } + } +#endif /* CONFIG_DEBUG_FRAME */ + + /* Next, try extbl-based unwinding. */ + if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)) + { + ret = arm_exidx_step (c); + if (ret > 0) + return 1; + if (ret == -UNW_ESTOPUNWIND || ret == 0) + return ret; + } + + /* Fall back on APCS frame parsing. + Note: This won't work in case the ARM EABI is used. */ + if (unlikely (ret < 0)) + { + if (UNW_TRY_METHOD(UNW_ARM_METHOD_FRAME)) + { + ret = UNW_ESUCCESS; + /* DWARF unwinding failed, try to follow APCS/optimized APCS frame chain */ + unw_word_t instr, i; + Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); + dwarf_loc_t ip_loc, fp_loc; + unw_word_t frame; + /* Mark all registers unsaved, since we don't know where + they are saved (if at all), except for the EBP and + EIP. */ + if (dwarf_get(&c->dwarf, c->dwarf.loc[UNW_ARM_R11], &frame) < 0) + { + return 0; + } + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) { + c->dwarf.loc[i] = DWARF_NULL_LOC; + } + if (frame) + { + if (dwarf_get(&c->dwarf, DWARF_LOC(frame, 0), &instr) < 0) + { + return 0; + } + instr -= 8; + if (dwarf_get(&c->dwarf, DWARF_LOC(instr, 0), &instr) < 0) + { + return 0; + } + if ((instr & 0xFFFFD800) == 0xE92DD800) + { + /* Standard APCS frame. */ + ip_loc = DWARF_LOC(frame - 4, 0); + fp_loc = DWARF_LOC(frame - 12, 0); + } + else + { + /* Codesourcery optimized normal frame. */ + ip_loc = DWARF_LOC(frame, 0); + fp_loc = DWARF_LOC(frame - 4, 0); + } + if (dwarf_get(&c->dwarf, ip_loc, &c->dwarf.ip) < 0) + { + return 0; + } + c->dwarf.loc[UNW_ARM_R12] = ip_loc; + c->dwarf.loc[UNW_ARM_R11] = fp_loc; + c->dwarf.pi_valid = 0; + Debug(15, "ip=%lx\n", c->dwarf.ip); + } + else + { + ret = -UNW_ENOINFO; + } + } + } + return ret == -UNW_ENOINFO ? 0 : 1; +} diff --git a/src/libs/libunwind/arm/Gtrace.c b/src/libs/libunwind/arm/Gtrace.c new file mode 100644 index 0000000000..135563a38f --- /dev/null +++ b/src/libs/libunwind/arm/Gtrace.c @@ -0,0 +1,550 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY + Copyright (C) 2014 CERN and Aalto University + Contributed by Filip Nyback + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" +#include +#include + +#pragma weak pthread_once +#pragma weak pthread_key_create +#pragma weak pthread_getspecific +#pragma weak pthread_setspecific + +/* Initial hash table size. Table expands by 2 bits (times four). */ +#define HASH_MIN_BITS 14 + +typedef struct +{ + unw_tdep_frame_t *frames; + size_t log_size; + size_t used; + size_t dtor_count; /* Counts how many times our destructor has already + been called. */ +} unw_trace_cache_t; + +static const unw_tdep_frame_t empty_frame = { 0, UNW_ARM_FRAME_OTHER, -1, -1, 0, -1, -1, -1 }; +static define_lock (trace_init_lock); +static pthread_once_t trace_cache_once = PTHREAD_ONCE_INIT; +static sig_atomic_t trace_cache_once_happen; +static pthread_key_t trace_cache_key; +static struct mempool trace_cache_pool; +static __thread unw_trace_cache_t *tls_cache; +static __thread int tls_cache_destroyed; + +/* Free memory for a thread's trace cache. */ +static void +trace_cache_free (void *arg) +{ + unw_trace_cache_t *cache = arg; + if (++cache->dtor_count < PTHREAD_DESTRUCTOR_ITERATIONS) + { + /* Not yet our turn to get destroyed. Re-install ourselves into the key. */ + pthread_setspecific(trace_cache_key, cache); + Debug(5, "delayed freeing cache %p (%zx to go)\n", cache, + PTHREAD_DESTRUCTOR_ITERATIONS - cache->dtor_count); + return; + } + tls_cache_destroyed = 1; + tls_cache = NULL; + munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); + mempool_free (&trace_cache_pool, cache); + Debug(5, "freed cache %p\n", cache); +} + +/* Initialise frame tracing for threaded use. */ +static void +trace_cache_init_once (void) +{ + pthread_key_create (&trace_cache_key, &trace_cache_free); + mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); + trace_cache_once_happen = 1; +} + +static unw_tdep_frame_t * +trace_cache_buckets (size_t n) +{ + unw_tdep_frame_t *frames; + size_t i; + + GET_MEMORY(frames, n * sizeof (unw_tdep_frame_t)); + if (likely(frames != NULL)) + for (i = 0; i < n; ++i) + frames[i] = empty_frame; + + return frames; +} + +/* Allocate and initialise hash table for frame cache lookups. + Returns the cache initialised with (1u << HASH_LOW_BITS) hash + buckets, or NULL if there was a memory allocation problem. */ +static unw_trace_cache_t * +trace_cache_create (void) +{ + unw_trace_cache_t *cache; + + if (tls_cache_destroyed) + { + /* The current thread is in the process of exiting. Don't recreate + cache, as we wouldn't have another chance to free it. */ + Debug(5, "refusing to reallocate cache: " + "thread-locals are being deallocated\n"); + return NULL; + } + + if (! (cache = mempool_alloc(&trace_cache_pool))) + { + Debug(5, "failed to allocate cache\n"); + return NULL; + } + + if (! (cache->frames = trace_cache_buckets(1u << HASH_MIN_BITS))) + { + Debug(5, "failed to allocate buckets\n"); + mempool_free(&trace_cache_pool, cache); + return NULL; + } + + cache->log_size = HASH_MIN_BITS; + cache->used = 0; + cache->dtor_count = 0; + tls_cache_destroyed = 0; /* Paranoia: should already be 0. */ + Debug(5, "allocated cache %p\n", cache); + return cache; +} + +/* Expand the hash table in the frame cache if possible. This always + quadruples the hash size, and clears all previous frame entries. */ +static int +trace_cache_expand (unw_trace_cache_t *cache) +{ + size_t old_size = (1u << cache->log_size); + size_t new_log_size = cache->log_size + 2; + unw_tdep_frame_t *new_frames = trace_cache_buckets (1u << new_log_size); + + if (unlikely(! new_frames)) + { + Debug(5, "failed to expand cache to 2^%u buckets\n", new_log_size); + return -UNW_ENOMEM; + } + + Debug(5, "expanded cache from 2^%u to 2^%u buckets\n", cache->log_size, + new_log_size); + munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); + cache->frames = new_frames; + cache->log_size = new_log_size; + cache->used = 0; + return 0; +} + +static unw_trace_cache_t * +trace_cache_get_unthreaded (void) +{ + unw_trace_cache_t *cache; + intrmask_t saved_mask; + static unw_trace_cache_t *global_cache = NULL; + lock_acquire (&trace_init_lock, saved_mask); + if (! global_cache) + { + mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); + global_cache = trace_cache_create (); + } + cache = global_cache; + lock_release (&trace_init_lock, saved_mask); + Debug(5, "using cache %p\n", cache); + return cache; +} + +/* Get the frame cache for the current thread. Create it if there is none. */ +static unw_trace_cache_t * +trace_cache_get (void) +{ + unw_trace_cache_t *cache; + if (likely (pthread_once != NULL)) + { + pthread_once(&trace_cache_once, &trace_cache_init_once); + if (!trace_cache_once_happen) + { + return trace_cache_get_unthreaded(); + } + if (! (cache = tls_cache)) + { + cache = trace_cache_create(); + pthread_setspecific(trace_cache_key, cache); + tls_cache = cache; + } + Debug(5, "using cache %p\n", cache); + return cache; + } + else + { + return trace_cache_get_unthreaded(); + } +} + +/* Initialise frame properties for address cache slot F at address + PC using current CFA, R7 and SP values. Modifies CURSOR to + that location, performs one unw_step(), and fills F with what + was discovered about the location. Returns F. + + FIXME: This probably should tell DWARF handling to never evaluate + or use registers other than R7, SP and PC in case there is + highly unusual unwind info which uses these creatively. */ +static unw_tdep_frame_t * +trace_init_addr (unw_tdep_frame_t *f, + unw_cursor_t *cursor, + unw_word_t cfa, + unw_word_t pc, + unw_word_t r7, + unw_word_t sp) +{ + struct cursor *c = (struct cursor *) cursor; + struct dwarf_cursor *d = &c->dwarf; + int ret = -UNW_EINVAL; + + /* Initialise frame properties: unknown, not last. */ + f->virtual_address = pc; + f->frame_type = UNW_ARM_FRAME_OTHER; + f->last_frame = 0; + f->cfa_reg_sp = -1; + f->cfa_reg_offset = 0; + f->r7_cfa_offset = -1; + f->lr_cfa_offset = -1; + f->sp_cfa_offset = -1; + + /* Reinitialise cursor to this instruction - but undo next/prev RIP + adjustment because unw_step will redo it - and force PC, R7 and + SP into register locations (=~ ucontext we keep), then set + their desired values. Then perform the step. */ + d->ip = pc + d->use_prev_instr; + d->cfa = cfa; + d->loc[UNW_ARM_R7] = DWARF_REG_LOC (d, UNW_ARM_R7); + d->loc[UNW_ARM_R13] = DWARF_REG_LOC (d, UNW_ARM_R13); + d->loc[UNW_ARM_R15] = DWARF_REG_LOC (d, UNW_ARM_R15); + c->frame_info = *f; + + if (likely(dwarf_put (d, d->loc[UNW_ARM_R7], r7) >= 0) + && likely(dwarf_put (d, d->loc[UNW_ARM_R13], sp) >= 0) + && likely(dwarf_put (d, d->loc[UNW_ARM_R15], pc) >= 0) + && likely((ret = unw_step (cursor)) >= 0)) + *f = c->frame_info; + + /* If unw_step() stopped voluntarily, remember that, even if it + otherwise could not determine anything useful. This avoids + failing trace if we hit frames without unwind info, which is + common for the outermost frame (CRT stuff) on many systems. + This avoids failing trace in very common circumstances; failing + to unw_step() loop wouldn't produce any better result. */ + if (ret == 0) + f->last_frame = -1; + + Debug (3, "frame va %x type %d last %d cfa %s+%d r7 @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n", + f->virtual_address, f->frame_type, f->last_frame, + f->cfa_reg_sp ? "sp" : "r7", f->cfa_reg_offset, + f->r7_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset); + + return f; +} + +/* Look up and if necessary fill in frame attributes for address PC + in CACHE using current CFA, R7 and SP values. Uses CURSOR to + perform any unwind steps necessary to fill the cache. Returns the + frame cache slot which describes RIP. */ +static unw_tdep_frame_t * +trace_lookup (unw_cursor_t *cursor, + unw_trace_cache_t *cache, + unw_word_t cfa, + unw_word_t pc, + unw_word_t r7, + unw_word_t sp) +{ + /* First look up for previously cached information using cache as + linear probing hash table with probe step of 1. Majority of + lookups should be completed within few steps, but it is very + important the hash table does not fill up, or performance falls + off the cliff. */ + uint32_t i, addr; + uint32_t cache_size = 1u << cache->log_size; + uint32_t slot = ((pc * 0x9e3779b9) >> 11) & (cache_size-1); + unw_tdep_frame_t *frame; + + for (i = 0; i < 16; ++i) + { + frame = &cache->frames[slot]; + addr = frame->virtual_address; + + /* Return if we found the address. */ + if (likely(addr == pc)) + { + Debug (4, "found address after %d steps\n", i); + return frame; + } + + /* If slot is empty, reuse it. */ + if (likely(! addr)) + break; + + /* Linear probe to next slot candidate, step = 1. */ + if (++slot >= cache_size) + slot -= cache_size; + } + + /* If we collided after 16 steps, or if the hash is more than half + full, force the hash to expand. Fill the selected slot, whether + it's free or collides. Note that hash expansion drops previous + contents; further lookups will refill the hash. */ + Debug (4, "updating slot %u after %d steps, replacing 0x%x\n", slot, i, addr); + if (unlikely(addr || cache->used >= cache_size / 2)) + { + if (unlikely(trace_cache_expand (cache) < 0)) + return NULL; + + cache_size = 1u << cache->log_size; + slot = ((pc * 0x9e3779b9) >> 11) & (cache_size-1); + frame = &cache->frames[slot]; + addr = frame->virtual_address; + } + + if (! addr) + ++cache->used; + + return trace_init_addr (frame, cursor, cfa, pc, r7, sp); +} + +/* Fast stack backtrace for ARM. + + This is used by backtrace() implementation to accelerate frequent + queries for current stack, without any desire to unwind. It fills + BUFFER with the call tree from CURSOR upwards for at most SIZE + stack levels. The first frame, backtrace itself, is omitted. When + called, SIZE should give the maximum number of entries that can be + stored into BUFFER. Uses an internal thread-specific cache to + accelerate queries. + + The caller should fall back to a unw_step() loop if this function + fails by returning -UNW_ESTOPUNWIND, meaning the routine hit a + stack frame that is too complex to be traced in the fast path. + + This function is tuned for clients which only need to walk the + stack to get the call tree as fast as possible but without any + other details, for example profilers sampling the stack thousands + to millions of times per second. The routine handles the most + common ARM ABI stack layouts: CFA is R7 or SP plus/minus + constant offset, return address is in LR, and R7, LR and SP are + either unchanged or saved on stack at constant offset from the CFA; + the signal return frame; and frames without unwind info provided + they are at the outermost (final) frame or can conservatively be + assumed to be frame-pointer based. + + Any other stack layout will cause the routine to give up. There + are only a handful of relatively rarely used functions which do + not have a stack in the standard form: vfork, longjmp, setcontext + and _dl_runtime_profile on common linux systems for example. + + On success BUFFER and *SIZE reflect the trace progress up to *SIZE + stack levels or the outermost frame, which ever is less. It may + stop short of outermost frame if unw_step() loop would also do so, + e.g. if there is no more unwind information; this is not reported + as an error. + + The function returns a negative value for errors, -UNW_ESTOPUNWIND + if tracing stopped because of an unusual frame unwind info. The + BUFFER and *SIZE reflect tracing progress up to the error frame. + + Callers of this function would normally look like this: + + unw_cursor_t cur; + unw_context_t ctx; + void addrs[128]; + int depth = 128; + int ret; + + unw_getcontext(&ctx); + unw_init_local(&cur, &ctx); + if ((ret = unw_tdep_trace(&cur, addrs, &depth)) < 0) + { + depth = 0; + unw_getcontext(&ctx); + unw_init_local(&cur, &ctx); + while ((ret = unw_step(&cur)) > 0 && depth < 128) + { + unw_word_t ip; + unw_get_reg(&cur, UNW_REG_IP, &ip); + addresses[depth++] = (void *) ip; + } + } +*/ +HIDDEN int +tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) +{ + struct cursor *c = (struct cursor *) cursor; + struct dwarf_cursor *d = &c->dwarf; + unw_trace_cache_t *cache; + unw_word_t sp, pc, cfa, r7, lr; + int maxdepth = 0; + int depth = 0; + int ret; + + /* Check input parametres. */ + if (unlikely(! cursor || ! buffer || ! size || (maxdepth = *size) <= 0)) + return -UNW_EINVAL; + + Debug (1, "begin ip 0x%x cfa 0x%x\n", d->ip, d->cfa); + + /* Tell core dwarf routines to call back to us. */ + d->stash_frames = 1; + + /* Determine initial register values. These are direct access safe + because we know they come from the initial machine context. */ + pc = d->ip; + sp = cfa = d->cfa; + ACCESS_MEM_FAST(ret, 0, d, DWARF_GET_LOC(d->loc[UNW_ARM_R7]), r7); + assert(ret == 0); + lr = 0; + + /* Get frame cache. */ + if (unlikely(! (cache = trace_cache_get()))) + { + Debug (1, "returning %d, cannot get trace cache\n", -UNW_ENOMEM); + *size = 0; + d->stash_frames = 0; + return -UNW_ENOMEM; + } + + /* Trace the stack upwards, starting from current PC. Adjust + the PC address for previous/next instruction as the main + unwinding logic would also do. We undo this before calling + back into unw_step(). */ + while (depth < maxdepth) + { + pc -= d->use_prev_instr; + Debug (2, "depth %d cfa 0x%x pc 0x%x sp 0x%x r7 0x%x\n", + depth, cfa, pc, sp, r7); + + /* See if we have this address cached. If not, evaluate enough of + the dwarf unwind information to fill the cache line data, or to + decide this frame cannot be handled in fast trace mode. We + cache negative results too to prevent unnecessary dwarf parsing + for common failures. */ + unw_tdep_frame_t *f = trace_lookup (cursor, cache, cfa, pc, r7, sp); + + /* If we don't have information for this frame, give up. */ + if (unlikely(! f)) + { + ret = -UNW_ENOINFO; + break; + } + + Debug (3, "frame va %x type %d last %d cfa %s+%d r7 @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n", + f->virtual_address, f->frame_type, f->last_frame, + f->cfa_reg_sp ? "sp" : "r7", f->cfa_reg_offset, + f->r7_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset); + + assert (f->virtual_address == pc); + + /* Stop if this was the last frame. In particular don't evaluate + new register values as it may not be safe - we don't normally + run with full validation on, and do not want to - and there's + enough bad unwind info floating around that we need to trust + what unw_step() previously said, in potentially bogus frames. */ + if (f->last_frame) + break; + + /* Evaluate CFA and registers for the next frame. */ + switch (f->frame_type) + { + case UNW_ARM_FRAME_GUESSED: + /* Fall thru to standard processing after forcing validation. */ + c->validate = 1; + + case UNW_ARM_FRAME_STANDARD: + /* Advance standard traceable frame. */ + cfa = (f->cfa_reg_sp ? sp : r7) + f->cfa_reg_offset; + if (likely(f->lr_cfa_offset != -1)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->lr_cfa_offset, pc); + else if (lr != 0) + { + /* Use the saved link register as the new pc. */ + pc = lr; + lr = 0; + } + if (likely(ret >= 0) && likely(f->r7_cfa_offset != -1)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->r7_cfa_offset, r7); + + /* Don't bother reading SP from DWARF, CFA becomes new SP. */ + sp = cfa; + + /* Next frame needs to back up for unwind info lookup. */ + d->use_prev_instr = 1; + break; + + case UNW_ARM_FRAME_SIGRETURN: + cfa = cfa + f->cfa_reg_offset; /* cfa now points to ucontext_t. */ + + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_PC_OFF, pc); + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_R7_OFF, r7); + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_SP_OFF, sp); + /* Save the link register here in case we end up in a function that + doesn't save the link register in the prologue, e.g. kill. */ + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_LR_OFF, lr); + + /* Resume stack at signal restoration point. The stack is not + necessarily continuous here, especially with sigaltstack(). */ + cfa = sp; + + /* Next frame should not back up. */ + d->use_prev_instr = 0; + break; + + default: + /* We cannot trace through this frame, give up and tell the + caller we had to stop. Data collected so far may still be + useful to the caller, so let it know how far we got. */ + ret = -UNW_ESTOPUNWIND; + break; + } + + Debug (4, "new cfa 0x%x pc 0x%x sp 0x%x r7 0x%x\n", + cfa, pc, sp, r7); + + /* If we failed or ended up somewhere bogus, stop. */ + if (unlikely(ret < 0 || pc < 0x4000)) + break; + + /* Record this address in stack trace. We skipped the first address. */ + buffer[depth++] = (void *) (pc - d->use_prev_instr); + } + +#if UNW_DEBUG + Debug (1, "returning %d, depth %d\n", ret, depth); +#endif + *size = depth; + return ret; +} + diff --git a/src/libs/libunwind/arm/Lcreate_addr_space.c b/src/libs/libunwind/arm/Lcreate_addr_space.c new file mode 100644 index 0000000000..0f2dc6be90 --- /dev/null +++ b/src/libs/libunwind/arm/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/libs/libunwind/arm/Lex_tables.c b/src/libs/libunwind/arm/Lex_tables.c new file mode 100644 index 0000000000..4a4f925c9c --- /dev/null +++ b/src/libs/libunwind/arm/Lex_tables.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gex_tables.c" +#endif diff --git a/src/libs/libunwind/arm/Lget_proc_info.c b/src/libs/libunwind/arm/Lget_proc_info.c new file mode 100644 index 0000000000..69028b019f --- /dev/null +++ b/src/libs/libunwind/arm/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/libs/libunwind/arm/Lget_save_loc.c b/src/libs/libunwind/arm/Lget_save_loc.c new file mode 100644 index 0000000000..9ea048a907 --- /dev/null +++ b/src/libs/libunwind/arm/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/libs/libunwind/arm/Lglobal.c b/src/libs/libunwind/arm/Lglobal.c new file mode 100644 index 0000000000..6d7b489e14 --- /dev/null +++ b/src/libs/libunwind/arm/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/libs/libunwind/arm/Linit.c b/src/libs/libunwind/arm/Linit.c new file mode 100644 index 0000000000..e9abfdd46a --- /dev/null +++ b/src/libs/libunwind/arm/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/libs/libunwind/arm/Linit_local.c b/src/libs/libunwind/arm/Linit_local.c new file mode 100644 index 0000000000..68a1687e85 --- /dev/null +++ b/src/libs/libunwind/arm/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/libs/libunwind/arm/Linit_remote.c b/src/libs/libunwind/arm/Linit_remote.c new file mode 100644 index 0000000000..58cb04ab7c --- /dev/null +++ b/src/libs/libunwind/arm/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/libs/libunwind/arm/Lis_signal_frame.c b/src/libs/libunwind/arm/Lis_signal_frame.c new file mode 100644 index 0000000000..b9a7c4f51a --- /dev/null +++ b/src/libs/libunwind/arm/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/libs/libunwind/arm/Lregs.c b/src/libs/libunwind/arm/Lregs.c new file mode 100644 index 0000000000..2c9c75cd7d --- /dev/null +++ b/src/libs/libunwind/arm/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/libs/libunwind/arm/Lresume.c b/src/libs/libunwind/arm/Lresume.c new file mode 100644 index 0000000000..41a8cf003d --- /dev/null +++ b/src/libs/libunwind/arm/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/libs/libunwind/arm/Lstash_frame.c b/src/libs/libunwind/arm/Lstash_frame.c new file mode 100644 index 0000000000..77587803d0 --- /dev/null +++ b/src/libs/libunwind/arm/Lstash_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstash_frame.c" +#endif diff --git a/src/libs/libunwind/arm/Lstep.c b/src/libs/libunwind/arm/Lstep.c new file mode 100644 index 0000000000..c1ac3c7547 --- /dev/null +++ b/src/libs/libunwind/arm/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/libs/libunwind/arm/Ltrace.c b/src/libs/libunwind/arm/Ltrace.c new file mode 100644 index 0000000000..24b7b3cfa6 --- /dev/null +++ b/src/libs/libunwind/arm/Ltrace.c @@ -0,0 +1,6 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gtrace.c" +#endif + diff --git a/src/libs/libunwind/arm/gen-offsets.c b/src/libs/libunwind/arm/gen-offsets.c new file mode 100644 index 0000000000..7d6bf2f1c5 --- /dev/null +++ b/src/libs/libunwind/arm/gen-offsets.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +#define UC(N,X) \ + printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) + +#define SC(N,X) \ + printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) + +int +main (void) +{ + printf ( +"/* Linux-specific definitions: */\n\n" + +"/* Define various structure offsets to simplify cross-compilation. */\n\n" + +"/* Offsets for ARM Linux \"ucontext_t\": */\n\n"); + + UC ("FLAGS", uc_flags); + UC ("LINK", uc_link); + UC ("STACK", uc_stack); + UC ("MCONTEXT", uc_mcontext); + UC ("SIGMASK", uc_sigmask); + UC ("REGSPACE", uc_regspace); + + printf ("\n/* Offsets for ARM Linux \"struct sigcontext\": */\n\n"); + + SC ("TRAPNO", trap_no); + SC ("ERRORCODE", error_code); + SC ("OLDMASK", oldmask); + SC ("R0", arm_r0); + SC ("R1", arm_r1); + SC ("R2", arm_r2); + SC ("R3", arm_r3); + SC ("R4", arm_r4); + SC ("R5", arm_r5); + SC ("R6", arm_r6); + SC ("R7", arm_r7); + SC ("R8", arm_r8); + SC ("R9", arm_r9); + SC ("R10", arm_r10); + SC ("FP", arm_fp); + SC ("IP", arm_ip); + SC ("SP", arm_sp); + SC ("LR", arm_lr); + SC ("PC", arm_pc); + SC ("CPSR", arm_cpsr); + SC ("FAULTADDR", fault_address); + + return 0; +} diff --git a/src/libs/libunwind/arm/getcontext.S b/src/libs/libunwind/arm/getcontext.S new file mode 100644 index 0000000000..c52992bfb9 --- /dev/null +++ b/src/libs/libunwind/arm/getcontext.S @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" + + .text + .arm + + .global _Uarm_getcontext + .type _Uarm_getcontext, %function + @ This is a stub version of getcontext() for ARM which only stores core + @ registers. It must be called in a special way, not as a regular + @ function -- see also the libunwind-arm.h:unw_tdep_getcontext macro. +_Uarm_getcontext: + stmfd sp!, {r0, r1} + @ store r0 + str r0, [r0, #LINUX_UC_MCONTEXT_OFF + LINUX_SC_R0_OFF] + add r0, r0, #LINUX_UC_MCONTEXT_OFF + LINUX_SC_R0_OFF + @ store r1 to r12 + stmib r0, {r1-r12} + @ reconstruct r13 at call site, then store + add r1, sp, #12 + str r1, [r0, #13 * 4] + @ retrieve r14 from call site, then store + ldr r1, [sp, #8] + str r1, [r0, #14 * 4] + @ point lr to instruction after call site's stack adjustment + add r1, lr, #4 + str r1, [r0, #15 * 4] + ldmfd sp!, {r0, r1} + bx lr +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",%progbits +#endif diff --git a/src/libs/libunwind/arm/init.h b/src/libs/libunwind/arm/init.h new file mode 100644 index 0000000000..6379d8ec1f --- /dev/null +++ b/src/libs/libunwind/arm/init.h @@ -0,0 +1,78 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret, i; + + c->dwarf.loc[UNW_ARM_R0] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R0); + c->dwarf.loc[UNW_ARM_R1] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R1); + c->dwarf.loc[UNW_ARM_R2] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R2); + c->dwarf.loc[UNW_ARM_R3] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R3); + c->dwarf.loc[UNW_ARM_R4] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R4); + c->dwarf.loc[UNW_ARM_R5] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R5); + c->dwarf.loc[UNW_ARM_R6] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R6); + c->dwarf.loc[UNW_ARM_R7] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R7); + c->dwarf.loc[UNW_ARM_R8] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R8); + c->dwarf.loc[UNW_ARM_R9] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R9); + c->dwarf.loc[UNW_ARM_R10] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R10); + c->dwarf.loc[UNW_ARM_R11] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R11); + c->dwarf.loc[UNW_ARM_R12] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R12); + c->dwarf.loc[UNW_ARM_R13] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R13); + c->dwarf.loc[UNW_ARM_R14] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R14); + c->dwarf.loc[UNW_ARM_R15] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R15); + for (i = UNW_ARM_R15 + 1; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R15], &c->dwarf.ip); + if (ret < 0) + return ret; + + /* FIXME: correct for ARM? */ + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_ARM_R13), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = ARM_SCF_NONE; + c->sigcontext_addr = 0; + c->sigcontext_sp = 0; + c->sigcontext_pc = 0; + + /* FIXME: Initialisation for other registers. */ + + c->dwarf.args_size = 0; + c->dwarf.ret_addr_column = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/libs/libunwind/arm/is_fpreg.c b/src/libs/libunwind/arm/is_fpreg.c new file mode 100644 index 0000000000..3b36a03d10 --- /dev/null +++ b/src/libs/libunwind/arm/is_fpreg.c @@ -0,0 +1,39 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +/* FIXME: I'm not sure if libunwind's GP/FP register distinction is very useful + on ARM. Count all the FP or coprocessor registers we know about for now. */ + +PROTECTED int +unw_is_fpreg (int regnum) +{ + return ((regnum >= UNW_ARM_S0 && regnum <= UNW_ARM_S31) + || (regnum >= UNW_ARM_F0 && regnum <= UNW_ARM_F7) + || (regnum >= UNW_ARM_wCGR0 && regnum <= UNW_ARM_wCGR7) + || (regnum >= UNW_ARM_wR0 && regnum <= UNW_ARM_wR15) + || (regnum >= UNW_ARM_wC0 && regnum <= UNW_ARM_wC7) + || (regnum >= UNW_ARM_D0 && regnum <= UNW_ARM_D31)); +} diff --git a/src/libs/libunwind/arm/offsets.h b/src/libs/libunwind/arm/offsets.h new file mode 100644 index 0000000000..a63847be41 --- /dev/null +++ b/src/libs/libunwind/arm/offsets.h @@ -0,0 +1,36 @@ +/* Linux-specific definitions: */ + +/* Define various structure offsets to simplify cross-compilation. */ + +/* Offsets for ARM Linux "ucontext_t": */ + +#define LINUX_UC_FLAGS_OFF 0x00 +#define LINUX_UC_LINK_OFF 0x04 +#define LINUX_UC_STACK_OFF 0x08 +#define LINUX_UC_MCONTEXT_OFF 0x14 +#define LINUX_UC_SIGMASK_OFF 0x68 +#define LINUX_UC_REGSPACE_OFF 0xE8 + +/* Offsets for ARM Linux "struct sigcontext": */ + +#define LINUX_SC_TRAPNO_OFF 0x00 +#define LINUX_SC_ERRORCODE_OFF 0x04 +#define LINUX_SC_OLDMASK_OFF 0x08 +#define LINUX_SC_R0_OFF 0x0C +#define LINUX_SC_R1_OFF 0x10 +#define LINUX_SC_R2_OFF 0x14 +#define LINUX_SC_R3_OFF 0x18 +#define LINUX_SC_R4_OFF 0x1C +#define LINUX_SC_R5_OFF 0x20 +#define LINUX_SC_R6_OFF 0x24 +#define LINUX_SC_R7_OFF 0x28 +#define LINUX_SC_R8_OFF 0x2C +#define LINUX_SC_R9_OFF 0x30 +#define LINUX_SC_R10_OFF 0x34 +#define LINUX_SC_FP_OFF 0x38 +#define LINUX_SC_IP_OFF 0x3C +#define LINUX_SC_SP_OFF 0x40 +#define LINUX_SC_LR_OFF 0x44 +#define LINUX_SC_PC_OFF 0x48 +#define LINUX_SC_CPSR_OFF 0x4C +#define LINUX_SC_FAULTADDR_OFF 0x50 diff --git a/src/libs/libunwind/arm/regname.c b/src/libs/libunwind/arm/regname.c new file mode 100644 index 0000000000..474337a568 --- /dev/null +++ b/src/libs/libunwind/arm/regname.c @@ -0,0 +1,90 @@ +#include "unwind_i.h" + +static const char *regname[] = + { + /* 0. */ + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + /* 8. */ + "r8", "r9", "r10", "fp", "ip", "sp", "lr", "pc", + /* 16. Obsolete FPA names. */ + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + /* 24. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 32. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 40. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 48. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 56. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 64. */ + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + /* 72. */ + "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", + /* 80. */ + "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", + /* 88. */ + "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", + /* 96. */ + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + /* 104. */ + "wCGR0", "wCGR1", "wCGR2", "wCGR3", "wCGR4", "wCGR5", "wCGR6", "wCGR7", + /* 112. */ + "wR0", "wR1", "wR2", "wR3", "wR4", "wR5", "wR6", "wR7", + /* 128. */ + "spsr", "spsr_fiq", "spsr_irq", "spsr_abt", "spsr_und", "spsr_svc", 0, 0, + /* 136. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 144. */ + "r8_usr", "r9_usr", "r10_usr", "r11_usr", "r12_usr", "r13_usr", "r14_usr", + /* 151. */ + "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", "r14_fiq", + /* 158. */ + "r13_irq", "r14_irq", + /* 160. */ + "r13_abt", "r14_abt", + /* 162. */ + "r13_und", "r14_und", + /* 164. */ + "r13_svc", "r14_svc", 0, 0, + /* 168. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 176. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 184. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 192. */ + "wC0", "wC1", "wC2", "wC3", "wC4", "wC5", "wC6", "wC7", + /* 200. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 208. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 216. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 224. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 232. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 240. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 248. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 256. */ + "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", + /* 264. */ + "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", + /* 272. */ + "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", + /* 280. */ + "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", + }; + +PROTECTED const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/libs/libunwind/arm/siglongjmp.S b/src/libs/libunwind/arm/siglongjmp.S new file mode 100644 index 0000000000..4df0736683 --- /dev/null +++ b/src/libs/libunwind/arm/siglongjmp.S @@ -0,0 +1,12 @@ + /* Dummy implementation for now. */ + + .globl _UI_siglongjmp_cont + .globl _UI_longjmp_cont + +_UI_siglongjmp_cont: +_UI_longjmp_cont: + bx lr +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",%progbits +#endif diff --git a/src/libs/libunwind/arm/unwind_i.h b/src/libs/libunwind/arm/unwind_i.h new file mode 100644 index 0000000000..4dabf217c5 --- /dev/null +++ b/src/libs/libunwind/arm/unwind_i.h @@ -0,0 +1,59 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include + +#include + +#include "libunwind_i.h" + +/* DWARF column numbers for ARM: */ +#define R7 7 +#define SP 13 +#define LR 14 +#define PC 15 + +#define arm_lock UNW_OBJ(lock) +#define arm_local_resume UNW_OBJ(local_resume) +#define arm_local_addr_space_init UNW_OBJ(local_addr_space_init) + +extern void arm_local_addr_space_init (void); +extern int arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); +/* By-pass calls to access_mem() when known to be safe. */ +#ifdef UNW_LOCAL_ONLY +# undef ACCESS_MEM_FAST +# define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \ + do { \ + if (unlikely(validate)) \ + (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); \ + else \ + (ret) = 0, (to) = *(unw_word_t *)(addr); \ + } while (0) +#endif + +#endif /* unwind_i_h */ diff --git a/src/libs/libunwind/coredump/README b/src/libs/libunwind/coredump/README new file mode 100644 index 0000000000..204493c93e --- /dev/null +++ b/src/libs/libunwind/coredump/README @@ -0,0 +1,8 @@ +This code is based on "unwinding via ptrace" code from ptrace/ +directory. + +Files with names starting with _UCD_ are substantially changed +from their ptrace/_UPT_... progenitors. + +Files which still have _UPT_... names are either verbiatim copies +from ptrace/, or unimplemented stubs. diff --git a/src/libs/libunwind/coredump/_UCD_access_mem.c b/src/libs/libunwind/coredump/_UCD_access_mem.c new file mode 100644 index 0000000000..1fdbd128ff --- /dev/null +++ b/src/libs/libunwind/coredump/_UCD_access_mem.c @@ -0,0 +1,98 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +int +_UCD_access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t *val, + int write, void *arg) +{ + if (write) + { + Debug(0, "write is not supported\n"); + return -UNW_EINVAL; + } + + struct UCD_info *ui = arg; + + unw_word_t addr_last = addr + sizeof(*val)-1; + coredump_phdr_t *phdr; + unsigned i; + for (i = 0; i < ui->phdrs_count; i++) + { + phdr = &ui->phdrs[i]; + if (phdr->p_vaddr <= addr && addr_last < phdr->p_vaddr + phdr->p_memsz) + { + goto found; + } + } + Debug(1, "addr 0x%llx is unmapped\n", (unsigned long long)addr); + return -UNW_EINVAL; + + found: ; + + const char *filename UNUSED; + off_t fileofs; + int fd; + if (addr_last >= phdr->p_vaddr + phdr->p_filesz) + { + /* This part of mapped address space is not present in coredump file */ + /* Do we have it in the backup file? */ + if (phdr->backing_fd < 0) + { + Debug(1, "access to not-present data in phdr[%d]: addr:0x%llx\n", + i, (unsigned long long)addr + ); + return -UNW_EINVAL; + } + filename = phdr->backing_filename; + fileofs = addr - phdr->p_vaddr; + fd = phdr->backing_fd; + goto read; + } + + filename = ui->coredump_filename; + fileofs = phdr->p_offset + (addr - phdr->p_vaddr); + fd = ui->coredump_fd; + read: + if (lseek(fd, fileofs, SEEK_SET) != fileofs) + goto read_error; + if (read(fd, val, sizeof(*val)) != sizeof(*val)) + goto read_error; + + Debug(1, "0x%llx <- [addr:0x%llx fileofs:0x%llx]\n", + (unsigned long long)(*val), + (unsigned long long)addr, + (unsigned long long)fileofs + ); + return 0; + + read_error: + Debug(1, "access out of file: addr:0x%llx fileofs:%llx file:'%s'\n", + (unsigned long long)addr, + (unsigned long long)fileofs, + filename + ); + return -UNW_EINVAL; +} diff --git a/src/libs/libunwind/coredump/_UCD_access_reg_freebsd.c b/src/libs/libunwind/coredump/_UCD_access_reg_freebsd.c new file mode 100644 index 0000000000..585b7e298b --- /dev/null +++ b/src/libs/libunwind/coredump/_UCD_access_reg_freebsd.c @@ -0,0 +1,118 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" + +#include "_UCD_internal.h" + +int +_UCD_access_reg (unw_addr_space_t as, + unw_regnum_t regnum, unw_word_t *valp, + int write, void *arg) +{ + if (write) + { + Debug(0, "write is not supported\n"); + return -UNW_EINVAL; + } + + struct UCD_info *ui = arg; + +#if defined(UNW_TARGET_X86) + switch (regnum) { + case UNW_X86_EAX: + *valp = ui->prstatus->pr_reg.r_eax; + break; + case UNW_X86_EDX: + *valp = ui->prstatus->pr_reg.r_edx; + break; + case UNW_X86_ECX: + *valp = ui->prstatus->pr_reg.r_ecx; + break; + case UNW_X86_EBX: + *valp = ui->prstatus->pr_reg.r_ebx; + break; + case UNW_X86_ESI: + *valp = ui->prstatus->pr_reg.r_esi; + break; + case UNW_X86_EDI: + *valp = ui->prstatus->pr_reg.r_edi; + break; + case UNW_X86_EBP: + *valp = ui->prstatus->pr_reg.r_ebp; + break; + case UNW_X86_ESP: + *valp = ui->prstatus->pr_reg.r_esp; + break; + case UNW_X86_EIP: + *valp = ui->prstatus->pr_reg.r_eip; + break; + case UNW_X86_EFLAGS: + *valp = ui->prstatus->pr_reg.r_eflags; + break; + case UNW_X86_TRAPNO: + *valp = ui->prstatus->pr_reg.r_trapno; + break; + default: + Debug(0, "bad regnum:%d\n", regnum); + return -UNW_EINVAL; + }; +#elif defined(UNW_TARGET_X86_64) + switch (regnum) { + case UNW_X86_64_RAX: + *valp = ui->prstatus->pr_reg.r_rax; + break; + case UNW_X86_64_RDX: + *valp = ui->prstatus->pr_reg.r_rdx; + break; + case UNW_X86_64_RCX: + *valp = ui->prstatus->pr_reg.r_rcx; + break; + case UNW_X86_64_RBX: + *valp = ui->prstatus->pr_reg.r_rbx; + break; + case UNW_X86_64_RSI: + *valp = ui->prstatus->pr_reg.r_rsi; + break; + case UNW_X86_64_RDI: + *valp = ui->prstatus->pr_reg.r_rdi; + break; + case UNW_X86_64_RBP: + *valp = ui->prstatus->pr_reg.r_rbp; + break; + case UNW_X86_64_RSP: + *valp = ui->prstatus->pr_reg.r_rsp; + break; + case UNW_X86_64_RIP: + *valp = ui->prstatus->pr_reg.r_rip; + break; + default: + Debug(0, "bad regnum:%d\n", regnum); + return -UNW_EINVAL; + }; +#else +#error Port me +#endif + + return 0; +} diff --git a/src/libs/libunwind/coredump/_UCD_access_reg_linux.c b/src/libs/libunwind/coredump/_UCD_access_reg_linux.c new file mode 100644 index 0000000000..4b5994fad4 --- /dev/null +++ b/src/libs/libunwind/coredump/_UCD_access_reg_linux.c @@ -0,0 +1,143 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" + +#include "_UCD_internal.h" + +int +_UCD_access_reg (unw_addr_space_t as, + unw_regnum_t regnum, unw_word_t *valp, + int write, void *arg) +{ + struct UCD_info *ui = arg; + + if (write) + { + Debug(0, "write is not supported\n"); + return -UNW_EINVAL; + } + +#if defined(UNW_TARGET_AARCH64) + if (regnum < 0 || regnum >= UNW_AARCH64_FPCR) + goto badreg; +#elif defined(UNW_TARGET_ARM) + if (regnum < 0 || regnum >= 16) + goto badreg; +#elif defined(UNW_TARGET_SH) + if (regnum < 0 || regnum > UNW_SH_PR) + goto badreg; +#elif defined(UNW_TARGET_TILEGX) + if (regnum < 0 || regnum > UNW_TILEGX_CFA) + goto badreg; +#else +#if defined(UNW_TARGET_MIPS) + static const uint8_t remap_regs[] = + { + [UNW_MIPS_R0] = EF_REG0, + [UNW_MIPS_R1] = EF_REG1, + [UNW_MIPS_R2] = EF_REG2, + [UNW_MIPS_R3] = EF_REG3, + [UNW_MIPS_R4] = EF_REG4, + [UNW_MIPS_R5] = EF_REG5, + [UNW_MIPS_R6] = EF_REG6, + [UNW_MIPS_R7] = EF_REG7, + [UNW_MIPS_R8] = EF_REG8, + [UNW_MIPS_R9] = EF_REG9, + [UNW_MIPS_R10] = EF_REG10, + [UNW_MIPS_R11] = EF_REG11, + [UNW_MIPS_R12] = EF_REG12, + [UNW_MIPS_R13] = EF_REG13, + [UNW_MIPS_R14] = EF_REG14, + [UNW_MIPS_R15] = EF_REG15, + [UNW_MIPS_R16] = EF_REG16, + [UNW_MIPS_R17] = EF_REG17, + [UNW_MIPS_R18] = EF_REG18, + [UNW_MIPS_R19] = EF_REG19, + [UNW_MIPS_R20] = EF_REG20, + [UNW_MIPS_R21] = EF_REG21, + [UNW_MIPS_R22] = EF_REG22, + [UNW_MIPS_R23] = EF_REG23, + [UNW_MIPS_R24] = EF_REG24, + [UNW_MIPS_R25] = EF_REG25, + [UNW_MIPS_R28] = EF_REG28, + [UNW_MIPS_R29] = EF_REG29, + [UNW_MIPS_R30] = EF_REG30, + [UNW_MIPS_R31] = EF_REG31, + [UNW_MIPS_PC] = EF_CP0_EPC, + }; +#elif defined(UNW_TARGET_X86) + static const uint8_t remap_regs[] = + { + /* names from libunwind-x86.h */ + [UNW_X86_EAX] = offsetof(struct user_regs_struct, eax) / sizeof(long), + [UNW_X86_EDX] = offsetof(struct user_regs_struct, edx) / sizeof(long), + [UNW_X86_ECX] = offsetof(struct user_regs_struct, ecx) / sizeof(long), + [UNW_X86_EBX] = offsetof(struct user_regs_struct, ebx) / sizeof(long), + [UNW_X86_ESI] = offsetof(struct user_regs_struct, esi) / sizeof(long), + [UNW_X86_EDI] = offsetof(struct user_regs_struct, edi) / sizeof(long), + [UNW_X86_EBP] = offsetof(struct user_regs_struct, ebp) / sizeof(long), + [UNW_X86_ESP] = offsetof(struct user_regs_struct, esp) / sizeof(long), + [UNW_X86_EIP] = offsetof(struct user_regs_struct, eip) / sizeof(long), + [UNW_X86_EFLAGS] = offsetof(struct user_regs_struct, eflags) / sizeof(long), + [UNW_X86_TRAPNO] = offsetof(struct user_regs_struct, orig_eax) / sizeof(long), + }; +#elif defined(UNW_TARGET_X86_64) + static const int8_t remap_regs[] = + { + [UNW_X86_64_RAX] = offsetof(struct user_regs_struct, rax) / sizeof(long), + [UNW_X86_64_RDX] = offsetof(struct user_regs_struct, rdx) / sizeof(long), + [UNW_X86_64_RCX] = offsetof(struct user_regs_struct, rcx) / sizeof(long), + [UNW_X86_64_RBX] = offsetof(struct user_regs_struct, rbx) / sizeof(long), + [UNW_X86_64_RSI] = offsetof(struct user_regs_struct, rsi) / sizeof(long), + [UNW_X86_64_RDI] = offsetof(struct user_regs_struct, rdi) / sizeof(long), + [UNW_X86_64_RBP] = offsetof(struct user_regs_struct, rbp) / sizeof(long), + [UNW_X86_64_RSP] = offsetof(struct user_regs_struct, rsp) / sizeof(long), + [UNW_X86_64_RIP] = offsetof(struct user_regs_struct, rip) / sizeof(long), + }; +#else +#error Port me +#endif + + if (regnum < 0 || regnum >= (unw_regnum_t)ARRAY_SIZE(remap_regs)) + goto badreg; + + regnum = remap_regs[regnum]; +#endif + + /* pr_reg is a long[] array, but it contains struct user_regs_struct's + * image. + */ + Debug(1, "pr_reg[%d]:%ld (0x%lx)\n", regnum, + (long)ui->prstatus->pr_reg[regnum], + (long)ui->prstatus->pr_reg[regnum] + ); + *valp = ui->prstatus->pr_reg[regnum]; + + return 0; + +badreg: + Debug(0, "bad regnum:%d\n", regnum); + return -UNW_EINVAL; +} diff --git a/src/libs/libunwind/coredump/_UCD_accessors.c b/src/libs/libunwind/coredump/_UCD_accessors.c new file mode 100644 index 0000000000..f081180319 --- /dev/null +++ b/src/libs/libunwind/coredump/_UCD_accessors.c @@ -0,0 +1,36 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_internal.h" + +PROTECTED unw_accessors_t _UCD_accessors = + { + .find_proc_info = _UCD_find_proc_info, + .put_unwind_info = _UCD_put_unwind_info, + .get_dyn_info_list_addr = _UCD_get_dyn_info_list_addr, + .access_mem = _UCD_access_mem, + .access_reg = _UCD_access_reg, + .access_fpreg = _UCD_access_fpreg, + .resume = _UCD_resume, + .get_proc_name = _UCD_get_proc_name + }; diff --git a/src/libs/libunwind/coredump/_UCD_create.c b/src/libs/libunwind/coredump/_UCD_create.c new file mode 100644 index 0000000000..f22664b685 --- /dev/null +++ b/src/libs/libunwind/coredump/_UCD_create.c @@ -0,0 +1,417 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +/* Endian detection */ +#include +#if defined(HAVE_BYTESWAP_H) +#include +#endif +#if defined(HAVE_ENDIAN_H) +# include +#elif defined(HAVE_SYS_ENDIAN_H) +# include +#endif +#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN +# define WE_ARE_BIG_ENDIAN 1 +# define WE_ARE_LITTLE_ENDIAN 0 +#elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN +# define WE_ARE_BIG_ENDIAN 0 +# define WE_ARE_LITTLE_ENDIAN 1 +#elif defined(_BYTE_ORDER) && _BYTE_ORDER == _BIG_ENDIAN +# define WE_ARE_BIG_ENDIAN 1 +# define WE_ARE_LITTLE_ENDIAN 0 +#elif defined(_BYTE_ORDER) && _BYTE_ORDER == _LITTLE_ENDIAN +# define WE_ARE_BIG_ENDIAN 0 +# define WE_ARE_LITTLE_ENDIAN 1 +#elif defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN +# define WE_ARE_BIG_ENDIAN 1 +# define WE_ARE_LITTLE_ENDIAN 0 +#elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN +# define WE_ARE_BIG_ENDIAN 0 +# define WE_ARE_LITTLE_ENDIAN 1 +#elif defined(__386__) +# define WE_ARE_BIG_ENDIAN 0 +# define WE_ARE_LITTLE_ENDIAN 1 +#else +# error "Can't determine endianness" +#endif + +#include +#include /* struct elf_prstatus */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +#define NOTE_DATA(_hdr) STRUCT_MEMBER_P((_hdr), sizeof (Elf32_Nhdr) + UNW_ALIGN((_hdr)->n_namesz, 4)) +#define NOTE_SIZE(_hdr) (sizeof (Elf32_Nhdr) + UNW_ALIGN((_hdr)->n_namesz, 4) + (_hdr)->n_descsz) +#define NOTE_NEXT(_hdr) STRUCT_MEMBER_P((_hdr), NOTE_SIZE(_hdr)) +#define NOTE_FITS_IN(_hdr, _size) ((_size) >= sizeof (Elf32_Nhdr) && (_size) >= NOTE_SIZE (_hdr)) +#define NOTE_FITS(_hdr, _end) NOTE_FITS_IN((_hdr), (unsigned long)((char *)(_end) - (char *)(_hdr))) + +struct UCD_info * +_UCD_create(const char *filename) +{ + union + { + Elf32_Ehdr h32; + Elf64_Ehdr h64; + } elf_header; +#define elf_header32 elf_header.h32 +#define elf_header64 elf_header.h64 + bool _64bits; + + struct UCD_info *ui = memset(malloc(sizeof(*ui)), 0, sizeof(*ui)); + ui->edi.di_cache.format = -1; + ui->edi.di_debug.format = -1; +#if UNW_TARGET_IA64 + ui->edi.ktab.format = -1; +#endif + + int fd = ui->coredump_fd = open(filename, O_RDONLY); + if (fd < 0) + goto err; + ui->coredump_filename = strdup(filename); + + /* No sane ELF32 file is going to be smaller then ELF64 _header_, + * so let's just read 64-bit sized one. + */ + if (read(fd, &elf_header64, sizeof(elf_header64)) != sizeof(elf_header64)) + { + Debug(0, "'%s' is not an ELF file\n", filename); + goto err; + } + + if (memcmp(&elf_header32, ELFMAG, SELFMAG) != 0) + { + Debug(0, "'%s' is not an ELF file\n", filename); + goto err; + } + + if (elf_header32.e_ident[EI_CLASS] != ELFCLASS32 + && elf_header32.e_ident[EI_CLASS] != ELFCLASS64) + { + Debug(0, "'%s' is not a 32/64 bit ELF file\n", filename); + goto err; + } + + if (WE_ARE_LITTLE_ENDIAN != (elf_header32.e_ident[EI_DATA] == ELFDATA2LSB)) + { + Debug(0, "'%s' is endian-incompatible\n", filename); + goto err; + } + + _64bits = (elf_header32.e_ident[EI_CLASS] == ELFCLASS64); + if (_64bits && sizeof(elf_header64.e_entry) > sizeof(off_t)) + { + Debug(0, "Can't process '%s': 64-bit file " + "while only %ld bits are supported", + filename, 8L * sizeof(off_t)); + goto err; + } + + /* paranoia check */ + if (_64bits + ? 0 /* todo: (elf_header64.e_ehsize != NN || elf_header64.e_phentsize != NN) */ + : (elf_header32.e_ehsize != 52 || elf_header32.e_phentsize != 32) + ) + { + Debug(0, "'%s' has wrong e_ehsize or e_phentsize\n", filename); + goto err; + } + + off_t ofs = (_64bits ? elf_header64.e_phoff : elf_header32.e_phoff); + if (lseek(fd, ofs, SEEK_SET) != ofs) + { + Debug(0, "Can't read phdrs from '%s'\n", filename); + goto err; + } + unsigned size = ui->phdrs_count = (_64bits ? elf_header64.e_phnum : elf_header32.e_phnum); + coredump_phdr_t *phdrs = ui->phdrs = memset(malloc(size * sizeof(phdrs[0])), 0, size * sizeof(phdrs[0])); + if (_64bits) + { + coredump_phdr_t *cur = phdrs; + unsigned i = 0; + while (i < size) + { + Elf64_Phdr hdr64; + if (read(fd, &hdr64, sizeof(hdr64)) != sizeof(hdr64)) + { + Debug(0, "Can't read phdrs from '%s'\n", filename); + goto err; + } + cur->p_type = hdr64.p_type ; + cur->p_flags = hdr64.p_flags ; + cur->p_offset = hdr64.p_offset; + cur->p_vaddr = hdr64.p_vaddr ; + /*cur->p_paddr = hdr32.p_paddr ; always 0 */ +//TODO: check that and abort if it isn't? + cur->p_filesz = hdr64.p_filesz; + cur->p_memsz = hdr64.p_memsz ; + cur->p_align = hdr64.p_align ; + /* cur->backing_filename = NULL; - done by memset */ + cur->backing_fd = -1; + cur->backing_filesize = hdr64.p_filesz; + i++; + cur++; + } + } else { + coredump_phdr_t *cur = phdrs; + unsigned i = 0; + while (i < size) + { + Elf32_Phdr hdr32; + if (read(fd, &hdr32, sizeof(hdr32)) != sizeof(hdr32)) + { + Debug(0, "Can't read phdrs from '%s'\n", filename); + goto err; + } + cur->p_type = hdr32.p_type ; + cur->p_flags = hdr32.p_flags ; + cur->p_offset = hdr32.p_offset; + cur->p_vaddr = hdr32.p_vaddr ; + /*cur->p_paddr = hdr32.p_paddr ; always 0 */ + cur->p_filesz = hdr32.p_filesz; + cur->p_memsz = hdr32.p_memsz ; + cur->p_align = hdr32.p_align ; + /* cur->backing_filename = NULL; - done by memset */ + cur->backing_fd = -1; + cur->backing_filesize = hdr32.p_memsz; + i++; + cur++; + } + } + + unsigned i = 0; + coredump_phdr_t *cur = phdrs; + while (i < size) + { + Debug(2, "phdr[%03d]: type:%d", i, cur->p_type); + if (cur->p_type == PT_NOTE) + { + Elf32_Nhdr *note_hdr, *note_end; + unsigned n_threads; + + ui->note_phdr = malloc(cur->p_filesz); + if (lseek(fd, cur->p_offset, SEEK_SET) != (off_t)cur->p_offset + || (uoff_t)read(fd, ui->note_phdr, cur->p_filesz) != cur->p_filesz) + { + Debug(0, "Can't read PT_NOTE from '%s'\n", filename); + goto err; + } + + note_end = STRUCT_MEMBER_P (ui->note_phdr, cur->p_filesz); + + /* Count number of threads */ + n_threads = 0; + note_hdr = (Elf32_Nhdr *)ui->note_phdr; + while (NOTE_FITS (note_hdr, note_end)) + { + if (note_hdr->n_type == NT_PRSTATUS) + n_threads++; + + note_hdr = NOTE_NEXT (note_hdr); + } + + ui->n_threads = n_threads; + ui->threads = malloc(sizeof (void *) * n_threads); + + n_threads = 0; + note_hdr = (Elf32_Nhdr *)ui->note_phdr; + while (NOTE_FITS (note_hdr, note_end)) + { + if (note_hdr->n_type == NT_PRSTATUS) + ui->threads[n_threads++] = NOTE_DATA (note_hdr); + + note_hdr = NOTE_NEXT (note_hdr); + } + } + if (cur->p_type == PT_LOAD) + { + Debug(2, " ofs:%08llx va:%08llx filesize:%08llx memsize:%08llx flg:%x", + (unsigned long long) cur->p_offset, + (unsigned long long) cur->p_vaddr, + (unsigned long long) cur->p_filesz, + (unsigned long long) cur->p_memsz, + cur->p_flags + ); + if (cur->p_filesz < cur->p_memsz) + Debug(2, " partial"); + if (cur->p_flags & PF_X) + Debug(2, " executable"); + } + Debug(2, "\n"); + i++; + cur++; + } + + if (ui->n_threads == 0) + { + Debug(0, "No NT_PRSTATUS note found in '%s'\n", filename); + goto err; + } + + ui->prstatus = ui->threads[0]; + + return ui; + + err: + _UCD_destroy(ui); + return NULL; +} + +int _UCD_get_num_threads(struct UCD_info *ui) +{ + return ui->n_threads; +} + +void _UCD_select_thread(struct UCD_info *ui, int n) +{ + if (n >= 0 && n < ui->n_threads) + ui->prstatus = ui->threads[n]; +} + +pid_t _UCD_get_pid(struct UCD_info *ui) +{ + return ui->prstatus->pr_pid; +} + +int _UCD_get_cursig(struct UCD_info *ui) +{ + return ui->prstatus->pr_cursig; +} + +int _UCD_add_backing_file_at_segment(struct UCD_info *ui, int phdr_no, const char *filename) +{ + if ((unsigned)phdr_no >= ui->phdrs_count) + { + Debug(0, "There is no segment %d in this coredump\n", phdr_no); + return -1; + } + + struct coredump_phdr *phdr = &ui->phdrs[phdr_no]; + if (phdr->backing_filename) + { + Debug(0, "Backing file already added to segment %d\n", phdr_no); + return -1; + } + + int fd = open(filename, O_RDONLY); + if (fd < 0) + { + Debug(0, "Can't open '%s'\n", filename); + return -1; + } + + phdr->backing_fd = fd; + phdr->backing_filename = strdup(filename); + + struct stat statbuf; + if (fstat(fd, &statbuf) != 0) + { + Debug(0, "Can't stat '%s'\n", filename); + goto err; + } + phdr->backing_filesize = (uoff_t)statbuf.st_size; + + if (phdr->p_flags != (PF_X | PF_R)) + Debug(1, "Note: phdr[%u] is not r-x: flags are 0x%x\n", phdr_no, phdr->p_flags); + + if (phdr->backing_filesize > phdr->p_memsz) + { + /* This is expected */ + Debug(2, "Note: phdr[%u] is %lld bytes, file is larger: %lld bytes\n", + phdr_no, + (unsigned long long)phdr->p_memsz, + (unsigned long long)phdr->backing_filesize + ); + } +//TODO: else loudly complain? Maybe even fail? + + if (phdr->p_filesz != 0) + { +//TODO: loop and compare in smaller blocks + char *core_buf = malloc(phdr->p_filesz); + char *file_buf = malloc(phdr->p_filesz); + if (lseek(ui->coredump_fd, phdr->p_offset, SEEK_SET) != (off_t)phdr->p_offset + || (uoff_t)read(ui->coredump_fd, core_buf, phdr->p_filesz) != phdr->p_filesz + ) + { + Debug(0, "Error reading from coredump file\n"); + err_read: + free(core_buf); + free(file_buf); + goto err; + } + if ((uoff_t)read(fd, file_buf, phdr->p_filesz) != phdr->p_filesz) + { + Debug(0, "Error reading from '%s'\n", filename); + goto err_read; + } + int r = memcmp(core_buf, file_buf, phdr->p_filesz); + free(core_buf); + free(file_buf); + if (r != 0) + { + Debug(1, "Note: phdr[%u] first %lld bytes in core dump and in file do not match\n", + phdr_no, (unsigned long long)phdr->p_filesz + ); + } else { + Debug(1, "Note: phdr[%u] first %lld bytes in core dump and in file match\n", + phdr_no, (unsigned long long)phdr->p_filesz + ); + } + } + + /* Success */ + return 0; + + err: + if (phdr->backing_fd >= 0) + { + close(phdr->backing_fd); + phdr->backing_fd = -1; + } + free(phdr->backing_filename); + phdr->backing_filename = NULL; + return -1; +} + +int _UCD_add_backing_file_at_vaddr(struct UCD_info *ui, + unsigned long vaddr, + const char *filename) +{ + unsigned i; + for (i = 0; i < ui->phdrs_count; i++) + { + struct coredump_phdr *phdr = &ui->phdrs[i]; + if (phdr->p_vaddr != vaddr) + continue; + /* It seems to match. Add it. */ + return _UCD_add_backing_file_at_segment(ui, i, filename); + } + return -1; +} diff --git a/src/libs/libunwind/coredump/_UCD_destroy.c b/src/libs/libunwind/coredump/_UCD_destroy.c new file mode 100644 index 0000000000..5aff989ccc --- /dev/null +++ b/src/libs/libunwind/coredump/_UCD_destroy.c @@ -0,0 +1,50 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_internal.h" + +void +_UCD_destroy (struct UCD_info *ui) +{ + if (!ui) + return; + + if (ui->coredump_fd >= 0) + close(ui->coredump_fd); + free(ui->coredump_filename); + + invalidate_edi (&ui->edi); + + unsigned i; + for (i = 0; i < ui->phdrs_count; i++) + { + struct coredump_phdr *phdr = &ui->phdrs[i]; + free(phdr->backing_filename); + if (phdr->backing_fd >= 0) + close(phdr->backing_fd); + } + + free(ui->note_phdr); + + free(ui); +} diff --git a/src/libs/libunwind/coredump/_UCD_elf_map_image.c b/src/libs/libunwind/coredump/_UCD_elf_map_image.c new file mode 100644 index 0000000000..4b3db0bbff --- /dev/null +++ b/src/libs/libunwind/coredump/_UCD_elf_map_image.c @@ -0,0 +1,98 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +static coredump_phdr_t * +CD_elf_map_image(struct UCD_info *ui, coredump_phdr_t *phdr) +{ + struct elf_image *ei = &ui->edi.ei; + + if (phdr->backing_fd < 0) + { + /* Note: coredump file contains only phdr->p_filesz bytes. + * We want to map bigger area (phdr->p_memsz bytes) to make sure + * these pages are allocated, but non-accessible. + */ + /* addr, length, prot, flags, fd, fd_offset */ + ei->image = mmap(NULL, phdr->p_memsz, PROT_READ, MAP_PRIVATE, ui->coredump_fd, phdr->p_offset); + if (ei->image == MAP_FAILED) + { + ei->image = NULL; + return NULL; + } + ei->size = phdr->p_filesz; + size_t remainder_len = phdr->p_memsz - phdr->p_filesz; + if (remainder_len > 0) + { + void *remainder_base = (char*) ei->image + phdr->p_filesz; + munmap(remainder_base, remainder_len); + } + } else { + /* We have a backing file for this segment. + * This file is always longer than phdr->p_memsz, + * and if phdr->p_filesz !=0, first phdr->p_filesz bytes in coredump + * are the same as first bytes in the file. (Thus no need to map coredump) + * We map the entire file: + * unwinding may need data which is past phdr->p_memsz bytes. + */ + /* addr, length, prot, flags, fd, fd_offset */ + ei->image = mmap(NULL, phdr->backing_filesize, PROT_READ, MAP_PRIVATE, phdr->backing_fd, 0); + if (ei->image == MAP_FAILED) + { + ei->image = NULL; + return NULL; + } + ei->size = phdr->backing_filesize; + } + + /* Check ELF header for sanity */ + if (!elf_w(valid_object)(ei)) + { + munmap(ei->image, ei->size); + ei->image = NULL; + ei->size = 0; + return NULL; + } + + return phdr; +} + +HIDDEN coredump_phdr_t * +_UCD_get_elf_image(struct UCD_info *ui, unw_word_t ip) +{ + unsigned i; + for (i = 0; i < ui->phdrs_count; i++) + { + coredump_phdr_t *phdr = &ui->phdrs[i]; + if (phdr->p_vaddr <= ip && ip < phdr->p_vaddr + phdr->p_memsz) + { + phdr = CD_elf_map_image(ui, phdr); + return phdr; + } + } + return NULL; +} diff --git a/src/libs/libunwind/coredump/_UCD_find_proc_info.c b/src/libs/libunwind/coredump/_UCD_find_proc_info.c new file mode 100644 index 0000000000..33b66c8edb --- /dev/null +++ b/src/libs/libunwind/coredump/_UCD_find_proc_info.c @@ -0,0 +1,163 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +static int +get_unwind_info(struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip) +{ + unsigned long segbase, mapoff; + +#if UNW_TARGET_IA64 && defined(__linux) + if (!ui->edi.ktab.start_ip && _Uia64_get_kernel_table (&ui->edi.ktab) < 0) + return -UNW_ENOINFO; + + if (ui->edi.ktab.format != -1 && ip >= ui->edi.ktab.start_ip && ip < ui->edi.ktab.end_ip) + return 0; +#endif + + if ((ui->edi.di_cache.format != -1 + && ip >= ui->edi.di_cache.start_ip && ip < ui->edi.di_cache.end_ip) +#if UNW_TARGET_ARM + || (ui->edi.di_debug.format != -1 + && ip >= ui->edi.di_arm.start_ip && ip < ui->edi.di_arm.end_ip) +#endif + || (ui->edi.di_debug.format != -1 + && ip >= ui->edi.di_debug.start_ip && ip < ui->edi.di_debug.end_ip)) + return 0; + + invalidate_edi (&ui->edi); + + /* Used to be tdep_get_elf_image() in ptrace unwinding code */ + coredump_phdr_t *phdr = _UCD_get_elf_image(ui, ip); + if (!phdr) + { + Debug(1, "returns error: _UCD_get_elf_image failed\n"); + return -UNW_ENOINFO; + } + /* segbase: where it is mapped in virtual memory */ + /* mapoff: offset in the file */ + segbase = phdr->p_vaddr; + /*mapoff = phdr->p_offset; WRONG! phdr->p_offset is the offset in COREDUMP file */ + mapoff = 0; +///FIXME. text segment is USUALLY, not always, at offset 0 in the binary/.so file. +// ensure that at initialization. + + /* Here, SEGBASE is the starting-address of the (mmap'ped) segment + which covers the IP we're looking for. */ + if (tdep_find_unwind_table(&ui->edi, as, phdr->backing_filename, segbase, mapoff, ip) < 0) + { + Debug(1, "returns error: tdep_find_unwind_table failed\n"); + return -UNW_ENOINFO; + } + + /* This can happen in corner cases where dynamically generated + code falls into the same page that contains the data-segment + and the page-offset of the code is within the first page of + the executable. */ + if (ui->edi.di_cache.format != -1 + && (ip < ui->edi.di_cache.start_ip || ip >= ui->edi.di_cache.end_ip)) + ui->edi.di_cache.format = -1; + + if (ui->edi.di_debug.format != -1 + && (ip < ui->edi.di_debug.start_ip || ip >= ui->edi.di_debug.end_ip)) + ui->edi.di_debug.format = -1; + + if (ui->edi.di_cache.format == -1 +#if UNW_TARGET_ARM + && ui->edi.di_arm.format == -1 +#endif + && ui->edi.di_debug.format == -1) + { + Debug(1, "returns error: all formats are -1\n"); + return -UNW_ENOINFO; + } + + Debug(1, "returns success\n"); + return 0; +} + +int +_UCD_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + struct UCD_info *ui = arg; + + Debug(1, "entering\n"); + + int ret = -UNW_ENOINFO; + + if (get_unwind_info(ui, as, ip) < 0) { + Debug(1, "returns error: get_unwind_info failed\n"); + return -UNW_ENOINFO; + } + +#if UNW_TARGET_IA64 + if (ui->edi.ktab.format != -1) + { + /* The kernel unwind table resides in local memory, so we have + to use the local address space to search it. Since + _UCD_put_unwind_info() has no easy way of detecting this + case, we simply make a copy of the unwind-info, so + _UCD_put_unwind_info() can always free() the unwind-info + without ill effects. */ + ret = tdep_search_unwind_table (unw_local_addr_space, ip, &ui->edi.ktab, pi, + need_unwind_info, arg); + if (ret >= 0) + { + if (!need_unwind_info) + pi->unwind_info = NULL; + else + { + void *mem = malloc (pi->unwind_info_size); + + if (!mem) + return -UNW_ENOMEM; + memcpy (mem, pi->unwind_info, pi->unwind_info_size); + pi->unwind_info = mem; + } + } + } +#endif + + if (ret == -UNW_ENOINFO && ui->edi.di_cache.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_cache, + pi, need_unwind_info, arg); + +#if UNW_TARGET_ARM + if (ret == -UNW_ENOINFO && ui->edi.di_arm.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_arm, pi, + need_unwind_info, arg); +#endif + + if (ret == -UNW_ENOINFO && ui->edi.di_debug.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_debug, pi, + need_unwind_info, arg); + + Debug(1, "returns %d\n", ret); + + return ret; +} diff --git a/src/libs/libunwind/coredump/_UCD_get_proc_name.c b/src/libs/libunwind/coredump/_UCD_get_proc_name.c new file mode 100644 index 0000000000..00096c48d0 --- /dev/null +++ b/src/libs/libunwind/coredump/_UCD_get_proc_name.c @@ -0,0 +1,70 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + + +/* Find the ELF image that contains IP and return the "closest" + procedure name, if there is one. With some caching, this could be + sped up greatly, but until an application materializes that's + sensitive to the performance of this routine, why bother... */ +static int +elf_w (CD_get_proc_name) (struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp) +{ + unsigned long segbase, mapoff; + int ret; + + /* Used to be tdep_get_elf_image() in ptrace unwinding code */ + coredump_phdr_t *cphdr = _UCD_get_elf_image(ui, ip); + if (!cphdr) + { + Debug(1, "returns error: _UCD_get_elf_image failed\n"); + return -UNW_ENOINFO; + } + /* segbase: where it is mapped in virtual memory */ + /* mapoff: offset in the file */ + segbase = cphdr->p_vaddr; + /*mapoff = phdr->p_offset; WRONG! phdr->p_offset is the offset in COREDUMP file */ + mapoff = 0; + + ret = elf_w (get_proc_name_in_image) (as, &ui->edi.ei, segbase, mapoff, ip, buf, buf_len, offp); + + return ret; +} + +int +_UCD_get_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, void *arg) +{ + struct UCD_info *ui = arg; + +#if ELF_CLASS == ELFCLASS64 + return _Uelf64_CD_get_proc_name (ui, as, ip, buf, buf_len, offp); +#elif ELF_CLASS == ELFCLASS32 + return _Uelf32_CD_get_proc_name (ui, as, ip, buf, buf_len, offp); +#else + return -UNW_ENOINFO; +#endif +} diff --git a/src/libs/libunwind/coredump/_UCD_internal.h b/src/libs/libunwind/coredump/_UCD_internal.h new file mode 100644 index 0000000000..3c95a2a003 --- /dev/null +++ b/src/libs/libunwind/coredump/_UCD_internal.h @@ -0,0 +1,105 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _UCD_internal_h +#define _UCD_internal_h + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_PROCFS_H +#include /* struct elf_prstatus */ +#endif +#include +#include +#include +#include +#include + +#include + +#include "libunwind_i.h" + + +#if SIZEOF_OFF_T == 4 +typedef uint32_t uoff_t; +#elif SIZEOF_OFF_T == 8 +typedef uint64_t uoff_t; +#else +# error Unknown size of off_t! +#endif + + +/* Similar to ELF phdrs. p_paddr element is absent, + * since it's always 0 in coredumps. + */ +struct coredump_phdr + { + uint32_t p_type; + uint32_t p_flags; + uoff_t p_offset; + uoff_t p_vaddr; + uoff_t p_filesz; + uoff_t p_memsz; + uoff_t p_align; + /* Data for backing file. If backing_fd < 0, there is no file */ + uoff_t backing_filesize; + char *backing_filename; /* for error meesages only */ + int backing_fd; + }; + +typedef struct coredump_phdr coredump_phdr_t; + +#if defined(HAVE_STRUCT_ELF_PRSTATUS) +#define PRSTATUS_STRUCT elf_prstatus +#elif defined(HAVE_STRUCT_PRSTATUS) +#define PRSTATUS_STRUCT prstatus +#else +#define PRSTATUS_STRUCT non_existent +#endif + +struct UCD_info + { + int big_endian; /* bool */ + int coredump_fd; + char *coredump_filename; /* for error meesages only */ + coredump_phdr_t *phdrs; /* array, allocated */ + unsigned phdrs_count; + void *note_phdr; /* allocated or NULL */ + struct PRSTATUS_STRUCT *prstatus; /* points inside note_phdr */ + int n_threads; + struct PRSTATUS_STRUCT **threads; + + struct elf_dyn_info edi; + }; + +extern coredump_phdr_t * _UCD_get_elf_image(struct UCD_info *ui, unw_word_t ip); + +#define STRUCT_MEMBER_P(struct_p, struct_offset) ((void *) ((char*) (struct_p) + (long) (struct_offset))) +#define STRUCT_MEMBER(member_type, struct_p, struct_offset) (*(member_type*) STRUCT_MEMBER_P ((struct_p), (struct_offset))) + +#endif diff --git a/src/libs/libunwind/coredump/_UCD_lib.h b/src/libs/libunwind/coredump/_UCD_lib.h new file mode 100644 index 0000000000..22be32ed1e --- /dev/null +++ b/src/libs/libunwind/coredump/_UCD_lib.h @@ -0,0 +1,57 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _UCD_lib_h +#define _UCD_lib_h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/src/libs/libunwind/coredump/_UPT_access_fpreg.c b/src/libs/libunwind/coredump/_UPT_access_fpreg.c new file mode 100644 index 0000000000..0b8b86ac90 --- /dev/null +++ b/src/libs/libunwind/coredump/_UPT_access_fpreg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +int +_UCD_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + print_error (__func__); + print_error (" not implemented\n"); + return -UNW_EINVAL; +} diff --git a/src/libs/libunwind/coredump/_UPT_elf.c b/src/libs/libunwind/coredump/_UPT_elf.c new file mode 100644 index 0000000000..fb7b19a7cb --- /dev/null +++ b/src/libs/libunwind/coredump/_UPT_elf.c @@ -0,0 +1,5 @@ +/* We need to get a separate copy of the ELF-code into + libunwind-coredump since it cannot (and must not) have any ELF + dependencies on libunwind. */ +#include "libunwind_i.h" /* get ELFCLASS defined */ +#include "../elfxx.c" diff --git a/src/libs/libunwind/coredump/_UPT_get_dyn_info_list_addr.c b/src/libs/libunwind/coredump/_UPT_get_dyn_info_list_addr.c new file mode 100644 index 0000000000..0d11905566 --- /dev/null +++ b/src/libs/libunwind/coredump/_UPT_get_dyn_info_list_addr.c @@ -0,0 +1,108 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +#if UNW_TARGET_IA64 && defined(__linux) +# include "elf64.h" +# include "os-linux.h" + +static inline int +get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, + int *countp) +{ + unsigned long lo, hi, off; + struct UPT_info *ui = arg; + struct map_iterator mi; + char path[PATH_MAX]; + unw_dyn_info_t *di; + unw_word_t res; + int count = 0; + + maps_init (&mi, ui->pid); + while (maps_next (&mi, &lo, &hi, &off)) + { + if (off) + continue; + + invalidate_edi (&ui->edi); + + if (elf_map_image (&ui->ei, path) < 0) + /* ignore unmappable stuff like "/SYSV00001b58 (deleted)" */ + continue; + + Debug (16, "checking object %s\n", path); + + di = tdep_find_unwind_table (&ui->edi, as, path, lo, off); + if (di) + { + res = _Uia64_find_dyn_list (as, di, arg); + if (res && count++ == 0) + { + Debug (12, "dyn_info_list_addr = 0x%lx\n", (long) res); + *dil_addr = res; + } + } + } + maps_close (&mi); + *countp = count; + return 0; +} + +#else + +static inline int +get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, + int *countp) +{ +# warning Implement get_list_addr(), please. + *countp = 0; + return 0; +} + +#endif + +int +_UCD_get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, + void *arg) +{ + int count, ret; + + Debug (12, "looking for dyn_info list\n"); + + if ((ret = get_list_addr (as, dil_addr, arg, &count)) < 0) + return ret; + + /* If multiple dynamic-info list addresses are found, we would have + to determine which was is the one actually in use (since the + dynamic name resolution algorithm will pick one "winner"). + Perhaps we'd have to track them all until we find one that's + non-empty. Hopefully, this case simply will never arise, since + only libunwind defines the dynamic info list head. */ + assert (count <= 1); + + return (count > 0) ? 0 : -UNW_ENOINFO; +} diff --git a/src/libs/libunwind/coredump/_UPT_put_unwind_info.c b/src/libs/libunwind/coredump/_UPT_put_unwind_info.c new file mode 100644 index 0000000000..462e1d048c --- /dev/null +++ b/src/libs/libunwind/coredump/_UPT_put_unwind_info.c @@ -0,0 +1,36 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +void +_UCD_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) +{ + if (!pi->unwind_info) + return; + free (pi->unwind_info); + pi->unwind_info = NULL; +} diff --git a/src/libs/libunwind/coredump/_UPT_resume.c b/src/libs/libunwind/coredump/_UPT_resume.c new file mode 100644 index 0000000000..a729c908cb --- /dev/null +++ b/src/libs/libunwind/coredump/_UPT_resume.c @@ -0,0 +1,35 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +int +_UCD_resume (unw_addr_space_t as, unw_cursor_t *c, void *arg) +{ + print_error (__func__); + print_error (" not implemented\n"); + return -UNW_EINVAL; +} diff --git a/src/libs/libunwind/dwarf/Gexpr.c b/src/libs/libunwind/dwarf/Gexpr.c new file mode 100644 index 0000000000..b56bb317ab --- /dev/null +++ b/src/libs/libunwind/dwarf/Gexpr.c @@ -0,0 +1,648 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "dwarf_i.h" +#include "libunwind_i.h" + +/* The "pick" operator provides an index range of 0..255 indicating + that the stack could at least have a depth of up to 256 elements, + but the GCC unwinder restricts the depth to 64, which seems + reasonable so we use the same value here. */ +#define MAX_EXPR_STACK_SIZE 64 + +#define NUM_OPERANDS(signature) (((signature) >> 6) & 0x3) +#define OPND1_TYPE(signature) (((signature) >> 3) & 0x7) +#define OPND2_TYPE(signature) (((signature) >> 0) & 0x7) + +#define OPND_SIGNATURE(n, t1, t2) (((n) << 6) | ((t1) << 3) | ((t2) << 0)) +#define OPND1(t1) OPND_SIGNATURE(1, t1, 0) +#define OPND2(t1, t2) OPND_SIGNATURE(2, t1, t2) + +#define VAL8 0x0 +#define VAL16 0x1 +#define VAL32 0x2 +#define VAL64 0x3 +#define ULEB128 0x4 +#define SLEB128 0x5 +#define OFFSET 0x6 /* 32-bit offset for 32-bit DWARF, 64-bit otherwise */ +#define ADDR 0x7 /* Machine address. */ + +static const uint8_t operands[256] = + { + [DW_OP_addr] = OPND1 (ADDR), + [DW_OP_const1u] = OPND1 (VAL8), + [DW_OP_const1s] = OPND1 (VAL8), + [DW_OP_const2u] = OPND1 (VAL16), + [DW_OP_const2s] = OPND1 (VAL16), + [DW_OP_const4u] = OPND1 (VAL32), + [DW_OP_const4s] = OPND1 (VAL32), + [DW_OP_const8u] = OPND1 (VAL64), + [DW_OP_const8s] = OPND1 (VAL64), + [DW_OP_pick] = OPND1 (VAL8), + [DW_OP_plus_uconst] = OPND1 (ULEB128), + [DW_OP_skip] = OPND1 (VAL16), + [DW_OP_bra] = OPND1 (VAL16), + [DW_OP_breg0 + 0] = OPND1 (SLEB128), + [DW_OP_breg0 + 1] = OPND1 (SLEB128), + [DW_OP_breg0 + 2] = OPND1 (SLEB128), + [DW_OP_breg0 + 3] = OPND1 (SLEB128), + [DW_OP_breg0 + 4] = OPND1 (SLEB128), + [DW_OP_breg0 + 5] = OPND1 (SLEB128), + [DW_OP_breg0 + 6] = OPND1 (SLEB128), + [DW_OP_breg0 + 7] = OPND1 (SLEB128), + [DW_OP_breg0 + 8] = OPND1 (SLEB128), + [DW_OP_breg0 + 9] = OPND1 (SLEB128), + [DW_OP_breg0 + 10] = OPND1 (SLEB128), + [DW_OP_breg0 + 11] = OPND1 (SLEB128), + [DW_OP_breg0 + 12] = OPND1 (SLEB128), + [DW_OP_breg0 + 13] = OPND1 (SLEB128), + [DW_OP_breg0 + 14] = OPND1 (SLEB128), + [DW_OP_breg0 + 15] = OPND1 (SLEB128), + [DW_OP_breg0 + 16] = OPND1 (SLEB128), + [DW_OP_breg0 + 17] = OPND1 (SLEB128), + [DW_OP_breg0 + 18] = OPND1 (SLEB128), + [DW_OP_breg0 + 19] = OPND1 (SLEB128), + [DW_OP_breg0 + 20] = OPND1 (SLEB128), + [DW_OP_breg0 + 21] = OPND1 (SLEB128), + [DW_OP_breg0 + 22] = OPND1 (SLEB128), + [DW_OP_breg0 + 23] = OPND1 (SLEB128), + [DW_OP_breg0 + 24] = OPND1 (SLEB128), + [DW_OP_breg0 + 25] = OPND1 (SLEB128), + [DW_OP_breg0 + 26] = OPND1 (SLEB128), + [DW_OP_breg0 + 27] = OPND1 (SLEB128), + [DW_OP_breg0 + 28] = OPND1 (SLEB128), + [DW_OP_breg0 + 29] = OPND1 (SLEB128), + [DW_OP_breg0 + 30] = OPND1 (SLEB128), + [DW_OP_breg0 + 31] = OPND1 (SLEB128), + [DW_OP_regx] = OPND1 (ULEB128), + [DW_OP_fbreg] = OPND1 (SLEB128), + [DW_OP_bregx] = OPND2 (ULEB128, SLEB128), + [DW_OP_piece] = OPND1 (ULEB128), + [DW_OP_deref_size] = OPND1 (VAL8), + [DW_OP_xderef_size] = OPND1 (VAL8), + [DW_OP_call2] = OPND1 (VAL16), + [DW_OP_call4] = OPND1 (VAL32), + [DW_OP_call_ref] = OPND1 (OFFSET) + }; + +static inline unw_sword_t +sword (unw_addr_space_t as, unw_word_t val) +{ + switch (dwarf_addr_size (as)) + { + case 1: return (int8_t) val; + case 2: return (int16_t) val; + case 4: return (int32_t) val; + case 8: return (int64_t) val; + default: abort (); + } +} + +static inline unw_word_t +read_operand (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int operand_type, unw_word_t *val, void *arg) +{ + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint64_t u64; + int ret; + + if (operand_type == ADDR) + switch (dwarf_addr_size (as)) + { + case 1: operand_type = VAL8; break; + case 2: operand_type = VAL16; break; + case 4: operand_type = VAL32; break; + case 8: operand_type = VAL64; break; + default: abort (); + } + + switch (operand_type) + { + case VAL8: + ret = dwarf_readu8 (as, a, addr, &u8, arg); + if (ret < 0) + return ret; + *val = u8; + break; + + case VAL16: + ret = dwarf_readu16 (as, a, addr, &u16, arg); + if (ret < 0) + return ret; + *val = u16; + break; + + case VAL32: + ret = dwarf_readu32 (as, a, addr, &u32, arg); + if (ret < 0) + return ret; + *val = u32; + break; + + case VAL64: + ret = dwarf_readu64 (as, a, addr, &u64, arg); + if (ret < 0) + return ret; + *val = u64; + break; + + case ULEB128: + ret = dwarf_read_uleb128 (as, a, addr, val, arg); + break; + + case SLEB128: + ret = dwarf_read_sleb128 (as, a, addr, val, arg); + break; + + case OFFSET: /* only used by DW_OP_call_ref, which we don't implement */ + default: + Debug (1, "Unexpected operand type %d\n", operand_type); + ret = -UNW_EINVAL; + } + return ret; +} + +HIDDEN int +dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, unw_word_t len, + unw_word_t *valp, int *is_register) +{ + unw_word_t operand1 = 0, operand2 = 0, tmp1, tmp2, tmp3, end_addr; + uint8_t opcode, operands_signature, u8; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + unw_word_t stack[MAX_EXPR_STACK_SIZE]; + unsigned int tos = 0; + uint16_t u16; + uint32_t u32; + uint64_t u64; + int ret; +# define pop() \ +({ \ + if ((tos - 1) >= MAX_EXPR_STACK_SIZE) \ + { \ + Debug (1, "Stack underflow\n"); \ + return -UNW_EINVAL; \ + } \ + stack[--tos]; \ +}) +# define push(x) \ +do { \ + unw_word_t _x = (x); \ + if (tos >= MAX_EXPR_STACK_SIZE) \ + { \ + Debug (1, "Stack overflow\n"); \ + return -UNW_EINVAL; \ + } \ + stack[tos++] = _x; \ +} while (0) +# define pick(n) \ +({ \ + unsigned int _index = tos - 1 - (n); \ + if (_index >= MAX_EXPR_STACK_SIZE) \ + { \ + Debug (1, "Out-of-stack pick\n"); \ + return -UNW_EINVAL; \ + } \ + stack[_index]; \ +}) + + as = c->as; + arg = c->as_arg; + a = unw_get_accessors (as); + end_addr = *addr + len; + *is_register = 0; + + Debug (14, "len=%lu, pushing cfa=0x%lx\n", + (unsigned long) len, (unsigned long) c->cfa); + + push (c->cfa); /* push current CFA as required by DWARF spec */ + + while (*addr < end_addr) + { + if ((ret = dwarf_readu8 (as, a, addr, &opcode, arg)) < 0) + return ret; + + operands_signature = operands[opcode]; + + if (unlikely (NUM_OPERANDS (operands_signature) > 0)) + { + if ((ret = read_operand (as, a, addr, + OPND1_TYPE (operands_signature), + &operand1, arg)) < 0) + return ret; + if (NUM_OPERANDS (operands_signature) > 1) + if ((ret = read_operand (as, a, addr, + OPND2_TYPE (operands_signature), + &operand2, arg)) < 0) + return ret; + } + + switch ((dwarf_expr_op_t) opcode) + { + case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: + case DW_OP_lit3: case DW_OP_lit4: case DW_OP_lit5: + case DW_OP_lit6: case DW_OP_lit7: case DW_OP_lit8: + case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: + case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: + case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17: + case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20: + case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: + case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: + case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29: + case DW_OP_lit30: case DW_OP_lit31: + Debug (15, "OP_lit(%d)\n", (int) opcode - DW_OP_lit0); + push (opcode - DW_OP_lit0); + break; + + case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: + case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5: + case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8: + case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: + case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: + case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17: + case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20: + case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: + case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: + case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29: + case DW_OP_breg30: case DW_OP_breg31: + Debug (15, "OP_breg(r%d,0x%lx)\n", + (int) opcode - DW_OP_breg0, (unsigned long) operand1); + if ((ret = unw_get_reg (dwarf_to_cursor (c), + dwarf_to_unw_regnum (opcode - DW_OP_breg0), + &tmp1)) < 0) + return ret; + push (tmp1 + operand1); + break; + + case DW_OP_bregx: + Debug (15, "OP_bregx(r%d,0x%lx)\n", + (int) operand1, (unsigned long) operand2); + if ((ret = unw_get_reg (dwarf_to_cursor (c), + dwarf_to_unw_regnum (operand1), &tmp1)) < 0) + return ret; + push (tmp1 + operand2); + break; + + case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: + case DW_OP_reg3: case DW_OP_reg4: case DW_OP_reg5: + case DW_OP_reg6: case DW_OP_reg7: case DW_OP_reg8: + case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: + case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: + case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17: + case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20: + case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: + case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: + case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29: + case DW_OP_reg30: case DW_OP_reg31: + Debug (15, "OP_reg(r%d)\n", (int) opcode - DW_OP_reg0); + *valp = dwarf_to_unw_regnum (opcode - DW_OP_reg0); + *is_register = 1; + return 0; + + case DW_OP_regx: + Debug (15, "OP_regx(r%d)\n", (int) operand1); + *valp = dwarf_to_unw_regnum (operand1); + *is_register = 1; + return 0; + + case DW_OP_addr: + case DW_OP_const1u: + case DW_OP_const2u: + case DW_OP_const4u: + case DW_OP_const8u: + case DW_OP_constu: + case DW_OP_const8s: + case DW_OP_consts: + Debug (15, "OP_const(0x%lx)\n", (unsigned long) operand1); + push (operand1); + break; + + case DW_OP_const1s: + if (operand1 & 0x80) + operand1 |= ((unw_word_t) -1) << 8; + Debug (15, "OP_const1s(%ld)\n", (long) operand1); + push (operand1); + break; + + case DW_OP_const2s: + if (operand1 & 0x8000) + operand1 |= ((unw_word_t) -1) << 16; + Debug (15, "OP_const2s(%ld)\n", (long) operand1); + push (operand1); + break; + + case DW_OP_const4s: + if (operand1 & 0x80000000) + operand1 |= (((unw_word_t) -1) << 16) << 16; + Debug (15, "OP_const4s(%ld)\n", (long) operand1); + push (operand1); + break; + + case DW_OP_deref: + Debug (15, "OP_deref\n"); + tmp1 = pop (); + if ((ret = dwarf_readw (as, a, &tmp1, &tmp2, arg)) < 0) + return ret; + push (tmp2); + break; + + case DW_OP_deref_size: + Debug (15, "OP_deref_size(%d)\n", (int) operand1); + tmp1 = pop (); + switch (operand1) + { + default: + Debug (1, "Unexpected DW_OP_deref_size size %d\n", + (int) operand1); + return -UNW_EINVAL; + + case 1: + if ((ret = dwarf_readu8 (as, a, &tmp1, &u8, arg)) < 0) + return ret; + tmp2 = u8; + break; + + case 2: + if ((ret = dwarf_readu16 (as, a, &tmp1, &u16, arg)) < 0) + return ret; + tmp2 = u16; + break; + + case 3: + case 4: + if ((ret = dwarf_readu32 (as, a, &tmp1, &u32, arg)) < 0) + return ret; + tmp2 = u32; + if (operand1 == 3) + { + if (dwarf_is_big_endian (as)) + tmp2 >>= 8; + else + tmp2 &= 0xffffff; + } + break; + case 5: + case 6: + case 7: + case 8: + if ((ret = dwarf_readu64 (as, a, &tmp1, &u64, arg)) < 0) + return ret; + tmp2 = u64; + if (operand1 != 8) + { + if (dwarf_is_big_endian (as)) + tmp2 >>= 64 - 8 * operand1; + else + tmp2 &= (~ (unw_word_t) 0) << (8 * operand1); + } + break; + } + push (tmp2); + break; + + case DW_OP_dup: + Debug (15, "OP_dup\n"); + push (pick (0)); + break; + + case DW_OP_drop: + Debug (15, "OP_drop\n"); + (void) pop (); + break; + + case DW_OP_pick: + Debug (15, "OP_pick(%d)\n", (int) operand1); + push (pick (operand1)); + break; + + case DW_OP_over: + Debug (15, "OP_over\n"); + push (pick (1)); + break; + + case DW_OP_swap: + Debug (15, "OP_swap\n"); + tmp1 = pop (); + tmp2 = pop (); + push (tmp1); + push (tmp2); + break; + + case DW_OP_rot: + Debug (15, "OP_rot\n"); + tmp1 = pop (); + tmp2 = pop (); + tmp3 = pop (); + push (tmp1); + push (tmp3); + push (tmp2); + break; + + case DW_OP_abs: + Debug (15, "OP_abs\n"); + tmp1 = pop (); + if (tmp1 & ((unw_word_t) 1 << (8 * dwarf_addr_size (as) - 1))) + tmp1 = -tmp1; + push (tmp1); + break; + + case DW_OP_and: + Debug (15, "OP_and\n"); + tmp1 = pop (); + tmp2 = pop (); + push (tmp1 & tmp2); + break; + + case DW_OP_div: + Debug (15, "OP_div\n"); + tmp1 = pop (); + tmp2 = pop (); + if (tmp1) + tmp1 = sword (as, tmp2) / sword (as, tmp1); + push (tmp1); + break; + + case DW_OP_minus: + Debug (15, "OP_minus\n"); + tmp1 = pop (); + tmp2 = pop (); + tmp1 = tmp2 - tmp1; + push (tmp1); + break; + + case DW_OP_mod: + Debug (15, "OP_mod\n"); + tmp1 = pop (); + tmp2 = pop (); + if (tmp1) + tmp1 = tmp2 % tmp1; + push (tmp1); + break; + + case DW_OP_mul: + Debug (15, "OP_mul\n"); + tmp1 = pop (); + tmp2 = pop (); + if (tmp1) + tmp1 = tmp2 * tmp1; + push (tmp1); + break; + + case DW_OP_neg: + Debug (15, "OP_neg\n"); + push (-pop ()); + break; + + case DW_OP_not: + Debug (15, "OP_not\n"); + push (~pop ()); + break; + + case DW_OP_or: + Debug (15, "OP_or\n"); + tmp1 = pop (); + tmp2 = pop (); + push (tmp1 | tmp2); + break; + + case DW_OP_plus: + Debug (15, "OP_plus\n"); + tmp1 = pop (); + tmp2 = pop (); + push (tmp1 + tmp2); + break; + + case DW_OP_plus_uconst: + Debug (15, "OP_plus_uconst(%lu)\n", (unsigned long) operand1); + tmp1 = pop (); + push (tmp1 + operand1); + break; + + case DW_OP_shl: + Debug (15, "OP_shl\n"); + tmp1 = pop (); + tmp2 = pop (); + push (tmp2 << tmp1); + break; + + case DW_OP_shr: + Debug (15, "OP_shr\n"); + tmp1 = pop (); + tmp2 = pop (); + push (tmp2 >> tmp1); + break; + + case DW_OP_shra: + Debug (15, "OP_shra\n"); + tmp1 = pop (); + tmp2 = pop (); + push (sword (as, tmp2) >> tmp1); + break; + + case DW_OP_xor: + Debug (15, "OP_xor\n"); + tmp1 = pop (); + tmp2 = pop (); + push (tmp1 ^ tmp2); + break; + + case DW_OP_le: + Debug (15, "OP_le\n"); + tmp1 = pop (); + tmp2 = pop (); + push (sword (as, tmp2) <= sword (as, tmp1)); + break; + + case DW_OP_ge: + Debug (15, "OP_ge\n"); + tmp1 = pop (); + tmp2 = pop (); + push (sword (as, tmp2) >= sword (as, tmp1)); + break; + + case DW_OP_eq: + Debug (15, "OP_eq\n"); + tmp1 = pop (); + tmp2 = pop (); + push (sword (as, tmp2) == sword (as, tmp1)); + break; + + case DW_OP_lt: + Debug (15, "OP_lt\n"); + tmp1 = pop (); + tmp2 = pop (); + push (sword (as, tmp2) < sword (as, tmp1)); + break; + + case DW_OP_gt: + Debug (15, "OP_gt\n"); + tmp1 = pop (); + tmp2 = pop (); + push (sword (as, tmp2) > sword (as, tmp1)); + break; + + case DW_OP_ne: + Debug (15, "OP_ne\n"); + tmp1 = pop (); + tmp2 = pop (); + push (sword (as, tmp2) != sword (as, tmp1)); + break; + + case DW_OP_skip: + Debug (15, "OP_skip(%d)\n", (int16_t) operand1); + *addr += (int16_t) operand1; + break; + + case DW_OP_bra: + Debug (15, "OP_skip(%d)\n", (int16_t) operand1); + tmp1 = pop (); + if (tmp1) + *addr += (int16_t) operand1; + break; + + case DW_OP_nop: + Debug (15, "OP_nop\n"); + break; + + case DW_OP_call2: + case DW_OP_call4: + case DW_OP_call_ref: + case DW_OP_fbreg: + case DW_OP_piece: + case DW_OP_push_object_address: + case DW_OP_xderef: + case DW_OP_xderef_size: + default: + Debug (1, "Unexpected opcode 0x%x\n", opcode); + return -UNW_EINVAL; + } + } + *valp = pop (); + Debug (14, "final value = 0x%lx\n", (unsigned long) *valp); + return 0; +} diff --git a/src/libs/libunwind/dwarf/Gfde.c b/src/libs/libunwind/dwarf/Gfde.c new file mode 100644 index 0000000000..dd30bf6664 --- /dev/null +++ b/src/libs/libunwind/dwarf/Gfde.c @@ -0,0 +1,366 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "dwarf_i.h" + +static inline int +is_cie_id (unw_word_t val, int is_debug_frame) +{ + /* The CIE ID is normally 0xffffffff (for 32-bit ELF) or + 0xffffffffffffffff (for 64-bit ELF). However, .eh_frame + uses 0. */ + if (is_debug_frame) + return (val == - (uint32_t) 1 || val == - (uint64_t) 1); + else + return (val == 0); +} + +/* Note: we don't need to keep track of more than the first four + characters of the augmentation string, because we (a) ignore any + augmentation string contents once we find an unrecognized character + and (b) those characters that we do recognize, can't be + repeated. */ +static inline int +parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr, + const unw_proc_info_t *pi, struct dwarf_cie_info *dci, + int is_debug_frame, void *arg) +{ + uint8_t version, ch, augstr[5], fde_encoding, handler_encoding; + unw_word_t len, cie_end_addr, aug_size; + uint32_t u32val; + uint64_t u64val; + size_t i; + int ret; +# define STR2(x) #x +# define STR(x) STR2(x) + + /* Pick appropriate default for FDE-encoding. DWARF spec says + start-IP (initial_location) and the code-size (address_range) are + "address-unit sized constants". The `R' augmentation can be used + to override this, but by default, we pick an address-sized unit + for fde_encoding. */ + switch (dwarf_addr_size (as)) + { + case 4: fde_encoding = DW_EH_PE_udata4; break; + case 8: fde_encoding = DW_EH_PE_udata8; break; + default: fde_encoding = DW_EH_PE_omit; break; + } + + dci->lsda_encoding = DW_EH_PE_omit; + dci->handler = 0; + + if ((ret = dwarf_readu32 (as, a, &addr, &u32val, arg)) < 0) + return ret; + + if (u32val != 0xffffffff) + { + /* the CIE is in the 32-bit DWARF format */ + uint32_t cie_id; + /* DWARF says CIE id should be 0xffffffff, but in .eh_frame, it's 0 */ + const uint32_t expected_id = (is_debug_frame) ? 0xffffffff : 0; + + len = u32val; + cie_end_addr = addr + len; + if ((ret = dwarf_readu32 (as, a, &addr, &cie_id, arg)) < 0) + return ret; + if (cie_id != expected_id) + { + Debug (1, "Unexpected CIE id %x\n", cie_id); + return -UNW_EINVAL; + } + } + else + { + /* the CIE is in the 64-bit DWARF format */ + uint64_t cie_id; + /* DWARF says CIE id should be 0xffffffffffffffff, but in + .eh_frame, it's 0 */ + const uint64_t expected_id = (is_debug_frame) ? 0xffffffffffffffffull : 0; + + if ((ret = dwarf_readu64 (as, a, &addr, &u64val, arg)) < 0) + return ret; + len = u64val; + cie_end_addr = addr + len; + if ((ret = dwarf_readu64 (as, a, &addr, &cie_id, arg)) < 0) + return ret; + if (cie_id != expected_id) + { + Debug (1, "Unexpected CIE id %llx\n", (long long) cie_id); + return -UNW_EINVAL; + } + } + dci->cie_instr_end = cie_end_addr; + + if ((ret = dwarf_readu8 (as, a, &addr, &version, arg)) < 0) + return ret; + + if (version != 1 && version != DWARF_CIE_VERSION) + { + Debug (1, "Got CIE version %u, expected version 1 or " + STR (DWARF_CIE_VERSION) "\n", version); + return -UNW_EBADVERSION; + } + + /* read and parse the augmentation string: */ + memset (augstr, 0, sizeof (augstr)); + for (i = 0;;) + { + if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0) + return ret; + + if (!ch) + break; /* end of augmentation string */ + + if (i < sizeof (augstr) - 1) + augstr[i++] = ch; + } + + if ((ret = dwarf_read_uleb128 (as, a, &addr, &dci->code_align, arg)) < 0 + || (ret = dwarf_read_sleb128 (as, a, &addr, &dci->data_align, arg)) < 0) + return ret; + + /* Read the return-address column either as a u8 or as a uleb128. */ + if (version == 1) + { + if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0) + return ret; + dci->ret_addr_column = ch; + } + else if ((ret = dwarf_read_uleb128 (as, a, &addr, &dci->ret_addr_column, + arg)) < 0) + return ret; + + i = 0; + if (augstr[0] == 'z') + { + dci->sized_augmentation = 1; + if ((ret = dwarf_read_uleb128 (as, a, &addr, &aug_size, arg)) < 0) + return ret; + i++; + } + + for (; i < sizeof (augstr) && augstr[i]; ++i) + switch (augstr[i]) + { + case 'L': + /* read the LSDA pointer-encoding format. */ + if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0) + return ret; + dci->lsda_encoding = ch; + break; + + case 'R': + /* read the FDE pointer-encoding format. */ + if ((ret = dwarf_readu8 (as, a, &addr, &fde_encoding, arg)) < 0) + return ret; + break; + + case 'P': + /* read the personality-routine pointer-encoding format. */ + if ((ret = dwarf_readu8 (as, a, &addr, &handler_encoding, arg)) < 0) + return ret; + if ((ret = dwarf_read_encoded_pointer (as, a, &addr, handler_encoding, + pi->gp, pi->start_ip, &dci->handler, arg)) < 0) + return ret; + break; + + case 'S': + /* This is a signal frame. */ + dci->signal_frame = 1; + + /* Temporarily set it to one so dwarf_parse_fde() knows that + it should fetch the actual ABI/TAG pair from the FDE. */ + dci->have_abi_marker = 1; + break; + + default: + Debug (1, "Unexpected augmentation string `%s'\n", augstr); + if (dci->sized_augmentation) + /* If we have the size of the augmentation body, we can skip + over the parts that we don't understand, so we're OK. */ + goto done; + else + return -UNW_EINVAL; + } + done: + dci->fde_encoding = fde_encoding; + dci->cie_instr_start = addr; + Debug (15, "CIE parsed OK, augmentation = \"%s\", handler=0x%lx\n", + augstr, (long) dci->handler); + return 0; +} + +/* Extract proc-info from the FDE starting at adress ADDR. + + Pass BASE as zero for eh_frame behaviour, or a pointer to + debug_frame base for debug_frame behaviour. */ + +HIDDEN int +dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addrp, unw_proc_info_t *pi, + unw_word_t base, + int need_unwind_info, int is_debug_frame, + void *arg) +{ + unw_word_t fde_end_addr, cie_addr, cie_offset_addr, aug_end_addr = 0; + unw_word_t start_ip, ip_range, aug_size, addr = *addrp; + int ret, ip_range_encoding; + struct dwarf_cie_info dci; + uint64_t u64val; + uint32_t u32val; + + Debug (12, "FDE @ 0x%lx\n", (long) addr); + + memset (&dci, 0, sizeof (dci)); + + if ((ret = dwarf_readu32 (as, a, &addr, &u32val, arg)) < 0) + return ret; + + if (u32val != 0xffffffff) + { + int32_t cie_offset; + + /* In some configurations, an FDE with a 0 length indicates the + end of the FDE-table. */ + if (u32val == 0) + return -UNW_ENOINFO; + + /* the FDE is in the 32-bit DWARF format */ + + *addrp = fde_end_addr = addr + u32val; + cie_offset_addr = addr; + + /* CIE must be within the segment. */ + if (cie_offset_addr < base) + return -UNW_ENOINFO; + + if ((ret = dwarf_reads32 (as, a, &addr, &cie_offset, arg)) < 0) + return ret; + + if (is_cie_id (cie_offset, is_debug_frame)) + /* ignore CIEs (happens during linear searches) */ + return 0; + + if (is_debug_frame) + cie_addr = base + cie_offset; + else + /* DWARF says that the CIE_pointer in the FDE is a + .debug_frame-relative offset, but the GCC-generated .eh_frame + sections instead store a "pcrelative" offset, which is just + as fine as it's self-contained. */ + cie_addr = cie_offset_addr - cie_offset; + } + else + { + int64_t cie_offset; + + /* the FDE is in the 64-bit DWARF format */ + + if ((ret = dwarf_readu64 (as, a, &addr, &u64val, arg)) < 0) + return ret; + + *addrp = fde_end_addr = addr + u64val; + cie_offset_addr = addr; + + /* CIE must be within the segment. */ + if (cie_offset_addr < base) + return -UNW_ENOINFO; + + if ((ret = dwarf_reads64 (as, a, &addr, &cie_offset, arg)) < 0) + return ret; + + if (is_cie_id (cie_offset, is_debug_frame)) + /* ignore CIEs (happens during linear searches) */ + return 0; + + if (is_debug_frame) + cie_addr = base + cie_offset; + else + /* DWARF says that the CIE_pointer in the FDE is a + .debug_frame-relative offset, but the GCC-generated .eh_frame + sections instead store a "pcrelative" offset, which is just + as fine as it's self-contained. */ + cie_addr = (unw_word_t) ((uint64_t) cie_offset_addr - cie_offset); + } + + Debug (15, "looking for CIE at address %lx\n", (long) cie_addr); + + if ((ret = parse_cie (as, a, cie_addr, pi, &dci, is_debug_frame, arg)) < 0) + return ret; + + /* IP-range has same encoding as FDE pointers, except that it's + always an absolute value: */ + ip_range_encoding = dci.fde_encoding & DW_EH_PE_FORMAT_MASK; + + if ((ret = dwarf_read_encoded_pointer (as, a, &addr, dci.fde_encoding, + pi->gp, pi->start_ip, &start_ip, arg)) < 0 + || (ret = dwarf_read_encoded_pointer (as, a, &addr, ip_range_encoding, + pi->gp, pi->start_ip, &ip_range, arg)) < 0) + return ret; + pi->start_ip = start_ip; + pi->end_ip = start_ip + ip_range; + pi->handler = dci.handler; + + if (dci.sized_augmentation) + { + if ((ret = dwarf_read_uleb128 (as, a, &addr, &aug_size, arg)) < 0) + return ret; + aug_end_addr = addr + aug_size; + } + + if ((ret = dwarf_read_encoded_pointer (as, a, &addr, dci.lsda_encoding, + pi->gp, pi->start_ip, &pi->lsda, arg)) < 0) + return ret; + + Debug (15, "FDE covers IP 0x%lx-0x%lx, LSDA=0x%lx\n", + (long) pi->start_ip, (long) pi->end_ip, (long) pi->lsda); + + if (need_unwind_info) + { + pi->format = UNW_INFO_FORMAT_TABLE; + pi->unwind_info_size = sizeof (dci); + pi->unwind_info = mempool_alloc (&dwarf_cie_info_pool); + if (!pi->unwind_info) + return -UNW_ENOMEM; + + if (dci.have_abi_marker) + { + if ((ret = dwarf_readu16 (as, a, &addr, &dci.abi, arg)) < 0 + || (ret = dwarf_readu16 (as, a, &addr, &dci.tag, arg)) < 0) + return ret; + Debug (13, "Found ABI marker = (abi=%u, tag=%u)\n", + dci.abi, dci.tag); + } + + if (dci.sized_augmentation) + dci.fde_instr_start = aug_end_addr; + else + dci.fde_instr_start = addr; + dci.fde_instr_end = fde_end_addr; + + memcpy (pi->unwind_info, &dci, sizeof (dci)); + } + return 0; +} diff --git a/src/libs/libunwind/dwarf/Gfind_proc_info-lsb.c b/src/libs/libunwind/dwarf/Gfind_proc_info-lsb.c new file mode 100644 index 0000000000..857b85c48c --- /dev/null +++ b/src/libs/libunwind/dwarf/Gfind_proc_info-lsb.c @@ -0,0 +1,1084 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Locate an FDE via the ELF data-structures defined by LSB v1.3 + (http://www.linuxbase.org/spec/). */ + +#include +#include +#include + +#include "dwarf_i.h" +#include "dwarf-eh.h" +#include "libunwind_i.h" + +struct table_entry + { + int32_t start_ip_offset; + int32_t fde_offset; + }; + + +static inline const struct table_entry * +lookup (const struct table_entry *table, size_t table_size, int32_t rel_ip); + +static int +remote_lookup (unw_addr_space_t as, + unw_word_t table, size_t table_size, int32_t rel_ip, + struct table_entry *e, void *arg); + + +#ifndef UNW_REMOTE_ONLY + +#ifdef __linux +#include "os-linux.h" +#endif + +static int +linear_search (unw_addr_space_t as, unw_word_t ip, + unw_word_t eh_frame_start, unw_word_t eh_frame_end, + unw_word_t fde_count, + unw_word_t *fde_addr, int need_unwind_info, void *arg) +{ + unw_accessors_t *a = unw_get_accessors (unw_local_addr_space); + unw_word_t i = 0, faddr, addr = eh_frame_start; + unw_proc_info_t pi; + int ret; + + while (i++ < fde_count && addr < eh_frame_end) + { + *fde_addr = addr; + if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, &pi, + eh_frame_start, + 0, 0, arg)) < 0) + return ret; + + if (ip >= pi.start_ip && ip < pi.end_ip) + { + *fde_addr = faddr; + + if (!need_unwind_info) + return 0; + + addr = faddr; + if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, &pi, + eh_frame_start, + need_unwind_info, 0, + arg)) + < 0) + return ret; + return 0; + } + } + return -UNW_ENOINFO; +} +#endif /* !UNW_REMOTE_ONLY */ + +#ifdef CONFIG_DEBUG_FRAME +/* Load .debug_frame section from FILE. Allocates and returns space + in *BUF, and sets *BUFSIZE to its size. IS_LOCAL is 1 if using the + local process, in which case we can search the system debug file + directory; 0 for other address spaces, in which case we do not; or + -1 for recursive calls following .gnu_debuglink. Returns 0 on + success, 1 on error. Succeeds even if the file contains no + .debug_frame. */ +/* XXX: Could use mmap; but elf_map_image keeps tons mapped in. */ + +static int +load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local) +{ + FILE *f; + Elf_W (Ehdr) ehdr; + Elf_W (Half) shstrndx; + Elf_W (Shdr) *sec_hdrs = NULL; + char *stringtab = NULL; + unsigned int i; + size_t linksize = 0; + char *linkbuf = NULL; + + *buf = NULL; + *bufsize = 0; + + f = fopen (file, "r"); + + if (!f) + return 1; + + if (fread (&ehdr, sizeof (Elf_W (Ehdr)), 1, f) != 1) + goto file_error; + + shstrndx = ehdr.e_shstrndx; + + Debug (4, "opened file '%s'. Section header at offset %d\n", + file, (int) ehdr.e_shoff); + + fseek (f, ehdr.e_shoff, SEEK_SET); + sec_hdrs = calloc (ehdr.e_shnum, sizeof (Elf_W (Shdr))); + if (fread (sec_hdrs, sizeof (Elf_W (Shdr)), ehdr.e_shnum, f) != ehdr.e_shnum) + goto file_error; + + Debug (4, "loading string table of size %zd\n", + sec_hdrs[shstrndx].sh_size); + stringtab = malloc (sec_hdrs[shstrndx].sh_size); + fseek (f, sec_hdrs[shstrndx].sh_offset, SEEK_SET); + if (fread (stringtab, 1, sec_hdrs[shstrndx].sh_size, f) != sec_hdrs[shstrndx].sh_size) + goto file_error; + + for (i = 1; i < ehdr.e_shnum && *buf == NULL; i++) + { + char *secname = &stringtab[sec_hdrs[i].sh_name]; + + if (strcmp (secname, ".debug_frame") == 0) + { + *bufsize = sec_hdrs[i].sh_size; + *buf = malloc (*bufsize); + + fseek (f, sec_hdrs[i].sh_offset, SEEK_SET); + if (fread (*buf, 1, *bufsize, f) != *bufsize) + goto file_error; + + Debug (4, "read %zd bytes of .debug_frame from offset %zd\n", + *bufsize, sec_hdrs[i].sh_offset); + } + else if (strcmp (secname, ".gnu_debuglink") == 0) + { + linksize = sec_hdrs[i].sh_size; + linkbuf = malloc (linksize); + + fseek (f, sec_hdrs[i].sh_offset, SEEK_SET); + if (fread (linkbuf, 1, linksize, f) != linksize) + goto file_error; + + Debug (4, "read %zd bytes of .gnu_debuglink from offset %zd\n", + linksize, sec_hdrs[i].sh_offset); + } + } + + free (stringtab); + free (sec_hdrs); + + fclose (f); + + /* Ignore separate debug files which contain a .gnu_debuglink section. */ + if (linkbuf && is_local == -1) + { + free (linkbuf); + return 1; + } + + if (*buf == NULL && linkbuf != NULL && memchr (linkbuf, 0, linksize) != NULL) + { + char *newname, *basedir, *p; + static const char *debugdir = "/usr/lib/debug"; + int ret; + + /* XXX: Don't bother with the checksum; just search for the file. */ + basedir = malloc (strlen (file) + 1); + newname = malloc (strlen (linkbuf) + strlen (debugdir) + + strlen (file) + 9); + + p = strrchr (file, '/'); + if (p != NULL) + { + memcpy (basedir, file, p - file); + basedir[p - file] = '\0'; + } + else + basedir[0] = 0; + + strcpy (newname, basedir); + strcat (newname, "/"); + strcat (newname, linkbuf); + ret = load_debug_frame (newname, buf, bufsize, -1); + + if (ret == 1) + { + strcpy (newname, basedir); + strcat (newname, "/.debug/"); + strcat (newname, linkbuf); + ret = load_debug_frame (newname, buf, bufsize, -1); + } + + if (ret == 1 && is_local == 1) + { + strcpy (newname, debugdir); + strcat (newname, basedir); + strcat (newname, "/"); + strcat (newname, linkbuf); + ret = load_debug_frame (newname, buf, bufsize, -1); + } + + free (basedir); + free (newname); + } + free (linkbuf); + + return 0; + +/* An error reading image file. Release resources and return error code */ +file_error: + free(stringtab); + free(sec_hdrs); + free(linkbuf); + fclose(f); + + return 1; +} + +/* Locate the binary which originated the contents of address ADDR. Return + the name of the binary in *name (space is allocated by the caller) + Returns 0 if a binary is successfully found, or 1 if an error occurs. */ + +static int +find_binary_for_address (unw_word_t ip, char *name, size_t name_size) +{ +#if defined(__linux) && (!UNW_REMOTE_ONLY) + struct map_iterator mi; + int found = 0; + int pid = getpid (); + unsigned long segbase, mapoff, hi; + + maps_init (&mi, pid); + while (maps_next (&mi, &segbase, &hi, &mapoff)) + if (ip >= segbase && ip < hi) + { + size_t len = strlen (mi.path); + + if (len + 1 <= name_size) + { + memcpy (name, mi.path, len + 1); + found = 1; + } + break; + } + maps_close (&mi); + return !found; +#endif + + return 1; +} + +/* Locate and/or try to load a debug_frame section for address ADDR. Return + pointer to debug frame descriptor, or zero if not found. */ + +static struct unw_debug_frame_list * +locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname, + unw_word_t start, unw_word_t end) +{ + struct unw_debug_frame_list *w, *fdesc = 0; + char path[PATH_MAX]; + char *name = path; + int err; + char *buf; + size_t bufsize; + + /* First, see if we loaded this frame already. */ + + for (w = as->debug_frames; w; w = w->next) + { + Debug (4, "checking %p: %lx-%lx\n", w, (long)w->start, (long)w->end); + if (addr >= w->start && addr < w->end) + return w; + } + + /* If the object name we receive is blank, there's still a chance of locating + the file by parsing /proc/self/maps. */ + + if (strcmp (dlname, "") == 0) + { + err = find_binary_for_address (addr, name, sizeof(path)); + if (err) + { + Debug (15, "tried to locate binary for 0x%" PRIx64 ", but no luck\n", + (uint64_t) addr); + return 0; + } + } + else + name = (char*) dlname; + + err = load_debug_frame (name, &buf, &bufsize, as == unw_local_addr_space); + + if (!err) + { + fdesc = malloc (sizeof (struct unw_debug_frame_list)); + + fdesc->start = start; + fdesc->end = end; + fdesc->debug_frame = buf; + fdesc->debug_frame_size = bufsize; + fdesc->index = NULL; + fdesc->next = as->debug_frames; + + as->debug_frames = fdesc; + } + + return fdesc; +} + +struct debug_frame_tab + { + struct table_entry *tab; + uint32_t length; + uint32_t size; + }; + +static void +debug_frame_tab_append (struct debug_frame_tab *tab, + unw_word_t fde_offset, unw_word_t start_ip) +{ + unsigned int length = tab->length; + + if (length == tab->size) + { + tab->size *= 2; + tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->size); + } + + tab->tab[length].fde_offset = fde_offset; + tab->tab[length].start_ip_offset = start_ip; + + tab->length = length + 1; +} + +static void +debug_frame_tab_shrink (struct debug_frame_tab *tab) +{ + if (tab->size > tab->length) + { + tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->length); + tab->size = tab->length; + } +} + +static int +debug_frame_tab_compare (const void *a, const void *b) +{ + const struct table_entry *fa = a, *fb = b; + + if (fa->start_ip_offset > fb->start_ip_offset) + return 1; + else if (fa->start_ip_offset < fb->start_ip_offset) + return -1; + else + return 0; +} + +PROTECTED int +dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, unw_word_t ip, + unw_word_t segbase, const char* obj_name, + unw_word_t start, unw_word_t end) +{ + unw_dyn_info_t *di; + struct unw_debug_frame_list *fdesc = 0; + unw_accessors_t *a; + unw_word_t addr; + + Debug (15, "Trying to find .debug_frame for %s\n", obj_name); + di = di_debug; + + fdesc = locate_debug_info (unw_local_addr_space, ip, obj_name, start, end); + + if (!fdesc) + { + Debug (15, "couldn't load .debug_frame\n"); + return found; + } + else + { + char *buf; + size_t bufsize; + unw_word_t item_start, item_end = 0; + uint32_t u32val = 0; + uint64_t cie_id = 0; + struct debug_frame_tab tab; + + Debug (15, "loaded .debug_frame\n"); + + buf = fdesc->debug_frame; + bufsize = fdesc->debug_frame_size; + + if (bufsize == 0) + { + Debug (15, "zero-length .debug_frame\n"); + return found; + } + + /* Now create a binary-search table, if it does not already exist. */ + if (!fdesc->index) + { + addr = (unw_word_t) (uintptr_t) buf; + + a = unw_get_accessors (unw_local_addr_space); + + /* Find all FDE entries in debug_frame, and make into a sorted + index. */ + + tab.length = 0; + tab.size = 16; + tab.tab = calloc (tab.size, sizeof (struct table_entry)); + + while (addr < (unw_word_t) (uintptr_t) (buf + bufsize)) + { + uint64_t id_for_cie; + item_start = addr; + + dwarf_readu32 (unw_local_addr_space, a, &addr, &u32val, NULL); + + if (u32val == 0) + break; + else if (u32val != 0xffffffff) + { + uint32_t cie_id32 = 0; + item_end = addr + u32val; + dwarf_readu32 (unw_local_addr_space, a, &addr, &cie_id32, + NULL); + cie_id = cie_id32; + id_for_cie = 0xffffffff; + } + else + { + uint64_t u64val = 0; + /* Extended length. */ + dwarf_readu64 (unw_local_addr_space, a, &addr, &u64val, NULL); + item_end = addr + u64val; + + dwarf_readu64 (unw_local_addr_space, a, &addr, &cie_id, NULL); + id_for_cie = 0xffffffffffffffffull; + } + + /*Debug (1, "CIE/FDE id = %.8x\n", (int) cie_id);*/ + + if (cie_id == id_for_cie) + ; + /*Debug (1, "Found CIE at %.8x.\n", item_start);*/ + else + { + unw_word_t fde_addr = item_start; + unw_proc_info_t this_pi; + int err; + + /*Debug (1, "Found FDE at %.8x\n", item_start);*/ + + err = dwarf_extract_proc_info_from_fde (unw_local_addr_space, + a, &fde_addr, + &this_pi, + (uintptr_t) buf, 0, 1, + NULL); + if (err == 0) + { + Debug (15, "start_ip = %lx, end_ip = %lx\n", + (long) this_pi.start_ip, (long) this_pi.end_ip); + debug_frame_tab_append (&tab, + item_start - (unw_word_t) (uintptr_t) buf, + this_pi.start_ip); + } + /*else + Debug (1, "FDE parse failed\n");*/ + } + + addr = item_end; + } + + debug_frame_tab_shrink (&tab); + qsort (tab.tab, tab.length, sizeof (struct table_entry), + debug_frame_tab_compare); + /* for (i = 0; i < tab.length; i++) + { + fprintf (stderr, "ip %x, fde offset %x\n", + (int) tab.tab[i].start_ip_offset, + (int) tab.tab[i].fde_offset); + }*/ + fdesc->index = tab.tab; + fdesc->index_size = tab.length; + } + + di->format = UNW_INFO_FORMAT_TABLE; + di->start_ip = fdesc->start; + di->end_ip = fdesc->end; + di->u.ti.name_ptr = (unw_word_t) (uintptr_t) obj_name; + di->u.ti.table_data = (unw_word_t *) fdesc; + di->u.ti.table_len = sizeof (*fdesc) / sizeof (unw_word_t); + di->u.ti.segbase = segbase; + + found = 1; + Debug (15, "found debug_frame table `%s': segbase=0x%lx, len=%lu, " + "gp=0x%lx, table_data=0x%lx\n", + (char *) (uintptr_t) di->u.ti.name_ptr, + (long) di->u.ti.segbase, (long) di->u.ti.table_len, + (long) di->gp, (long) di->u.ti.table_data); + } + return found; +} + +#endif /* CONFIG_DEBUG_FRAME */ + +#ifndef UNW_REMOTE_ONLY + +static int +dwarf_search_fde_in_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_word_t segbase, size_t table_len, + const struct table_entry *table, + unw_word_t debug_frame_base, + unw_word_t *fde_addr, + void *arg) +{ + const struct table_entry *e = NULL; + unw_accessors_t *a; +#ifndef UNW_LOCAL_ONLY + struct table_entry ent; +#endif + int ret; + + Debug(15, "dwarf_search_fde_in_unwind_table: ip=0x%lx, segbase=%lx, " + "table_len=%zu, table=%p, debug_frame_base=%lx", + ip, segbase, table_len, table, debug_frame_base); + + a = unw_get_accessors (as); + +#ifndef UNW_REMOTE_ONLY + if (as == unw_local_addr_space) + { + e = lookup (table, table_len, ip - segbase); + } + else +#endif + { +#ifndef UNW_LOCAL_ONLY + if ((ret = remote_lookup (as, (uintptr_t) table, table_len, + ip - segbase, &ent, arg)) < 0) + return ret; + if (ret) + e = &ent; + else + e = NULL; /* no info found */ +#endif + } + if (!e) + { + Debug (1, "IP %x: no explicit unwind info found\n", + (int) ip); + /* IP is inside this table's range, but there is no explicit + unwind info. */ + return -UNW_ENOINFO; + } + + Debug (15, "ip=0x%lx, start_ip=0x%lx\n", + (long) ip, (long) (e->start_ip_offset)); + + if (debug_frame_base) + *fde_addr = e->fde_offset + debug_frame_base; + else + *fde_addr = e->fde_offset + segbase; + + Debug (1, "e->fde_offset = %x, segbase = %x, debug_frame_base = %x, " + "fde_addr = %x\n", (int) e->fde_offset, (int) segbase, + (int) debug_frame_base, (int) fde_addr); + + return 0; +} + + +/* Searches for FDE for specific ip in eh_frame_hdr. + Returns 0 if success. */ +static int +search_fde_in_eh_frame(unw_word_t ip, unw_word_t hdr_addr, unw_word_t gp, + unw_word_t eh_frame_end, unw_word_t *fde_addr, + int need_unwind_info, void *arg, + const char * name) +{ + unw_accessors_t *a; + unw_word_t addr, eh_frame_start, fde_count; + int ret; + struct dwarf_eh_frame_hdr *hdr = (struct dwarf_eh_frame_hdr *)hdr_addr; + + if (hdr->version != DW_EH_VERSION) + { + Debug (1, "table `%s' has unexpected version %d\n", + name, hdr->version); + return -UNW_ENOINFO; + } + + a = unw_get_accessors (unw_local_addr_space); + addr = (unw_word_t) (uintptr_t) (hdr + 1); + + /* (Optionally) read eh_frame_ptr: */ + if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, + &addr, hdr->eh_frame_ptr_enc, gp, 0, + &eh_frame_start, NULL)) < 0) + return ret; + + /* (Optionally) read fde_count: */ + if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, + &addr, hdr->fde_count_enc, gp, 0, + &fde_count, NULL)) < 0) + return ret; + + if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) + { + int err; + + /* If there is no search table or it has an unsupported + encoding, fall back on linear search. */ + if (hdr->table_enc == DW_EH_PE_omit) + Debug (4, "table `%s' lacks search table; doing linear search\n", + name); + else + Debug (4, "table `%s' has encoding 0x%x; doing linear search\n", + name, hdr->table_enc); + + if (hdr->fde_count_enc == DW_EH_PE_omit) + fde_count = ~0UL; + if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit) + abort (); + + /* XXX we know how to build a local binary search table for + .debug_frame, so we could do that here too. */ + return linear_search (unw_local_addr_space, ip, + eh_frame_start, eh_frame_end, fde_count, + fde_addr, need_unwind_info, NULL); + } + else + { + int err; + + size_t table_len = (fde_count * sizeof (struct table_entry)); + /* For the binary-search table in the eh_frame_hdr, data-relative + means relative to the start of that section... */ + unw_word_t sbase = (unw_word_t) (uintptr_t) hdr; + + Debug (15, "found table `%s': sbase=0x%lx, len=%lu, gp=0x%lx, " + "table_data=0x%lx\n", (char *) (uintptr_t) name, + (long) sbase, (long) table_len, + (long) gp, (long) addr); + + return dwarf_search_fde_in_unwind_table (unw_local_addr_space, ip, + sbase, table_len, + (const struct table_entry*)addr, 0, + fde_addr, arg); + } +} + +#ifdef HAVE_DL_ITERATE_PHDR + +/* ptr is a pointer to a dwarf_callback_data structure and, on entry, + member ip contains the instruction-pointer we're looking + for. */ +HIDDEN int +dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr) +{ + struct dwarf_callback_data *cb_data = ptr; + const Elf_W(Phdr) *phdr, *p_eh_hdr, *p_dynamic, *p_text; + unw_word_t addr, eh_frame_start, eh_frame_end, fde_count, ip; + Elf_W(Addr) load_base, max_load_addr = 0; + int ret, need_unwind_info = cb_data->need_unwind_info; + struct dwarf_eh_frame_hdr *hdr; + unw_accessors_t *a; + long n; + int found = 0; +#ifdef CONFIG_DEBUG_FRAME + unw_word_t start, end; +#endif /* CONFIG_DEBUG_FRAME*/ + + ip = cb_data->ip; + + /* Make sure struct dl_phdr_info is at least as big as we need. */ + if (size < offsetof (struct dl_phdr_info, dlpi_phnum) + + sizeof (info->dlpi_phnum)) + return -1; + + Debug (15, "checking %s, base=0x%lx)\n", + info->dlpi_name, (long) info->dlpi_addr); + + phdr = info->dlpi_phdr; + load_base = info->dlpi_addr; + p_text = NULL; + p_eh_hdr = NULL; + p_dynamic = NULL; + + /* See if PC falls into one of the loaded segments. Find the + eh-header segment at the same time. */ + for (n = info->dlpi_phnum; --n >= 0; phdr++) + { + if (phdr->p_type == PT_LOAD) + { + Elf_W(Addr) vaddr = phdr->p_vaddr + load_base; + + if (ip >= vaddr && ip < vaddr + phdr->p_memsz) + p_text = phdr; + + if (vaddr + phdr->p_filesz > max_load_addr) + max_load_addr = vaddr + phdr->p_filesz; + } + else if (phdr->p_type == PT_GNU_EH_FRAME) + p_eh_hdr = phdr; + else if (phdr->p_type == PT_DYNAMIC) + p_dynamic = phdr; + } + + if (!p_text) + return 0; + + if (p_eh_hdr) + { + if (p_dynamic) + { + /* For dynamicly linked executables and shared libraries, + DT_PLTGOT is the value that data-relative addresses are + relative to for that object. We call this the "gp". */ + Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(p_dynamic->p_vaddr + load_base); + for (; dyn->d_tag != DT_NULL; ++dyn) + if (dyn->d_tag == DT_PLTGOT) + { + /* Assume that _DYNAMIC is writable and GLIBC has + relocated it (true for x86 at least). */ + cb_data->gp = dyn->d_un.d_ptr; + break; + } + } + else + /* Otherwise this is a static executable with no _DYNAMIC. Assume + that data-relative addresses are relative to 0, i.e., + absolute. */ + cb_data->gp = 0; + + eh_frame_end = (unw_word_t)max_load_addr; // Can we do better? + ret = search_fde_in_eh_frame(ip, (unw_word_t)(p_eh_hdr->p_vaddr + load_base), + cb_data->gp, eh_frame_end, &cb_data->fde_addr, + cb_data->need_unwind_info, cb_data->arg, info->dlpi_name); + if (ret < 0) + return ret; + + cb_data->fde_base = 0; + cb_data->ip_offset = 0; + + return 1; + } + +#ifdef CONFIG_DEBUG_FRAME + found = dwarf_find_debug_frame (found, &cb_data->di_debug, info, ip); +#endif /* CONFIG_DEBUG_FRAME */ + + return found; +} + +static int +find_proc_fde (unw_word_t ip, unw_word_t *fde_addr, + unw_word_t *gp, unw_word_t *fde_base, + unw_word_t *ip_offset, void *arg) { + struct dwarf_callback_data cb_data; + intrmask_t saved_mask; + int ret; + + memset (&cb_data, 0, sizeof (cb_data)); + cb_data.ip = ip; + cb_data.arg = arg; + + SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); + ret = dl_iterate_phdr (dwarf_callback, &cb_data); + SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); + + if (ret < 0) + return ret; + + if (ret == 0) + { + ret = -UNW_ENOINFO; + return ret; + } + + *fde_addr = cb_data.fde_addr; + *gp = cb_data.gp; + *fde_base = cb_data.fde_base; + *ip_offset = cb_data.ip_offset; + + return 0; +} + +#else // HAVE_DL_ITERATE_PHDR + +static int +find_proc_fde(unw_word_t ip, unw_word_t *fde_addr, + unw_word_t *gp, unw_word_t *fde_base, + unw_word_t *ip_offset, void *arg) { + Dl_amd64_unwindinfo dlef; + void* data; + void* data_end; + int fp_enc, fc_enc, ft_enc; + unsigned char *pi, *pj; + ptrdiff_t reloc; + uintptr_t base; + int ret; + + dlef.dlui_version = 1; + + /* Locate the appropiate exception_range_entry table first */ + if (0 == dlamd64getunwind((void*)ip, &dlef)) { + return -UNW_ENOINFO; + } + + /* + * you now know size and position of block of data needed for + * binary search ??REMOTE?? + */ + data = dlef.dlui_unwindstart; + if (0 == data) + return -UNW_ENOINFO; + + base = (uintptr_t)data; + data_end = dlef.dlui_unwindend; + reloc = 0; + /* ??REMOTE?? */ + + *gp = 0; + *fde_base = 0; + *ip_offset = 0; + + return search_fde_in_eh_frame(ip, (unw_word_t)data, 0, + (unw_word_t)data_end, fde_addr, arg, 0, + dlef.dlui_objname); +} + +#endif // HAVE_DL_ITERATE_PHDR + +HIDDEN int +dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, int need_unwind_info, void *arg) +{ + struct dwarf_callback_data cb_data; + intrmask_t saved_mask; + int ret; + unw_word_t fde_addr; + unw_word_t gp; + unw_word_t fde_base; + unw_word_t ip_offset; + unw_accessors_t *a; + + Debug (14, "looking for IP=0x%lx\n", (long) ip); + + ret = find_proc_fde (ip, &fde_addr, &gp, &fde_base, &ip_offset, arg); + if (ret < 0) + { + Debug (14, "IP=0x%lx not found\n", (long) ip); + return ret; + } + + pi->gp = gp; + + a = unw_get_accessors (unw_local_addr_space); + ret = dwarf_extract_proc_info_from_fde (as, a, &fde_addr, pi, + fde_base, + need_unwind_info, 0, + arg); + if (ret < 0) + return ret; + + pi->start_ip += ip_offset; + pi->end_ip += ip_offset; + + if (ip < pi->start_ip || ip >= pi->end_ip) + return -UNW_ENOINFO; + + return 0; +} + +static inline const struct table_entry * +lookup (const struct table_entry *table, size_t table_size, int32_t rel_ip) +{ + unsigned long table_len = table_size / sizeof (struct table_entry); + const struct table_entry *e = NULL; + unsigned long lo, hi, mid; + + /* do a binary search for right entry: */ + for (lo = 0, hi = table_len; lo < hi;) + { + mid = (lo + hi) / 2; + e = table + mid; + Debug (15, "e->start_ip_offset = %lx\n", (long) e->start_ip_offset); + if (rel_ip < e->start_ip_offset) + hi = mid; + else + lo = mid + 1; + } + if (hi <= 0) + return NULL; + e = table + hi - 1; + return e; +} + +#endif /* !UNW_REMOTE_ONLY */ + +#ifndef UNW_LOCAL_ONLY + +/* Lookup an unwind-table entry in remote memory. Returns 1 if an + entry is found, 0 if no entry is found, negative if an error + occurred reading remote memory. */ +static int +remote_lookup (unw_addr_space_t as, + unw_word_t table, size_t table_size, int32_t rel_ip, + struct table_entry *e, void *arg) +{ + unsigned long table_len = table_size / sizeof (struct table_entry); + unw_accessors_t *a = unw_get_accessors (as); + unsigned long lo, hi, mid; + unw_word_t e_addr = 0; + int32_t start; + int ret; + + /* do a binary search for right entry: */ + for (lo = 0, hi = table_len; lo < hi;) + { + mid = (lo + hi) / 2; + e_addr = table + mid * sizeof (struct table_entry); + if ((ret = dwarf_reads32 (as, a, &e_addr, &start, arg)) < 0) + return ret; + + if (rel_ip < start) + hi = mid; + else + lo = mid + 1; + } + if (hi <= 0) + return 0; + e_addr = table + (hi - 1) * sizeof (struct table_entry); + if ((ret = dwarf_reads32 (as, a, &e_addr, &e->start_ip_offset, arg)) < 0 + || (ret = dwarf_reads32 (as, a, &e_addr, &e->fde_offset, arg)) < 0) + return ret; + return 1; +} + +#endif /* !UNW_LOCAL_ONLY */ + +PROTECTED int +dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t *di, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + const struct table_entry *e = NULL, *table; + unw_word_t segbase = 0, fde_addr; + unw_accessors_t *a; +#ifndef UNW_LOCAL_ONLY + struct table_entry ent; +#endif + int ret; + unw_word_t debug_frame_base; + size_t table_len; + +#ifdef UNW_REMOTE_ONLY + assert (di->format == UNW_INFO_FORMAT_REMOTE_TABLE); +#else + assert (di->format == UNW_INFO_FORMAT_REMOTE_TABLE + || di->format == UNW_INFO_FORMAT_TABLE); +#endif + assert (ip >= di->start_ip && ip < di->end_ip); + + if (di->format == UNW_INFO_FORMAT_REMOTE_TABLE) + { + table = (const struct table_entry *) (uintptr_t) di->u.rti.table_data; + table_len = di->u.rti.table_len * sizeof (unw_word_t); + debug_frame_base = 0; + } + else + { +#ifndef UNW_REMOTE_ONLY + struct unw_debug_frame_list *fdesc = (void *) di->u.ti.table_data; + + /* UNW_INFO_FORMAT_TABLE (i.e. .debug_frame) is read from local address + space. Both the index and the unwind tables live in local memory, but + the address space to check for properties like the address size and + endianness is the target one. */ + as = unw_local_addr_space; + table = fdesc->index; + table_len = fdesc->index_size * sizeof (struct table_entry); + debug_frame_base = (uintptr_t) fdesc->debug_frame; +#endif + } + + a = unw_get_accessors (as); + +#ifndef UNW_REMOTE_ONLY + if (as == unw_local_addr_space) + { + segbase = di->u.rti.segbase; + e = lookup (table, table_len, ip - segbase); + } + else +#endif + { +#ifndef UNW_LOCAL_ONLY + segbase = di->u.rti.segbase; + if ((ret = remote_lookup (as, (uintptr_t) table, table_len, + ip - segbase, &ent, arg)) < 0) + return ret; + if (ret) + e = &ent; + else + e = NULL; /* no info found */ +#endif + } + if (!e) + { + Debug (1, "IP %lx inside range %lx-%lx, but no explicit unwind info found\n", + (long) ip, (long) di->start_ip, (long) di->end_ip); + /* IP is inside this table's range, but there is no explicit + unwind info. */ + return -UNW_ENOINFO; + } + Debug (15, "ip=0x%lx, start_ip=0x%lx\n", + (long) ip, (long) (e->start_ip_offset)); + if (debug_frame_base) + fde_addr = e->fde_offset + debug_frame_base; + else + fde_addr = e->fde_offset + segbase; + Debug (1, "e->fde_offset = %lx, segbase = %lx, debug_frame_base = %lx, " + "fde_addr = %lx\n", (long) e->fde_offset, (long) segbase, + (long) debug_frame_base, (long) fde_addr); + if ((ret = dwarf_extract_proc_info_from_fde (as, a, &fde_addr, pi, + debug_frame_base ? + debug_frame_base : segbase, + need_unwind_info, + debug_frame_base != 0, arg)) < 0) + return ret; + + /* .debug_frame uses an absolute encoding that does not know about any + shared library relocation. */ + if (di->format == UNW_INFO_FORMAT_TABLE) + { + pi->start_ip += segbase; + pi->end_ip += segbase; + pi->flags = UNW_PI_FLAG_DEBUG_FRAME; + } + + if (ip < pi->start_ip || ip >= pi->end_ip) + return -UNW_ENOINFO; + + return 0; +} + +HIDDEN void +dwarf_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) +{ + return; /* always a nop */ +} diff --git a/src/libs/libunwind/dwarf/Gfind_unwind_table.c b/src/libs/libunwind/dwarf/Gfind_unwind_table.c new file mode 100644 index 0000000000..d54a370b27 --- /dev/null +++ b/src/libs/libunwind/dwarf/Gfind_unwind_table.c @@ -0,0 +1,219 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include + +#include + +#include "libunwind_i.h" +#include "dwarf-eh.h" +#include "dwarf_i.h" + +int +dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, + char *path, unw_word_t segbase, unw_word_t mapoff, + unw_word_t ip) +{ + Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL; + unw_word_t addr, eh_frame_start, fde_count, load_base; + unw_word_t max_load_addr = 0; + unw_word_t start_ip = (unw_word_t) -1; + unw_word_t end_ip = 0; + struct dwarf_eh_frame_hdr *hdr; + unw_accessors_t *a; + Elf_W(Ehdr) *ehdr; +#if UNW_TARGET_ARM + const Elf_W(Phdr) *parm_exidx = NULL; +#endif + int i, ret, found = 0; + + /* XXX: Much of this code is Linux/LSB-specific. */ + + if (!elf_w(valid_object) (&edi->ei)) + return -UNW_ENOINFO; + + ehdr = edi->ei.image; + phdr = (Elf_W(Phdr) *) ((char *) edi->ei.image + ehdr->e_phoff); + + for (i = 0; i < ehdr->e_phnum; ++i) + { + switch (phdr[i].p_type) + { + case PT_LOAD: + if (phdr[i].p_vaddr < start_ip) + start_ip = phdr[i].p_vaddr; + + if (phdr[i].p_vaddr + phdr[i].p_memsz > end_ip) + end_ip = phdr[i].p_vaddr + phdr[i].p_memsz; + + if (phdr[i].p_offset == mapoff) + ptxt = phdr + i; + if ((uintptr_t) edi->ei.image + phdr->p_filesz > max_load_addr) + max_load_addr = (uintptr_t) edi->ei.image + phdr->p_filesz; + break; + + case PT_GNU_EH_FRAME: + peh_hdr = phdr + i; + break; + + case PT_DYNAMIC: + pdyn = phdr + i; + break; + +#if UNW_TARGET_ARM + case PT_ARM_EXIDX: + parm_exidx = phdr + i; + break; +#endif + + default: + break; + } + } + + if (!ptxt) + return 0; + + load_base = segbase - ptxt->p_vaddr; + start_ip += load_base; + end_ip += load_base; + + if (peh_hdr) + { + if (pdyn) + { + /* For dynamicly linked executables and shared libraries, + DT_PLTGOT is the value that data-relative addresses are + relative to for that object. We call this the "gp". */ + Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(pdyn->p_offset + + (char *) edi->ei.image); + for (; dyn->d_tag != DT_NULL; ++dyn) + if (dyn->d_tag == DT_PLTGOT) + { + /* Assume that _DYNAMIC is writable and GLIBC has + relocated it (true for x86 at least). */ + edi->di_cache.gp = dyn->d_un.d_ptr; + break; + } + } + else + /* Otherwise this is a static executable with no _DYNAMIC. Assume + that data-relative addresses are relative to 0, i.e., + absolute. */ + edi->di_cache.gp = 0; + + hdr = (struct dwarf_eh_frame_hdr *) (peh_hdr->p_offset + + (char *) edi->ei.image); + if (hdr->version != DW_EH_VERSION) + { + Debug (1, "table `%s' has unexpected version %d\n", + path, hdr->version); + return -UNW_ENOINFO; + } + + a = unw_get_accessors (unw_local_addr_space); + addr = (unw_word_t) (hdr + 1); + + /* (Optionally) read eh_frame_ptr: */ + if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, + &addr, hdr->eh_frame_ptr_enc, edi->di_cache.gp, 0, + &eh_frame_start, NULL)) < 0) + return -UNW_ENOINFO; + + /* (Optionally) read fde_count: */ + if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, + &addr, hdr->fde_count_enc, edi->di_cache.gp, 0, + &fde_count, NULL)) < 0) + return -UNW_ENOINFO; + + if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) + { + #if 1 + abort (); + #else + unw_word_t eh_frame_end; + + /* If there is no search table or it has an unsupported + encoding, fall back on linear search. */ + if (hdr->table_enc == DW_EH_PE_omit) + Debug (4, "EH lacks search table; doing linear search\n"); + else + Debug (4, "EH table has encoding 0x%x; doing linear search\n", + hdr->table_enc); + + eh_frame_end = max_load_addr; /* XXX can we do better? */ + + if (hdr->fde_count_enc == DW_EH_PE_omit) + fde_count = ~0UL; + if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit) + abort (); + + return linear_search (unw_local_addr_space, ip, + eh_frame_start, eh_frame_end, fde_count, + pi, need_unwind_info, NULL); + #endif + } + + edi->di_cache.start_ip = start_ip; + edi->di_cache.end_ip = end_ip; + edi->di_cache.format = UNW_INFO_FORMAT_REMOTE_TABLE; + edi->di_cache.u.rti.name_ptr = 0; + /* two 32-bit values (ip_offset/fde_offset) per table-entry: */ + edi->di_cache.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t); + edi->di_cache.u.rti.table_data = ((load_base + peh_hdr->p_vaddr) + + (addr - (unw_word_t) edi->ei.image + - peh_hdr->p_offset)); + + /* For the binary-search table in the eh_frame_hdr, data-relative + means relative to the start of that section... */ + edi->di_cache.u.rti.segbase = ((load_base + peh_hdr->p_vaddr) + + ((unw_word_t) hdr - (unw_word_t) edi->ei.image + - peh_hdr->p_offset)); + found = 1; + } + +#if UNW_TARGET_ARM + if (parm_exidx) + { + edi->di_arm.format = UNW_INFO_FORMAT_ARM_EXIDX; + edi->di_arm.start_ip = start_ip; + edi->di_arm.end_ip = end_ip; + edi->di_arm.u.rti.name_ptr = (unw_word_t) path; + edi->di_arm.u.rti.table_data = load_base + parm_exidx->p_vaddr; + edi->di_arm.u.rti.table_len = parm_exidx->p_memsz; + found = 1; + } +#endif + +#ifdef CONFIG_DEBUG_FRAME + /* Try .debug_frame. */ + found = dwarf_find_debug_frame (found, &edi->di_debug, ip, load_base, path, + start_ip, end_ip); +#endif + + return found; +} diff --git a/src/libs/libunwind/dwarf/Gparser.c b/src/libs/libunwind/dwarf/Gparser.c new file mode 100644 index 0000000000..cae95c4d4f --- /dev/null +++ b/src/libs/libunwind/dwarf/Gparser.c @@ -0,0 +1,931 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include "dwarf_i.h" +#include "libunwind_i.h" + +#define alloc_reg_state() (mempool_alloc (&dwarf_reg_state_pool)) +#define free_reg_state(rs) (mempool_free (&dwarf_reg_state_pool, rs)) + +static inline int +read_regnum (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + unw_word_t *valp, void *arg) +{ + int ret; + + if ((ret = dwarf_read_uleb128 (as, a, addr, valp, arg)) < 0) + return ret; + + if (*valp >= DWARF_NUM_PRESERVED_REGS) + { + Debug (1, "Invalid register number %u\n", (unsigned int) *valp); + return -UNW_EBADREG; + } + return 0; +} + +static inline void +set_reg (dwarf_state_record_t *sr, unw_word_t regnum, dwarf_where_t where, + unw_word_t val) +{ + sr->rs_current.reg[regnum].where = where; + sr->rs_current.reg[regnum].val = val; +} + +/* Run a CFI program to update the register state. */ +static int +run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr, + unw_word_t ip, unw_word_t *addr, unw_word_t end_addr, + struct dwarf_cie_info *dci) +{ + unw_word_t curr_ip, operand = 0, regnum, val, len, fde_encoding; + dwarf_reg_state_t *rs_stack = NULL, *new_rs, *old_rs; + unw_addr_space_t as; + unw_accessors_t *a; + uint8_t u8, op; + uint16_t u16; + uint32_t u32; + void *arg; + int ret; + + as = c->as; + arg = c->as_arg; + if (c->pi.flags & UNW_PI_FLAG_DEBUG_FRAME) + { + /* .debug_frame CFI is stored in local address space. */ + as = unw_local_addr_space; + arg = NULL; + } + a = unw_get_accessors (as); + curr_ip = c->pi.start_ip; + + /* Process everything up to and including the current 'ip', + including all the DW_CFA_advance_loc instructions. See + 'c->use_prev_instr' use in 'fetch_proc_info' for details. */ + while (curr_ip <= ip && *addr < end_addr) + { + if ((ret = dwarf_readu8 (as, a, addr, &op, arg)) < 0) + return ret; + + if (op & DWARF_CFA_OPCODE_MASK) + { + operand = op & DWARF_CFA_OPERAND_MASK; + op &= ~DWARF_CFA_OPERAND_MASK; + } + switch ((dwarf_cfa_t) op) + { + case DW_CFA_advance_loc: + curr_ip += operand * dci->code_align; + Debug (15, "CFA_advance_loc to 0x%lx\n", (long) curr_ip); + break; + + case DW_CFA_advance_loc1: + if ((ret = dwarf_readu8 (as, a, addr, &u8, arg)) < 0) + goto fail; + curr_ip += u8 * dci->code_align; + Debug (15, "CFA_advance_loc1 to 0x%lx\n", (long) curr_ip); + break; + + case DW_CFA_advance_loc2: + if ((ret = dwarf_readu16 (as, a, addr, &u16, arg)) < 0) + goto fail; + curr_ip += u16 * dci->code_align; + Debug (15, "CFA_advance_loc2 to 0x%lx\n", (long) curr_ip); + break; + + case DW_CFA_advance_loc4: + if ((ret = dwarf_readu32 (as, a, addr, &u32, arg)) < 0) + goto fail; + curr_ip += u32 * dci->code_align; + Debug (15, "CFA_advance_loc4 to 0x%lx\n", (long) curr_ip); + break; + + case DW_CFA_MIPS_advance_loc8: +#ifdef UNW_TARGET_MIPS + { + uint64_t u64; + + if ((ret = dwarf_readu64 (as, a, addr, &u64, arg)) < 0) + goto fail; + curr_ip += u64 * dci->code_align; + Debug (15, "CFA_MIPS_advance_loc8\n"); + break; + } +#else + Debug (1, "DW_CFA_MIPS_advance_loc8 on non-MIPS target\n"); + ret = -UNW_EINVAL; + goto fail; +#endif + + case DW_CFA_offset: + regnum = operand; + if (regnum >= DWARF_NUM_PRESERVED_REGS) + { + Debug (1, "Invalid register number %u in DW_cfa_OFFSET\n", + (unsigned int) regnum); + ret = -UNW_EBADREG; + goto fail; + } + if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) + goto fail; + set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); + Debug (15, "CFA_offset r%lu at cfa+0x%lx\n", + (long) regnum, (long) (val * dci->data_align)); + break; + + case DW_CFA_offset_extended: + if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) + goto fail; + set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); + Debug (15, "CFA_offset_extended r%lu at cf+0x%lx\n", + (long) regnum, (long) (val * dci->data_align)); + break; + + case DW_CFA_offset_extended_sf: + if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + || ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0)) + goto fail; + set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); + Debug (15, "CFA_offset_extended_sf r%lu at cf+0x%lx\n", + (long) regnum, (long) (val * dci->data_align)); + break; + + case DW_CFA_restore: + regnum = operand; + if (regnum >= DWARF_NUM_PRESERVED_REGS) + { + Debug (1, "Invalid register number %u in DW_CFA_restore\n", + (unsigned int) regnum); + ret = -UNW_EINVAL; + goto fail; + } + sr->rs_current.reg[regnum] = sr->rs_initial.reg[regnum]; + Debug (15, "CFA_restore r%lu\n", (long) regnum); + break; + + case DW_CFA_restore_extended: + if ((ret = dwarf_read_uleb128 (as, a, addr, ®num, arg)) < 0) + goto fail; + if (regnum >= DWARF_NUM_PRESERVED_REGS) + { + Debug (1, "Invalid register number %u in " + "DW_CFA_restore_extended\n", (unsigned int) regnum); + ret = -UNW_EINVAL; + goto fail; + } + sr->rs_current.reg[regnum] = sr->rs_initial.reg[regnum]; + Debug (15, "CFA_restore_extended r%lu\n", (long) regnum); + break; + + case DW_CFA_nop: + break; + + case DW_CFA_set_loc: + fde_encoding = dci->fde_encoding; + if ((ret = dwarf_read_encoded_pointer (as, a, addr, fde_encoding, + c->pi.gp, c->pi.start_ip, &curr_ip, + arg)) < 0) + goto fail; + Debug (15, "CFA_set_loc to 0x%lx\n", (long) curr_ip); + break; + + case DW_CFA_undefined: + if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + goto fail; + set_reg (sr, regnum, DWARF_WHERE_UNDEF, 0); + Debug (15, "CFA_undefined r%lu\n", (long) regnum); + break; + + case DW_CFA_same_value: + if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + goto fail; + set_reg (sr, regnum, DWARF_WHERE_SAME, 0); + Debug (15, "CFA_same_value r%lu\n", (long) regnum); + break; + + case DW_CFA_register: + if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) + goto fail; + set_reg (sr, regnum, DWARF_WHERE_REG, val); + Debug (15, "CFA_register r%lu to r%lu\n", (long) regnum, (long) val); + break; + + case DW_CFA_remember_state: + new_rs = alloc_reg_state (); + if (!new_rs) + { + Debug (1, "Out of memory in DW_CFA_remember_state\n"); + ret = -UNW_ENOMEM; + goto fail; + } + + memcpy (new_rs->reg, sr->rs_current.reg, sizeof (new_rs->reg)); + new_rs->next = rs_stack; + rs_stack = new_rs; + Debug (15, "CFA_remember_state\n"); + break; + + case DW_CFA_restore_state: + if (!rs_stack) + { + Debug (1, "register-state stack underflow\n"); + ret = -UNW_EINVAL; + goto fail; + } + memcpy (&sr->rs_current.reg, &rs_stack->reg, sizeof (rs_stack->reg)); + old_rs = rs_stack; + rs_stack = rs_stack->next; + free_reg_state (old_rs); + Debug (15, "CFA_restore_state\n"); + break; + + case DW_CFA_def_cfa: + if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) + goto fail; + set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); + set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val); /* NOT factored! */ + Debug (15, "CFA_def_cfa r%lu+0x%lx\n", (long) regnum, (long) val); + break; + + case DW_CFA_def_cfa_sf: + if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + || ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0)) + goto fail; + set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); + set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, + val * dci->data_align); /* factored! */ + Debug (15, "CFA_def_cfa_sf r%lu+0x%lx\n", + (long) regnum, (long) (val * dci->data_align)); + break; + + case DW_CFA_def_cfa_register: + if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + goto fail; + set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); + Debug (15, "CFA_def_cfa_register r%lu\n", (long) regnum); + break; + + case DW_CFA_def_cfa_offset: + if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) + goto fail; + set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val); /* NOT factored! */ + Debug (15, "CFA_def_cfa_offset 0x%lx\n", (long) val); + break; + + case DW_CFA_def_cfa_offset_sf: + if ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0) + goto fail; + set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, + val * dci->data_align); /* factored! */ + Debug (15, "CFA_def_cfa_offset_sf 0x%lx\n", + (long) (val * dci->data_align)); + break; + + case DW_CFA_def_cfa_expression: + /* Save the address of the DW_FORM_block for later evaluation. */ + set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_EXPR, *addr); + + if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0) + goto fail; + + Debug (15, "CFA_def_cfa_expr @ 0x%lx [%lu bytes]\n", + (long) *addr, (long) len); + *addr += len; + break; + + case DW_CFA_expression: + if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + goto fail; + + /* Save the address of the DW_FORM_block for later evaluation. */ + set_reg (sr, regnum, DWARF_WHERE_EXPR, *addr); + + if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0) + goto fail; + + Debug (15, "CFA_expression r%lu @ 0x%lx [%lu bytes]\n", + (long) regnum, (long) addr, (long) len); + *addr += len; + break; + + case DW_CFA_val_expression: + if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + goto fail; + + /* Save the address of the DW_FORM_block for later evaluation. */ + set_reg (sr, regnum, DWARF_WHERE_VAL_EXPR, *addr); + + if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0) + goto fail; + + Debug (15, "CFA_val_expression r%lu @ 0x%lx [%lu bytes]\n", + (long) regnum, (long) addr, (long) len); + *addr += len; + break; + + case DW_CFA_GNU_args_size: + if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) + goto fail; + sr->args_size = val; + Debug (15, "CFA_GNU_args_size %lu\n", (long) val); + break; + + case DW_CFA_GNU_negative_offset_extended: + /* A comment in GCC says that this is obsoleted by + DW_CFA_offset_extended_sf, but that it's used by older + PowerPC code. */ + if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) + goto fail; + set_reg (sr, regnum, DWARF_WHERE_CFAREL, -(val * dci->data_align)); + Debug (15, "CFA_GNU_negative_offset_extended cfa+0x%lx\n", + (long) -(val * dci->data_align)); + break; + + case DW_CFA_GNU_window_save: +#ifdef UNW_TARGET_SPARC + /* This is a special CFA to handle all 16 windowed registers + on SPARC. */ + for (regnum = 16; regnum < 32; ++regnum) + set_reg (sr, regnum, DWARF_WHERE_CFAREL, + (regnum - 16) * sizeof (unw_word_t)); + Debug (15, "CFA_GNU_window_save\n"); + break; +#else + /* FALL THROUGH */ +#endif + case DW_CFA_lo_user: + case DW_CFA_hi_user: + Debug (1, "Unexpected CFA opcode 0x%x\n", op); + ret = -UNW_EINVAL; + goto fail; + } + } + ret = 0; + + fail: + /* Free the register-state stack, if not empty already. */ + while (rs_stack) + { + old_rs = rs_stack; + rs_stack = rs_stack->next; + free_reg_state (old_rs); + } + return ret; +} + +static int +fetch_proc_info (struct dwarf_cursor *c, unw_word_t ip, int need_unwind_info) +{ + int ret, dynamic = 1; + + /* The 'ip' can point either to the previous or next instruction + depending on what type of frame we have: normal call or a place + to resume execution (e.g. after signal frame). + + For a normal call frame we need to back up so we point within the + call itself; this is important because a) the call might be the + very last instruction of the function and the edge of the FDE, + and b) so that run_cfi_program() runs locations up to the call + but not more. + + For execution resume, we need to do the exact opposite and look + up using the current 'ip' value. That is where execution will + continue, and it's important we get this right, as 'ip' could be + right at the function entry and hence FDE edge, or at instruction + that manipulates CFA (push/pop). */ + if (c->use_prev_instr) + --ip; + + if (c->pi_valid && !need_unwind_info) + return 0; + + memset (&c->pi, 0, sizeof (c->pi)); + + /* check dynamic info first --- it overrides everything else */ + ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, need_unwind_info, + c->as_arg); + if (ret == -UNW_ENOINFO) + { + dynamic = 0; + if ((ret = tdep_find_proc_info (c, ip, need_unwind_info)) < 0) + return ret; + } + + if (c->pi.format != UNW_INFO_FORMAT_DYNAMIC + && c->pi.format != UNW_INFO_FORMAT_TABLE + && c->pi.format != UNW_INFO_FORMAT_REMOTE_TABLE) + return -UNW_ENOINFO; + + c->pi_valid = 1; + c->pi_is_dynamic = dynamic; + + /* Let system/machine-dependent code determine frame-specific attributes. */ + if (ret >= 0) + tdep_fetch_frame (c, ip, need_unwind_info); + + /* Update use_prev_instr for the next frame. */ + if (need_unwind_info) + { + assert(c->pi.unwind_info); + struct dwarf_cie_info *dci = c->pi.unwind_info; + c->use_prev_instr = ! dci->signal_frame; + } + + return ret; +} + +static int +parse_dynamic (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr) +{ + Debug (1, "Not yet implemented\n"); +#if 0 + /* Don't forget to set the ret_addr_column! */ + c->ret_addr_column = XXX; +#endif + return -UNW_ENOINFO; +} + +static inline void +put_unwind_info (struct dwarf_cursor *c, unw_proc_info_t *pi) +{ + if (c->pi_is_dynamic) + unwi_put_dynamic_unwind_info (c->as, pi, c->as_arg); + else if (pi->unwind_info && pi->format == UNW_INFO_FORMAT_TABLE) + { + mempool_free (&dwarf_cie_info_pool, pi->unwind_info); + pi->unwind_info = NULL; + } +} + +static inline int +parse_fde (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr) +{ + struct dwarf_cie_info *dci; + unw_word_t addr; + int ret; + + dci = c->pi.unwind_info; + c->ret_addr_column = dci->ret_addr_column; + + addr = dci->cie_instr_start; + if ((ret = run_cfi_program (c, sr, ~(unw_word_t) 0, &addr, + dci->cie_instr_end, dci)) < 0) + return ret; + + memcpy (&sr->rs_initial, &sr->rs_current, sizeof (sr->rs_initial)); + + addr = dci->fde_instr_start; + if ((ret = run_cfi_program (c, sr, ip, &addr, dci->fde_instr_end, dci)) < 0) + return ret; + + return 0; +} + +static inline void +flush_rs_cache (struct dwarf_rs_cache *cache) +{ + int i; + + cache->lru_head = DWARF_UNW_CACHE_SIZE - 1; + cache->lru_tail = 0; + + for (i = 0; i < DWARF_UNW_CACHE_SIZE; ++i) + { + if (i > 0) + cache->buckets[i].lru_chain = (i - 1); + cache->buckets[i].coll_chain = -1; + cache->buckets[i].ip = 0; + cache->buckets[i].valid = 0; + } + for (i = 0; ihash[i] = -1; +} + +static inline struct dwarf_rs_cache * +get_rs_cache (unw_addr_space_t as, intrmask_t *saved_maskp) +{ + struct dwarf_rs_cache *cache = &as->global_cache; + unw_caching_policy_t caching = as->caching_policy; + + if (caching == UNW_CACHE_NONE) + return NULL; + + if (likely (caching == UNW_CACHE_GLOBAL)) + { + Debug (16, "acquiring lock\n"); + lock_acquire (&cache->lock, *saved_maskp); + } + + if (atomic_read (&as->cache_generation) != atomic_read (&cache->generation)) + { + flush_rs_cache (cache); + cache->generation = as->cache_generation; + } + + return cache; +} + +static inline void +put_rs_cache (unw_addr_space_t as, struct dwarf_rs_cache *cache, + intrmask_t *saved_maskp) +{ + assert (as->caching_policy != UNW_CACHE_NONE); + + Debug (16, "unmasking signals/interrupts and releasing lock\n"); + if (likely (as->caching_policy == UNW_CACHE_GLOBAL)) + lock_release (&cache->lock, *saved_maskp); +} + +static inline unw_hash_index_t CONST_ATTR +hash (unw_word_t ip) +{ + /* based on (sqrt(5)/2-1)*2^64 */ +# define magic ((unw_word_t) 0x9e3779b97f4a7c16ULL) + + return ip * magic >> ((sizeof(unw_word_t) * 8) - DWARF_LOG_UNW_HASH_SIZE); +} + +static inline long +cache_match (dwarf_reg_state_t *rs, unw_word_t ip) +{ + if (rs->valid && (ip == rs->ip)) + return 1; + return 0; +} + +static dwarf_reg_state_t * +rs_lookup (struct dwarf_rs_cache *cache, struct dwarf_cursor *c) +{ + dwarf_reg_state_t *rs = cache->buckets + c->hint; + unsigned short index; + unw_word_t ip; + + ip = c->ip; + + if (cache_match (rs, ip)) + return rs; + + index = cache->hash[hash (ip)]; + if (index >= DWARF_UNW_CACHE_SIZE) + return NULL; + + rs = cache->buckets + index; + while (1) + { + if (cache_match (rs, ip)) + { + /* update hint; no locking needed: single-word writes are atomic */ + c->hint = cache->buckets[c->prev_rs].hint = + (rs - cache->buckets); + return rs; + } + if (rs->coll_chain >= DWARF_UNW_HASH_SIZE) + return NULL; + rs = cache->buckets + rs->coll_chain; + } +} + +static inline dwarf_reg_state_t * +rs_new (struct dwarf_rs_cache *cache, struct dwarf_cursor * c) +{ + dwarf_reg_state_t *rs, *prev, *tmp; + unw_hash_index_t index; + unsigned short head; + + head = cache->lru_head; + rs = cache->buckets + head; + cache->lru_head = rs->lru_chain; + + /* re-insert rs at the tail of the LRU chain: */ + cache->buckets[cache->lru_tail].lru_chain = head; + cache->lru_tail = head; + + /* remove the old rs from the hash table (if it's there): */ + if (rs->ip) + { + index = hash (rs->ip); + tmp = cache->buckets + cache->hash[index]; + prev = NULL; + while (1) + { + if (tmp == rs) + { + if (prev) + prev->coll_chain = tmp->coll_chain; + else + cache->hash[index] = tmp->coll_chain; + break; + } + else + prev = tmp; + if (tmp->coll_chain >= DWARF_UNW_CACHE_SIZE) + /* old rs wasn't in the hash-table */ + break; + tmp = cache->buckets + tmp->coll_chain; + } + } + + /* enter new rs in the hash table */ + index = hash (c->ip); + rs->coll_chain = cache->hash[index]; + cache->hash[index] = rs - cache->buckets; + + rs->hint = 0; + rs->ip = c->ip; + rs->valid = 1; + rs->ret_addr_column = c->ret_addr_column; + rs->signal_frame = 0; + tdep_cache_frame (c, rs); + + return rs; +} + +static int +create_state_record_for (struct dwarf_cursor *c, dwarf_state_record_t *sr, + unw_word_t ip) +{ + int i, ret; + + assert (c->pi_valid); + + memset (sr, 0, sizeof (*sr)); + for (i = 0; i < DWARF_NUM_PRESERVED_REGS + 2; ++i) + set_reg (sr, i, DWARF_WHERE_SAME, 0); + + switch (c->pi.format) + { + case UNW_INFO_FORMAT_TABLE: + case UNW_INFO_FORMAT_REMOTE_TABLE: + ret = parse_fde (c, ip, sr); + break; + + case UNW_INFO_FORMAT_DYNAMIC: + ret = parse_dynamic (c, ip, sr); + break; + + default: + Debug (1, "Unexpected unwind-info format %d\n", c->pi.format); + ret = -UNW_EINVAL; + } + return ret; +} + +static inline int +eval_location_expr (struct dwarf_cursor *c, unw_addr_space_t as, + unw_accessors_t *a, unw_word_t addr, + dwarf_loc_t *locp, void *arg) +{ + int ret, is_register; + unw_word_t len, val; + + /* read the length of the expression: */ + if ((ret = dwarf_read_uleb128 (as, a, &addr, &len, arg)) < 0) + return ret; + + /* evaluate the expression: */ + if ((ret = dwarf_eval_expr (c, &addr, len, &val, &is_register)) < 0) + return ret; + + if (is_register) + *locp = DWARF_REG_LOC (c, dwarf_to_unw_regnum (val)); + else + *locp = DWARF_MEM_LOC (c, val); + + return 0; +} + +static int +apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) +{ + unw_word_t regnum, addr, cfa, ip; + unw_word_t prev_ip, prev_cfa; + unw_addr_space_t as; + dwarf_loc_t cfa_loc; + unw_accessors_t *a; + int i, ret; + void *arg; + + prev_ip = c->ip; + prev_cfa = c->cfa; + + as = c->as; + arg = c->as_arg; + a = unw_get_accessors (as); + + /* Evaluate the CFA first, because it may be referred to by other + expressions. */ + + if (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_REG) + { + /* CFA is equal to [reg] + offset: */ + + /* As a special-case, if the stack-pointer is the CFA and the + stack-pointer wasn't saved, popping the CFA implicitly pops + the stack-pointer as well. */ + if ((rs->reg[DWARF_CFA_REG_COLUMN].val == UNW_TDEP_SP) + && (UNW_TDEP_SP < ARRAY_SIZE(rs->reg)) + && (rs->reg[UNW_TDEP_SP].where == DWARF_WHERE_SAME)) + cfa = c->cfa; + else + { + regnum = dwarf_to_unw_regnum (rs->reg[DWARF_CFA_REG_COLUMN].val); + if ((ret = unw_get_reg ((unw_cursor_t *) c, regnum, &cfa)) < 0) + return ret; + } + cfa += rs->reg[DWARF_CFA_OFF_COLUMN].val; + } + else + { + /* CFA is equal to EXPR: */ + + assert (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_EXPR); + + addr = rs->reg[DWARF_CFA_REG_COLUMN].val; + if ((ret = eval_location_expr (c, as, a, addr, &cfa_loc, arg)) < 0) + return ret; + /* the returned location better be a memory location... */ + if (DWARF_IS_REG_LOC (cfa_loc)) + return -UNW_EBADFRAME; + cfa = DWARF_GET_LOC (cfa_loc); + } + + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + { + switch ((dwarf_where_t) rs->reg[i].where) + { + case DWARF_WHERE_UNDEF: + c->loc[i] = DWARF_NULL_LOC; + break; + + case DWARF_WHERE_SAME: + break; + + case DWARF_WHERE_CFAREL: + c->loc[i] = DWARF_MEM_LOC (c, cfa + rs->reg[i].val); + break; + + case DWARF_WHERE_REG: + c->loc[i] = DWARF_REG_LOC (c, dwarf_to_unw_regnum (rs->reg[i].val)); + break; + + case DWARF_WHERE_EXPR: + addr = rs->reg[i].val; + if ((ret = eval_location_expr (c, as, a, addr, c->loc + i, arg)) < 0) + return ret; + break; + + case DWARF_WHERE_VAL_EXPR: + addr = rs->reg[i].val; + if ((ret = eval_location_expr (c, as, a, addr, c->loc + i, arg)) < 0) + return ret; + c->loc[i] = DWARF_VAL_LOC (c, DWARF_GET_LOC (c->loc[i])); + break; + } + } + + c->cfa = cfa; + /* DWARF spec says undefined return address location means end of stack. */ + if (DWARF_IS_NULL_LOC (c->loc[c->ret_addr_column])) + c->ip = 0; + else + { + ret = dwarf_get (c, c->loc[c->ret_addr_column], &ip); + if (ret < 0) + return ret; + c->ip = ip; + } + + /* XXX: check for ip to be code_aligned */ + if (c->ip == prev_ip && c->cfa == prev_cfa) + { + Dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n", + __FUNCTION__, (long) c->ip); + return -UNW_EBADFRAME; + } + + if (c->stash_frames) + tdep_stash_frame (c, rs); + + return 0; +} + +static int +uncached_dwarf_find_save_locs (struct dwarf_cursor *c) +{ + dwarf_state_record_t sr; + int ret; + + if ((ret = fetch_proc_info (c, c->ip, 1)) < 0) + { + put_unwind_info (c, &c->pi); + return ret; + } + + if ((ret = create_state_record_for (c, &sr, c->ip)) < 0) + return ret; + + if ((ret = apply_reg_state (c, &sr.rs_current)) < 0) + return ret; + + put_unwind_info (c, &c->pi); + return 0; +} + +/* The function finds the saved locations and applies the register + state as well. */ +HIDDEN int +dwarf_find_save_locs (struct dwarf_cursor *c) +{ + dwarf_state_record_t sr; + dwarf_reg_state_t *rs, rs_copy; + struct dwarf_rs_cache *cache; + int ret = 0; + intrmask_t saved_mask; + + if (c->as->caching_policy == UNW_CACHE_NONE) + return uncached_dwarf_find_save_locs (c); + + cache = get_rs_cache(c->as, &saved_mask); + rs = rs_lookup(cache, c); + + if (rs) + { + c->ret_addr_column = rs->ret_addr_column; + c->use_prev_instr = ! rs->signal_frame; + } + else + { + if ((ret = fetch_proc_info (c, c->ip, 1)) < 0 || + (ret = create_state_record_for (c, &sr, c->ip)) < 0) + { + put_rs_cache (c->as, cache, &saved_mask); + put_unwind_info (c, &c->pi); + return ret; + } + + rs = rs_new (cache, c); + memcpy(rs, &sr.rs_current, offsetof(struct dwarf_reg_state, ip)); + cache->buckets[c->prev_rs].hint = rs - cache->buckets; + + c->hint = rs->hint; + c->prev_rs = rs - cache->buckets; + + put_unwind_info (c, &c->pi); + } + + memcpy (&rs_copy, rs, sizeof (rs_copy)); + put_rs_cache (c->as, cache, &saved_mask); + + tdep_reuse_frame (c, &rs_copy); + if ((ret = apply_reg_state (c, &rs_copy)) < 0) + return ret; + + return 0; +} + +/* The proc-info must be valid for IP before this routine can be + called. */ +HIDDEN int +dwarf_create_state_record (struct dwarf_cursor *c, dwarf_state_record_t *sr) +{ + return create_state_record_for (c, sr, c->ip); +} + +HIDDEN int +dwarf_make_proc_info (struct dwarf_cursor *c) +{ +#if 0 + if (c->as->caching_policy == UNW_CACHE_NONE + || get_cached_proc_info (c) < 0) +#endif + /* Lookup it up the slow way... */ + return fetch_proc_info (c, c->ip, 0); + return 0; +} diff --git a/src/libs/libunwind/dwarf/Gpe.c b/src/libs/libunwind/dwarf/Gpe.c new file mode 100644 index 0000000000..611db7ec5d --- /dev/null +++ b/src/libs/libunwind/dwarf/Gpe.c @@ -0,0 +1,40 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "dwarf_i.h" +#include "libunwind_i.h" + +#include + +HIDDEN int +dwarf_read_encoded_pointer (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, unsigned char encoding, + unw_word_t gp, + unw_word_t start_ip, + unw_word_t *valp, void *arg) +{ + return dwarf_read_encoded_pointer_inlined (as, a, addr, encoding, + gp, start_ip, valp, arg); +} diff --git a/src/libs/libunwind/dwarf/Gstep.c b/src/libs/libunwind/dwarf/Gstep.c new file mode 100644 index 0000000000..d251af92a3 --- /dev/null +++ b/src/libs/libunwind/dwarf/Gstep.c @@ -0,0 +1,41 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "dwarf.h" +#include "libunwind_i.h" + +HIDDEN int +dwarf_step (struct dwarf_cursor *c) +{ + int ret; + + if ((ret = dwarf_find_save_locs (c)) >= 0) { + c->pi_valid = 0; + ret = 1; + } + + Debug (15, "returning %d\n", ret); + return ret; +} diff --git a/src/libs/libunwind/dwarf/Lexpr.c b/src/libs/libunwind/dwarf/Lexpr.c new file mode 100644 index 0000000000..245970c9e3 --- /dev/null +++ b/src/libs/libunwind/dwarf/Lexpr.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gexpr.c" +#endif diff --git a/src/libs/libunwind/dwarf/Lfde.c b/src/libs/libunwind/dwarf/Lfde.c new file mode 100644 index 0000000000..e779e8f192 --- /dev/null +++ b/src/libs/libunwind/dwarf/Lfde.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gfde.c" +#endif diff --git a/src/libs/libunwind/dwarf/Lfind_proc_info-lsb.c b/src/libs/libunwind/dwarf/Lfind_proc_info-lsb.c new file mode 100644 index 0000000000..27a5eeac18 --- /dev/null +++ b/src/libs/libunwind/dwarf/Lfind_proc_info-lsb.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gfind_proc_info-lsb.c" +#endif diff --git a/src/libs/libunwind/dwarf/Lfind_unwind_table.c b/src/libs/libunwind/dwarf/Lfind_unwind_table.c new file mode 100644 index 0000000000..68e269f1d7 --- /dev/null +++ b/src/libs/libunwind/dwarf/Lfind_unwind_table.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gfind_unwind_table.c" +#endif diff --git a/src/libs/libunwind/dwarf/Lparser.c b/src/libs/libunwind/dwarf/Lparser.c new file mode 100644 index 0000000000..f23aaf48e9 --- /dev/null +++ b/src/libs/libunwind/dwarf/Lparser.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gparser.c" +#endif diff --git a/src/libs/libunwind/dwarf/Lpe.c b/src/libs/libunwind/dwarf/Lpe.c new file mode 100644 index 0000000000..a672358f06 --- /dev/null +++ b/src/libs/libunwind/dwarf/Lpe.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gpe.c" +#endif diff --git a/src/libs/libunwind/dwarf/Lstep.c b/src/libs/libunwind/dwarf/Lstep.c new file mode 100644 index 0000000000..c1ac3c7547 --- /dev/null +++ b/src/libs/libunwind/dwarf/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/libs/libunwind/dwarf/global.c b/src/libs/libunwind/dwarf/global.c new file mode 100644 index 0000000000..8d0957d32b --- /dev/null +++ b/src/libs/libunwind/dwarf/global.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003-2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "dwarf_i.h" + +HIDDEN struct mempool dwarf_reg_state_pool; +HIDDEN struct mempool dwarf_cie_info_pool; + +HIDDEN int +dwarf_init (void) +{ + mempool_init (&dwarf_reg_state_pool, sizeof (dwarf_reg_state_t), 0); + mempool_init (&dwarf_cie_info_pool, sizeof (struct dwarf_cie_info), 0); + return 0; +} diff --git a/src/libs/libunwind/elf32.c b/src/libs/libunwind/elf32.c new file mode 100644 index 0000000000..a70bb58f24 --- /dev/null +++ b/src/libs/libunwind/elf32.c @@ -0,0 +1,4 @@ +#ifndef UNW_REMOTE_ONLY +# include "elf32.h" +# include "elfxx.c" +#endif diff --git a/src/libs/libunwind/elf32.h b/src/libs/libunwind/elf32.h new file mode 100644 index 0000000000..2c7bca4c9d --- /dev/null +++ b/src/libs/libunwind/elf32.h @@ -0,0 +1,9 @@ +#ifndef elf32_h +#define elf32_h + +#ifndef ELF_CLASS +#define ELF_CLASS ELFCLASS32 +#endif +#include "elfxx.h" + +#endif /* elf32_h */ diff --git a/src/libs/libunwind/elf64.c b/src/libs/libunwind/elf64.c new file mode 100644 index 0000000000..195b887948 --- /dev/null +++ b/src/libs/libunwind/elf64.c @@ -0,0 +1,4 @@ +#ifndef UNW_REMOTE_ONLY +# include "elf64.h" +# include "elfxx.c" +#endif diff --git a/src/libs/libunwind/elf64.h b/src/libs/libunwind/elf64.h new file mode 100644 index 0000000000..091fba8e1f --- /dev/null +++ b/src/libs/libunwind/elf64.h @@ -0,0 +1,9 @@ +#ifndef elf64_h +#define elf64_h + +#ifndef ELF_CLASS +#define ELF_CLASS ELFCLASS64 +#endif +#include "elfxx.h" + +#endif /* elf64_h */ diff --git a/src/libs/libunwind/elfxx.c b/src/libs/libunwind/elfxx.c new file mode 100644 index 0000000000..33fccba273 --- /dev/null +++ b/src/libs/libunwind/elfxx.c @@ -0,0 +1,359 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +#include +#include + +#ifdef HAVE_LZMA +#include +#endif /* HAVE_LZMA */ + +static Elf_W (Shdr)* +elf_w (section_table) (struct elf_image *ei) +{ + Elf_W (Ehdr) *ehdr = ei->image; + Elf_W (Off) soff; + + soff = ehdr->e_shoff; + if (soff + ehdr->e_shnum * ehdr->e_shentsize > ei->size) + { + Debug (1, "section table outside of image? (%lu > %lu)\n", + (unsigned long) (soff + ehdr->e_shnum * ehdr->e_shentsize), + (unsigned long) ei->size); + return NULL; + } + + return (Elf_W (Shdr) *) ((char *) ei->image + soff); +} + +static char* +elf_w (string_table) (struct elf_image *ei, int section) +{ + Elf_W (Ehdr) *ehdr = ei->image; + Elf_W (Off) soff, str_soff; + Elf_W (Shdr) *str_shdr; + + /* this offset is assumed to be OK */ + soff = ehdr->e_shoff; + + str_soff = soff + (section * ehdr->e_shentsize); + if (str_soff + ehdr->e_shentsize > ei->size) + { + Debug (1, "string shdr table outside of image? (%lu > %lu)\n", + (unsigned long) (str_soff + ehdr->e_shentsize), + (unsigned long) ei->size); + return NULL; + } + str_shdr = (Elf_W (Shdr) *) ((char *) ei->image + str_soff); + + if (str_shdr->sh_offset + str_shdr->sh_size > ei->size) + { + Debug (1, "string table outside of image? (%lu > %lu)\n", + (unsigned long) (str_shdr->sh_offset + str_shdr->sh_size), + (unsigned long) ei->size); + return NULL; + } + + Debug (16, "strtab=0x%lx\n", (long) str_shdr->sh_offset); + return ei->image + str_shdr->sh_offset; +} + +static int +elf_w (lookup_symbol) (unw_addr_space_t as, + unw_word_t ip, struct elf_image *ei, + Elf_W (Addr) load_offset, + char *buf, size_t buf_len, Elf_W (Addr) *min_dist) +{ + size_t syment_size; + Elf_W (Ehdr) *ehdr = ei->image; + Elf_W (Sym) *sym, *symtab, *symtab_end; + Elf_W (Shdr) *shdr; + Elf_W (Addr) val; + int i, ret = -UNW_ENOINFO; + char *strtab; + + if (!elf_w (valid_object) (ei)) + return -UNW_ENOINFO; + + shdr = elf_w (section_table) (ei); + if (!shdr) + return -UNW_ENOINFO; + + for (i = 0; i < ehdr->e_shnum; ++i) + { + switch (shdr->sh_type) + { + case SHT_SYMTAB: + case SHT_DYNSYM: + symtab = (Elf_W (Sym) *) ((char *) ei->image + shdr->sh_offset); + symtab_end = (Elf_W (Sym) *) ((char *) symtab + shdr->sh_size); + syment_size = shdr->sh_entsize; + + strtab = elf_w (string_table) (ei, shdr->sh_link); + if (!strtab) + break; + + Debug (16, "symtab=0x%lx[%d]\n", + (long) shdr->sh_offset, shdr->sh_type); + + for (sym = symtab; + sym < symtab_end; + sym = (Elf_W (Sym) *) ((char *) sym + syment_size)) + { + if (ELF_W (ST_TYPE) (sym->st_info) == STT_FUNC + && sym->st_shndx != SHN_UNDEF) + { + val = sym->st_value; + if (sym->st_shndx != SHN_ABS) + val += load_offset; + if (tdep_get_func_addr (as, val, &val) < 0) + continue; + Debug (16, "0x%016lx info=0x%02x %s\n", + (long) val, sym->st_info, strtab + sym->st_name); + + if ((Elf_W (Addr)) (ip - val) < *min_dist) + { + *min_dist = (Elf_W (Addr)) (ip - val); + strncpy (buf, strtab + sym->st_name, buf_len); + buf[buf_len - 1] = '\0'; + ret = (strlen (strtab + sym->st_name) >= buf_len + ? -UNW_ENOMEM : 0); + } + } + } + break; + + default: + break; + } + shdr = (Elf_W (Shdr) *) (((char *) shdr) + ehdr->e_shentsize); + } + return ret; +} + +static Elf_W (Addr) +elf_w (get_load_offset) (struct elf_image *ei, unsigned long segbase, + unsigned long mapoff) +{ + Elf_W (Addr) offset = 0; + Elf_W (Ehdr) *ehdr; + Elf_W (Phdr) *phdr; + int i; + + ehdr = ei->image; + phdr = (Elf_W (Phdr) *) ((char *) ei->image + ehdr->e_phoff); + + for (i = 0; i < ehdr->e_phnum; ++i) + if (phdr[i].p_type == PT_LOAD && phdr[i].p_offset == mapoff) + { + offset = segbase - phdr[i].p_vaddr; + break; + } + + return offset; +} + +#if HAVE_LZMA +static size_t +xz_uncompressed_size (uint8_t *compressed, size_t length) +{ + uint64_t memlimit = UINT64_MAX; + size_t ret = 0, pos = 0; + lzma_stream_flags options; + lzma_index *index; + + if (length < LZMA_STREAM_HEADER_SIZE) + return 0; + + uint8_t *footer = compressed + length - LZMA_STREAM_HEADER_SIZE; + if (lzma_stream_footer_decode (&options, footer) != LZMA_OK) + return 0; + + if (length < LZMA_STREAM_HEADER_SIZE + options.backward_size) + return 0; + + uint8_t *indexdata = footer - options.backward_size; + if (lzma_index_buffer_decode (&index, &memlimit, NULL, indexdata, + &pos, options.backward_size) != LZMA_OK) + return 0; + + if (lzma_index_size (index) == options.backward_size) + { + ret = lzma_index_uncompressed_size (index); + } + + lzma_index_end (index, NULL); + return ret; +} + +static int +elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi) +{ + Elf_W (Ehdr) *ehdr = ei->image; + Elf_W (Shdr) *shdr; + char *strtab; + int i; + uint8_t *compressed = NULL; + uint64_t memlimit = UINT64_MAX; /* no memory limit */ + size_t compressed_len, uncompressed_len; + + if (!elf_w (valid_object) (ei)) + return 0; + + shdr = elf_w (section_table) (ei); + if (!shdr) + return 0; + + strtab = elf_w (string_table) (ei, ehdr->e_shstrndx); + if (!strtab) + return 0; + + for (i = 0; i < ehdr->e_shnum; ++i) + { + if (strcmp (strtab + shdr->sh_name, ".gnu_debugdata") == 0) + { + if (shdr->sh_offset + shdr->sh_size > ei->size) + { + Debug (1, ".gnu_debugdata outside image? (0x%lu > 0x%lu)\n", + (unsigned long) shdr->sh_offset + shdr->sh_size, + (unsigned long) ei->size); + return 0; + } + + Debug (16, "found .gnu_debugdata at 0x%lx\n", + (unsigned long) shdr->sh_offset); + compressed = ((uint8_t *) ei->image) + shdr->sh_offset; + compressed_len = shdr->sh_size; + break; + } + + shdr = (Elf_W (Shdr) *) (((char *) shdr) + ehdr->e_shentsize); + } + + /* not found */ + if (!compressed) + return 0; + + uncompressed_len = xz_uncompressed_size (compressed, compressed_len); + if (uncompressed_len == 0) + { + Debug (1, "invalid .gnu_debugdata contents\n"); + return 0; + } + + mdi->size = uncompressed_len; + mdi->image = mmap (NULL, uncompressed_len, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + + if (mdi->image == MAP_FAILED) + return 0; + + size_t in_pos = 0, out_pos = 0; + lzma_ret lret; + lret = lzma_stream_buffer_decode (&memlimit, 0, NULL, + compressed, &in_pos, compressed_len, + mdi->image, &out_pos, mdi->size); + if (lret != LZMA_OK) + { + Debug (1, "LZMA decompression failed: %d\n", lret); + munmap (mdi->image, mdi->size); + return 0; + } + + return 1; +} +#else +static int +elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi) +{ + return 0; +} +#endif /* !HAVE_LZMA */ + +/* Find the ELF image that contains IP and return the "closest" + procedure name, if there is one. With some caching, this could be + sped up greatly, but until an application materializes that's + sensitive to the performance of this routine, why bother... */ + +HIDDEN int +elf_w (get_proc_name_in_image) (unw_addr_space_t as, struct elf_image *ei, + unsigned long segbase, + unsigned long mapoff, + unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp) +{ + Elf_W (Addr) load_offset; + Elf_W (Addr) min_dist = ~(Elf_W (Addr))0; + int ret; + + load_offset = elf_w (get_load_offset) (ei, segbase, mapoff); + ret = elf_w (lookup_symbol) (as, ip, ei, load_offset, buf, buf_len, &min_dist); + + /* If the ELF image has MiniDebugInfo embedded in it, look up the symbol in + there as well and replace the previously found if it is closer. */ + struct elf_image mdi; + if (elf_w (extract_minidebuginfo) (ei, &mdi)) + { + int ret_mdi = elf_w (lookup_symbol) (as, ip, &mdi, load_offset, buf, + buf_len, &min_dist); + + /* Closer symbol was found (possibly truncated). */ + if (ret_mdi == 0 || ret_mdi == -UNW_ENOMEM) + { + ret = ret_mdi; + } + + munmap (mdi.image, mdi.size); + } + + if (min_dist >= ei->size) + return -UNW_ENOINFO; /* not found */ + if (offp) + *offp = min_dist; + return ret; +} + +HIDDEN int +elf_w (get_proc_name) (unw_addr_space_t as, pid_t pid, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp) +{ + unsigned long segbase, mapoff; + struct elf_image ei; + int ret; + + ret = tdep_get_elf_image (&ei, pid, ip, &segbase, &mapoff, NULL, 0); + if (ret < 0) + return ret; + + ret = elf_w (get_proc_name_in_image) (as, &ei, segbase, mapoff, ip, buf, buf_len, offp); + + munmap (ei.image, ei.size); + ei.image = NULL; + + return ret; +} diff --git a/src/libs/libunwind/elfxx.h b/src/libs/libunwind/elfxx.h new file mode 100644 index 0000000000..cef6647b42 --- /dev/null +++ b/src/libs/libunwind/elfxx.h @@ -0,0 +1,98 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003, 2005 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include +#include + +#include "libunwind_i.h" + +#if ELF_CLASS == ELFCLASS32 +# define ELF_W(x) ELF32_##x +# define Elf_W(x) Elf32_##x +# define elf_w(x) _Uelf32_##x +#else +# define ELF_W(x) ELF64_##x +# define Elf_W(x) Elf64_##x +# define elf_w(x) _Uelf64_##x +#endif + +extern int elf_w (get_proc_name) (unw_addr_space_t as, + pid_t pid, unw_word_t ip, + char *buf, size_t len, + unw_word_t *offp); + +extern int elf_w (get_proc_name_in_image) (unw_addr_space_t as, + struct elf_image *ei, + unsigned long segbase, + unsigned long mapoff, + unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp); + +static inline int +elf_w (valid_object) (struct elf_image *ei) +{ + if (ei->size <= EI_VERSION) + return 0; + + return (memcmp (ei->image, ELFMAG, SELFMAG) == 0 + && ((uint8_t *) ei->image)[EI_CLASS] == ELF_CLASS + && ((uint8_t *) ei->image)[EI_VERSION] != EV_NONE + && ((uint8_t *) ei->image)[EI_VERSION] <= EV_CURRENT); +} + +static inline int +elf_map_image (struct elf_image *ei, const char *path) +{ + struct stat stat; + int fd; + + fd = open (path, O_RDONLY); + if (fd < 0) + return -1; + + if (fstat (fd, &stat) < 0) + { + close (fd); + return -1; + } + + ei->size = stat.st_size; + ei->image = mmap (NULL, ei->size, PROT_READ, MAP_PRIVATE, fd, 0); + close (fd); + if (ei->image == MAP_FAILED) + return -1; + + if (!elf_w (valid_object) (ei)) + { + munmap(ei->image, ei->size); + return -1; + } + + return 0; +} diff --git a/src/libs/libunwind/hppa/Gcreate_addr_space.c b/src/libs/libunwind/hppa/Gcreate_addr_space.c new file mode 100644 index 0000000000..71186e0e7a --- /dev/null +++ b/src/libs/libunwind/hppa/Gcreate_addr_space.c @@ -0,0 +1,54 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +PROTECTED unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * hppa supports only big-endian. + */ + if (byte_order != 0 && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + return as; +#endif +} diff --git a/src/libs/libunwind/hppa/Gget_proc_info.c b/src/libs/libunwind/hppa/Gget_proc_info.c new file mode 100644 index 0000000000..ce7a950aab --- /dev/null +++ b/src/libs/libunwind/hppa/Gget_proc_info.c @@ -0,0 +1,46 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + + if (dwarf_make_proc_info (&c->dwarf) < 0) + { + /* On hppa, some key routines such as _start() and _dl_start() + are missing DWARF unwind info. We don't want to fail in that + case, because those frames are uninteresting and just mark + the end of the frame-chain anyhow. */ + memset (pi, 0, sizeof (*pi)); + pi->start_ip = c->dwarf.ip; + pi->end_ip = c->dwarf.ip + 4; + return 0; + } + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/libs/libunwind/hppa/Gget_save_loc.c b/src/libs/libunwind/hppa/Gget_save_loc.c new file mode 100644 index 0000000000..549366a833 --- /dev/null +++ b/src/libs/libunwind/hppa/Gget_save_loc.c @@ -0,0 +1,59 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + /* struct cursor *c = (struct cursor *) cursor; */ + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + +#warning FIX ME! + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/libs/libunwind/hppa/Gglobal.c b/src/libs/libunwind/hppa/Gglobal.c new file mode 100644 index 0000000000..351a5015d6 --- /dev/null +++ b/src/libs/libunwind/hppa/Gglobal.c @@ -0,0 +1,55 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN define_lock (hppa_lock); +HIDDEN int tdep_init_done; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&hppa_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + hppa_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&hppa_lock, saved_mask); +} diff --git a/src/libs/libunwind/hppa/Ginit.c b/src/libs/libunwind/hppa/Ginit.c new file mode 100644 index 0000000000..89ad51caca --- /dev/null +++ b/src/libs/libunwind/hppa/Ginit.c @@ -0,0 +1,194 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2004 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +PROTECTED unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static inline void * +uc_addr (ucontext_t *uc, int reg) +{ + void *addr; + + if ((unsigned) (reg - UNW_HPPA_GR) < 32) + addr = &uc->uc_mcontext.sc_gr[reg - UNW_HPPA_GR]; + else if ((unsigned) (reg - UNW_HPPA_FR) < 32) + addr = &uc->uc_mcontext.sc_fr[reg - UNW_HPPA_FR]; + else + addr = NULL; + return addr; +} + +# ifdef UNW_LOCAL_ONLY + +void * +_Uhppa_uc_addr (ucontext_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (12, "mem[%x] <- %x\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "mem[%x] -> %x\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = arg; + + if ((unsigned int) (reg - UNW_HPPA_FR) < 32) + goto badreg; + + addr = uc_addr (uc, reg); + if (!addr) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %x\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %x\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + unw_fpreg_t *addr; + + if ((unsigned) (reg - UNW_HPPA_FR) > 32) + goto badreg; + + addr = uc_addr (uc, reg); + if (!addr) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08x.%08x\n", + unw_regname (reg), val->raw.bits[1], val->raw.bits[0]); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %08x.%08x\n", + unw_regname (reg), val->raw.bits[1], val->raw.bits[0]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +hppa_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = hppa_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/hppa/Ginit_local.c b/src/libs/libunwind/hppa/Ginit_local.c new file mode 100644 index 0000000000..0ad2f88463 --- /dev/null +++ b/src/libs/libunwind/hppa/Ginit_local.c @@ -0,0 +1,54 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by ... + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = uc; + return common_init (c, 1); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/hppa/Ginit_remote.c b/src/libs/libunwind/hppa/Ginit_remote.c new file mode 100644 index 0000000000..a4160fd191 --- /dev/null +++ b/src/libs/libunwind/hppa/Ginit_remote.c @@ -0,0 +1,46 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +PROTECTED int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/libs/libunwind/hppa/Gis_signal_frame.c b/src/libs/libunwind/hppa/Gis_signal_frame.c new file mode 100644 index 0000000000..00e40c6ac1 --- /dev/null +++ b/src/libs/libunwind/hppa/Gis_signal_frame.c @@ -0,0 +1,74 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, w2, w3, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors (as); + arg = c->dwarf.as_arg; + + /* Check if IP points at sigreturn() sequence. On Linux, this normally is: + + rt_sigreturn: + 0x34190000 ldi 0, %r25 + 0x3414015a ldi __NR_rt_sigreturn,%r20 + 0xe4008200 be,l 0x100(%sr2,%r0),%sr0,%r31 + 0x08000240 nop + + When a signal interrupts a system call, the first word is instead: + + 0x34190002 ldi 1, %r25 + */ + ip = c->dwarf.ip; + if (!ip) + return 0; + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 8, &w2, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 12, &w3, 0, arg)) < 0) + { + Debug (1, "failed to read sigreturn code (ret=%d)\n", ret); + return ret; + } + ret = ((w0 == 0x34190000 || w0 == 0x34190002) + && w1 == 0x3414015a && w2 == 0xe4008200 && w3 == 0x08000240); + Debug (1, "(cursor=%p, ip=0x%08lx) -> %d\n", c, (unsigned) ip, ret); + return ret; +#else + printf ("%s: implement me\n", __FUNCTION__); +#endif + return -UNW_ENOINFO; +} diff --git a/src/libs/libunwind/hppa/Gregs.c b/src/libs/libunwind/hppa/Gregs.c new file mode 100644 index 0000000000..da0542c81f --- /dev/null +++ b/src/libs/libunwind/hppa/Gregs.c @@ -0,0 +1,87 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + struct dwarf_loc loc; + + switch (reg) + { + case UNW_HPPA_IP: + if (write) + c->dwarf.ip = *valp; /* update the IP cache */ + if (c->dwarf.pi_valid && (*valp < c->dwarf.pi.start_ip + || *valp >= c->dwarf.pi.end_ip)) + c->dwarf.pi_valid = 0; /* new IP outside of current proc */ + break; + + case UNW_HPPA_CFA: + case UNW_HPPA_SP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + /* Do the exception-handling register remapping: */ + case UNW_HPPA_EH0: reg = UNW_HPPA_GR + 20; break; + case UNW_HPPA_EH1: reg = UNW_HPPA_GR + 21; break; + case UNW_HPPA_EH2: reg = UNW_HPPA_GR + 22; break; + case UNW_HPPA_EH3: reg = UNW_HPPA_GR + 31; break; + + default: + break; + } + + if ((unsigned) (reg - UNW_HPPA_GR) >= 32) + return -UNW_EBADREG; + + loc = c->dwarf.loc[reg]; + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + struct dwarf_loc loc; + + if ((unsigned) (reg - UNW_HPPA_FR) >= 32) + return -UNW_EBADREG; + + loc = c->dwarf.loc[reg]; + + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); +} diff --git a/src/libs/libunwind/hppa/Gresume.c b/src/libs/libunwind/hppa/Gresume.c new file mode 100644 index 0000000000..f6bc023f50 --- /dev/null +++ b/src/libs/libunwind/hppa/Gresume.c @@ -0,0 +1,145 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#ifndef UNW_REMOTE_ONLY + +#if defined(__linux) + +# include + +static NORETURN inline long +my_rt_sigreturn (void *new_sp, int in_syscall) +{ + register unsigned long r25 __asm__ ("r25") = (in_syscall != 0); + register unsigned long r20 __asm__ ("r20") = SYS_rt_sigreturn; + + __asm__ __volatile__ ("copy %0, %%sp\n" + "be,l 0x100(%%sr2,%%r0),%%sr0,%%r31\n" + "nop" + : + : "r"(new_sp), "r"(r20), "r"(r25) + : "memory"); + abort (); +} + +#endif /* __linux */ + +HIDDEN inline int +hppa_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ +#if defined(__linux) + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = c->dwarf.as_arg; + + /* Ensure c->pi is up-to-date. On PA-RISC, it's relatively common to be + missing DWARF unwind info. We don't want to fail in that case, + because the frame-chain still would let us do a backtrace at + least. */ + dwarf_make_proc_info (&c->dwarf); + + if (unlikely (c->sigcontext_format != HPPA_SCF_NONE)) + { + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + + Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc); + my_rt_sigreturn (sc, (sc->sc_flags & PARISC_SC_FLAG_IN_SYSCALL) != 0); + } + else + { + Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip); + setcontext (uc); + } +#else +# warning Implement me! +#endif + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +/* This routine is responsible for copying the register values in + cursor C and establishing them as the current machine state. */ + +static inline int +establish_machine_state (struct cursor *c) +{ + int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, + int write, void *); + int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, + int write, void *); + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + access_reg = as->acc.access_reg; + access_fpreg = as->acc.access_fpreg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + (*access_fpreg) (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + (*access_reg) (as, reg, &val, 1, arg); + } + } + return 0; +} + +PROTECTED int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if (!c->dwarf.ip) + { + /* This can happen easily when the frame-chain gets truncated + due to bad or missing unwind-info. */ + Debug (1, "refusing to resume execution at address 0\n"); + return -UNW_EINVAL; + } + + if ((ret = establish_machine_state (c)) < 0) + return ret; + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/libs/libunwind/hppa/Gstep.c b/src/libs/libunwind/hppa/Gstep.c new file mode 100644 index 0000000000..078ff4303d --- /dev/null +++ b/src/libs/libunwind/hppa/Gstep.c @@ -0,0 +1,96 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +PROTECTED int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret, i; + + Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip); + + /* Try DWARF-based unwinding... */ + ret = dwarf_step (&c->dwarf); + + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + if (unlikely (ret < 0)) + { + /* DWARF failed, let's see if we can follow the frame-chain + or skip over the signal trampoline. */ + + Debug (13, "dwarf_step() failed (ret=%d), trying fallback\n", ret); + + if (unw_is_signal_frame (cursor)) + { +#ifdef __linux__ + /* Assume that the trampoline is at the beginning of the + sigframe. */ + unw_word_t ip, sc_addr = c->dwarf.ip + LINUX_RT_SIGFRAME_UC_OFF; + dwarf_loc_t iaoq_loc = DWARF_LOC (sc_addr + LINUX_SC_IAOQ_OFF, 0); + + c->sigcontext_format = HPPA_SCF_LINUX_RT_SIGFRAME; + c->sigcontext_addr = sc_addr; + c->dwarf.ret_addr_column = UNW_HPPA_RP; + + if ((ret = dwarf_get (&c->dwarf, iaoq_loc, &ip)) < 0) + { + Debug (2, "failed to read IAOQ[1] (ret=%d)\n", ret); + return ret; + } + c->dwarf.ip = ip & ~0x3; /* mask out the privilege level */ + + for (i = 0; i < 32; ++i) + { + c->dwarf.loc[UNW_HPPA_GR + i] + = DWARF_LOC (sc_addr + LINUX_SC_GR_OFF + 4*i, 0); + c->dwarf.loc[UNW_HPPA_FR + i] + = DWARF_LOC (sc_addr + LINUX_SC_FR_OFF + 4*i, 0); + } + + if ((ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_HPPA_SP], + &c->dwarf.cfa)) < 0) + { + Debug (2, "failed to read SP (ret=%d)\n", ret); + return ret; + } +#else +# error Implement me! +#endif + } + else + c->dwarf.ip = 0; + } + ret = (c->dwarf.ip == 0) ? 0 : 1; + Debug (2, "returning %d\n", ret); + return ret; +} diff --git a/src/libs/libunwind/hppa/Lcreate_addr_space.c b/src/libs/libunwind/hppa/Lcreate_addr_space.c new file mode 100644 index 0000000000..0f2dc6be90 --- /dev/null +++ b/src/libs/libunwind/hppa/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/libs/libunwind/hppa/Lget_proc_info.c b/src/libs/libunwind/hppa/Lget_proc_info.c new file mode 100644 index 0000000000..69028b019f --- /dev/null +++ b/src/libs/libunwind/hppa/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/libs/libunwind/hppa/Lget_save_loc.c b/src/libs/libunwind/hppa/Lget_save_loc.c new file mode 100644 index 0000000000..9ea048a907 --- /dev/null +++ b/src/libs/libunwind/hppa/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/libs/libunwind/hppa/Lglobal.c b/src/libs/libunwind/hppa/Lglobal.c new file mode 100644 index 0000000000..6d7b489e14 --- /dev/null +++ b/src/libs/libunwind/hppa/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/libs/libunwind/hppa/Linit.c b/src/libs/libunwind/hppa/Linit.c new file mode 100644 index 0000000000..e9abfdd46a --- /dev/null +++ b/src/libs/libunwind/hppa/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/libs/libunwind/hppa/Linit_local.c b/src/libs/libunwind/hppa/Linit_local.c new file mode 100644 index 0000000000..68a1687e85 --- /dev/null +++ b/src/libs/libunwind/hppa/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/libs/libunwind/hppa/Linit_remote.c b/src/libs/libunwind/hppa/Linit_remote.c new file mode 100644 index 0000000000..58cb04ab7c --- /dev/null +++ b/src/libs/libunwind/hppa/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/libs/libunwind/hppa/Lis_signal_frame.c b/src/libs/libunwind/hppa/Lis_signal_frame.c new file mode 100644 index 0000000000..b9a7c4f51a --- /dev/null +++ b/src/libs/libunwind/hppa/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/libs/libunwind/hppa/Lregs.c b/src/libs/libunwind/hppa/Lregs.c new file mode 100644 index 0000000000..2c9c75cd7d --- /dev/null +++ b/src/libs/libunwind/hppa/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/libs/libunwind/hppa/Lresume.c b/src/libs/libunwind/hppa/Lresume.c new file mode 100644 index 0000000000..41a8cf003d --- /dev/null +++ b/src/libs/libunwind/hppa/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/libs/libunwind/hppa/Lstep.c b/src/libs/libunwind/hppa/Lstep.c new file mode 100644 index 0000000000..c1ac3c7547 --- /dev/null +++ b/src/libs/libunwind/hppa/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/libs/libunwind/hppa/get_accessors.c b/src/libs/libunwind/hppa/get_accessors.c new file mode 100644 index 0000000000..873a38c876 --- /dev/null +++ b/src/libs/libunwind/hppa/get_accessors.c @@ -0,0 +1,35 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by ... + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED unw_accessors_t * +unw_get_accessors (unw_addr_space_t as) +{ + if (!tdep_init_done) + tdep_init (); + + return &as->acc; +} diff --git a/src/libs/libunwind/hppa/getcontext.S b/src/libs/libunwind/hppa/getcontext.S new file mode 100644 index 0000000000..ec7554a025 --- /dev/null +++ b/src/libs/libunwind/hppa/getcontext.S @@ -0,0 +1,74 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#define SPILL(n) stw %r##n, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_GR_OFF+4*(n))(%r26) + +#include "offsets.h" + + .align 4 + .protected _Uhppa_getcontext + .global _Uhppa_getcontext + .proc + .callinfo +_Uhppa_getcontext: + SPILL (2) /* return-pointer */ + SPILL (3) /* frame pointer */ + SPILL (4) /* 2nd-ary frame pointer */ + SPILL (5) /* preserved register */ + SPILL (6) /* preserved register */ + SPILL (7) /* preserved register */ + SPILL (8) /* preserved register */ + SPILL (9) /* preserved register */ + SPILL (10) /* preserved register */ + SPILL (11) /* preserved register */ + SPILL (12) /* preserved register */ + SPILL (13) /* preserved register */ + SPILL (14) /* preserved register */ + SPILL (15) /* preserved register */ + SPILL (16) /* preserved register */ + SPILL (17) /* preserved register */ + SPILL (18) /* preserved register */ + SPILL (19) /* linkage-table register */ + SPILL (27) /* global-data pointer */ + SPILL (30) /* stack pointer */ + + ldo (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FR_OFF)(%r26), %r29 + fstds,ma %fr12, 8(%r29) + fstds,ma %fr13, 8(%r29) + fstds,ma %fr14, 8(%r29) + fstds,ma %fr15, 8(%r29) + fstds,ma %fr16, 8(%r29) + fstds,ma %fr17, 8(%r29) + fstds,ma %fr18, 8(%r29) + fstds,ma %fr19, 8(%r29) + fstds,ma %fr20, 8(%r29) + fstds %fr21, 8(%r29) + + bv,n %r0(%rp) + .procend +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/hppa/init.h b/src/libs/libunwind/hppa/init.h new file mode 100644 index 0000000000..4e23b86132 --- /dev/null +++ b/src/libs/libunwind/hppa/init.h @@ -0,0 +1,47 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by ... + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret; + + c->dwarf.loc[UNW_HPPA_IP] = DWARF_REG_LOC (&c->dwarf, UNW_HPPA_IP); + c->dwarf.loc[UNW_HPPA_SP] = DWARF_REG_LOC (&c->dwarf, UNW_HPPA_SP); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_HPPA_IP], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_HPPA_SP], &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + return 0; +} diff --git a/src/libs/libunwind/hppa/offsets.h b/src/libs/libunwind/hppa/offsets.h new file mode 100644 index 0000000000..24e6453ac4 --- /dev/null +++ b/src/libs/libunwind/hppa/offsets.h @@ -0,0 +1,17 @@ +#define LINUX_UC_FLAGS_OFF 0x000 +#define LINUX_UC_LINK_OFF 0x004 +#define LINUX_UC_STACK_OFF 0x008 +#define LINUX_UC_MCONTEXT_OFF 0x018 +#define LINUX_UC_SIGMASK_OFF 0x1b8 + +#define LINUX_SC_FLAGS_OFF 0x000 +#define LINUX_SC_GR_OFF 0x004 +#define LINUX_SC_FR_OFF 0x088 +#define LINUX_SC_IASQ_OFF 0x188 +#define LINUX_SC_IAOQ_OFF 0x190 +#define LINUX_SC_SAR_OFF 0x198 + +/* The signal frame contains 4 words of space for the sigreturn + trampoline, the siginfo structure, and then the sigcontext + structure. See include/asm-parisc/compat_rt_sigframe.h. */ +#define LINUX_RT_SIGFRAME_UC_OFF 0xac diff --git a/src/libs/libunwind/hppa/regname.c b/src/libs/libunwind/hppa/regname.c new file mode 100644 index 0000000000..06dfae7501 --- /dev/null +++ b/src/libs/libunwind/hppa/regname.c @@ -0,0 +1,50 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", + "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", + "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", + "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23", + "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31", + "ip", + "eh0", "eh1", "eh2", "eh3", + "cfa" + }; + +PROTECTED const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/libs/libunwind/hppa/setcontext.S b/src/libs/libunwind/hppa/setcontext.S new file mode 100644 index 0000000000..a36ea35cc6 --- /dev/null +++ b/src/libs/libunwind/hppa/setcontext.S @@ -0,0 +1,77 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* The setcontext() in glibc is a no-op (as of 4 Dec 2004), so we have + to implement something useful on our own here. */ + +#define FILL(n) ldw (LINUX_UC_MCONTEXT_OFF+LINUX_SC_GR_OFF+4*(n))(%r26),%r##n + +#include "offsets.h" + + .align 4 + .global _Uhppa_setcontext + .protected _Uhppa_setcontext + .proc + .callinfo +_Uhppa_setcontext: + FILL (2) /* return-pointer */ + FILL (3) /* frame pointer */ + FILL (4) /* 2nd-ary frame pointer */ + FILL (5) /* preserved register */ + FILL (6) /* preserved register */ + FILL (7) /* preserved register */ + FILL (8) /* preserved register */ + FILL (9) /* preserved register */ + FILL (10) /* preserved register */ + FILL (11) /* preserved register */ + FILL (12) /* preserved register */ + FILL (13) /* preserved register */ + FILL (14) /* preserved register */ + FILL (15) /* preserved register */ + FILL (16) /* preserved register */ + FILL (17) /* preserved register */ + FILL (18) /* preserved register */ + FILL (19) /* linkage-table register */ + FILL (27) /* global-data pointer */ + FILL (30) /* stack pointer */ + + ldo (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FR_OFF)(%r26), %r29 + fldds,ma 8(%r29), %fr12 + fldds,ma 8(%r29), %fr13 + fldds,ma 8(%r29), %fr14 + fldds,ma 8(%r29), %fr15 + fldds,ma 8(%r29), %fr16 + fldds,ma 8(%r29), %fr17 + fldds,ma 8(%r29), %fr18 + fldds,ma 8(%r29), %fr19 + fldds,ma 8(%r29), %fr20 + fldds 8(%r29), %fr21 + + bv,n %r0(%rp) + .procend +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/hppa/siglongjmp.S b/src/libs/libunwind/hppa/siglongjmp.S new file mode 100644 index 0000000000..34878dbe8f --- /dev/null +++ b/src/libs/libunwind/hppa/siglongjmp.S @@ -0,0 +1,16 @@ + /* Dummy implementation for now. */ + + .globl _UI_siglongjmp_cont + .globl _UI_longjmp_cont + +_UI_siglongjmp_cont: +_UI_longjmp_cont: + .proc + .callinfo +#warning fix me + bv %r0(%rp) + .procend +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/hppa/tables.c b/src/libs/libunwind/hppa/tables.c new file mode 100644 index 0000000000..5104d4d342 --- /dev/null +++ b/src/libs/libunwind/hppa/tables.c @@ -0,0 +1,43 @@ +#include "unwind_i.h" + +static inline int +is_local_addr_space (unw_addr_space_t as) +{ + extern unw_addr_space_t _ULhppa_local_addr_space; + + return (as == _Uhppa_local_addr_space +#ifndef UNW_REMOTE_ONLY + || as == _ULhppa_local_addr_space +#endif + ); +} + +HIDDEN int +tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, int need_unwind_info, void *arg) +{ + printf ("%s: begging to get implemented...\n", __FUNCTION__); + return 0; +} + +HIDDEN int +tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t *di, + unw_proc_info_t *pi, int need_unwind_info, void *arg) +{ + printf ("%s: the biggest beggar of them all...\n", __FUNCTION__); + return 0; +} + +HIDDEN void +tdep_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) +{ + if (!pi->unwind_info) + return; + + if (!is_local_addr_space (as)) + { + free (pi->unwind_info); + pi->unwind_info = NULL; + } +} diff --git a/src/libs/libunwind/hppa/unwind_i.h b/src/libs/libunwind/hppa/unwind_i.h new file mode 100644 index 0000000000..cafeab57b8 --- /dev/null +++ b/src/libs/libunwind/hppa/unwind_i.h @@ -0,0 +1,47 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include + +#include + +#include "libunwind_i.h" + +#define hppa_lock UNW_OBJ(lock) +#define hppa_local_resume UNW_OBJ(local_resume) +#define hppa_local_addr_space_init UNW_OBJ(local_addr_space_init) +#define hppa_scratch_loc UNW_OBJ(scratch_loc) +#define setcontext UNW_ARCH_OBJ (setcontext) + +extern void hppa_local_addr_space_init (void); +extern int hppa_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); +extern dwarf_loc_t hppa_scratch_loc (struct cursor *c, unw_regnum_t reg); +extern int setcontext (const ucontext_t *ucp); + +#endif /* unwind_i_h */ diff --git a/src/libs/libunwind/ia64/Gcreate_addr_space.c b/src/libs/libunwind/ia64/Gcreate_addr_space.c new file mode 100644 index 0000000000..20cf5d8bf1 --- /dev/null +++ b/src/libs/libunwind/ia64/Gcreate_addr_space.c @@ -0,0 +1,63 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +PROTECTED unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * IA-64 supports only big or little-endian, not weird stuff like + * PDP_ENDIAN. + */ + if (byte_order != 0 + && byte_order != __LITTLE_ENDIAN + && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + if (byte_order == 0) + /* use host default: */ + as->big_endian = (__BYTE_ORDER == __BIG_ENDIAN); + else + as->big_endian = (byte_order == __BIG_ENDIAN); + return as; +#endif +} diff --git a/src/libs/libunwind/ia64/Gfind_unwind_table.c b/src/libs/libunwind/ia64/Gfind_unwind_table.c new file mode 100644 index 0000000000..9fd2707ace --- /dev/null +++ b/src/libs/libunwind/ia64/Gfind_unwind_table.c @@ -0,0 +1,143 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include +#include +#include +#include + +#include + +#include "libunwind_i.h" +#include "elf64.h" + +static unw_word_t +find_gp (struct elf_dyn_info *edi, Elf64_Phdr *pdyn, Elf64_Addr load_base) +{ + Elf64_Off soff, str_soff; + Elf64_Ehdr *ehdr = edi->ei.image; + Elf64_Shdr *shdr; + Elf64_Shdr *str_shdr; + Elf64_Addr gp = 0; + char *strtab; + int i; + + if (pdyn) + { + /* If we have a PT_DYNAMIC program header, fetch the gp-value + from the DT_PLTGOT entry. */ + Elf64_Dyn *dyn = (Elf64_Dyn *) (pdyn->p_offset + (char *) edi->ei.image); + for (; dyn->d_tag != DT_NULL; ++dyn) + if (dyn->d_tag == DT_PLTGOT) + { + gp = (Elf64_Addr) dyn->d_un.d_ptr + load_base; + goto done; + } + } + + /* Without a PT_DYAMIC header, lets try to look for a non-empty .opd + section. If there is such a section, we know it's full of + function descriptors, and we can simply pick up the gp from the + second word of the first entry in this table. */ + + soff = ehdr->e_shoff; + str_soff = soff + (ehdr->e_shstrndx * ehdr->e_shentsize); + + if (soff + ehdr->e_shnum * ehdr->e_shentsize > edi->ei.size) + { + Debug (1, "section table outside of image? (%lu > %lu)", + soff + ehdr->e_shnum * ehdr->e_shentsize, + edi->ei.size); + goto done; + } + + shdr = (Elf64_Shdr *) ((char *) edi->ei.image + soff); + str_shdr = (Elf64_Shdr *) ((char *) edi->ei.image + str_soff); + strtab = (char *) edi->ei.image + str_shdr->sh_offset; + for (i = 0; i < ehdr->e_shnum; ++i) + { + if (strcmp (strtab + shdr->sh_name, ".opd") == 0 + && shdr->sh_size >= 16) + { + gp = ((Elf64_Addr *) ((char *) edi->ei.image + shdr->sh_offset))[1]; + goto done; + } + shdr = (Elf64_Shdr *) (((char *) shdr) + ehdr->e_shentsize); + } + + done: + Debug (16, "image at %p, gp = %lx\n", edi->ei.image, gp); + return gp; +} + +int +ia64_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, + char *path, unw_word_t segbase, unw_word_t mapoff, + unw_word_t ip) +{ + Elf64_Phdr *phdr, *ptxt = NULL, *punw = NULL, *pdyn = NULL; + Elf64_Ehdr *ehdr; + int i; + + if (!_Uelf64_valid_object (&edi->ei)) + return -UNW_ENOINFO; + + ehdr = edi->ei.image; + phdr = (Elf64_Phdr *) ((char *) edi->ei.image + ehdr->e_phoff); + + for (i = 0; i < ehdr->e_phnum; ++i) + { + switch (phdr[i].p_type) + { + case PT_LOAD: + if (phdr[i].p_offset == mapoff) + ptxt = phdr + i; + break; + + case PT_IA_64_UNWIND: + punw = phdr + i; + break; + + case PT_DYNAMIC: + pdyn = phdr + i; + break; + + default: + break; + } + } + if (!ptxt || !punw) + return 0; + + edi->di_cache.start_ip = segbase; + edi->di_cache.end_ip = edi->di_cache.start_ip + ptxt->p_memsz; + edi->di_cache.gp = find_gp (edi, pdyn, segbase - ptxt->p_vaddr); + edi->di_cache.format = UNW_INFO_FORMAT_TABLE; + edi->di_cache.u.ti.name_ptr = 0; + edi->di_cache.u.ti.segbase = segbase; + edi->di_cache.u.ti.table_len = punw->p_memsz / sizeof (unw_word_t); + edi->di_cache.u.ti.table_data = (unw_word_t *) + ((char *) edi->ei.image + (punw->p_vaddr - ptxt->p_vaddr)); + return 1; +} diff --git a/src/libs/libunwind/ia64/Gget_proc_info.c b/src/libs/libunwind/ia64/Gget_proc_info.c new file mode 100644 index 0000000000..6b4722d5d6 --- /dev/null +++ b/src/libs/libunwind/ia64/Gget_proc_info.c @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + if ((ret = ia64_make_proc_info (c)) < 0) + return ret; + *pi = c->pi; + return 0; +} diff --git a/src/libs/libunwind/ia64/Gget_save_loc.c b/src/libs/libunwind/ia64/Gget_save_loc.c new file mode 100644 index 0000000000..fc37ad9dc9 --- /dev/null +++ b/src/libs/libunwind/ia64/Gget_save_loc.c @@ -0,0 +1,168 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2003, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "rse.h" + +#include "offsets.h" +#include "regs.h" + +PROTECTED int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + ia64_loc_t loc, reg_loc; + uint8_t nat_bitnr; + int ret; + + loc = IA64_NULL_LOC; /* default to "not saved" */ + + switch (reg) + { + /* frame registers */ + case UNW_IA64_BSP: + case UNW_REG_SP: + default: + break; + + case UNW_REG_IP: + loc = c->loc[IA64_REG_IP]; + break; + + /* preserved registers: */ + case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: + loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_GR + 4))]; + break; + + case UNW_IA64_NAT + 4 ... UNW_IA64_NAT + 7: + loc = c->loc[IA64_REG_NAT4 + (reg - (UNW_IA64_NAT + 4))]; + reg_loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_NAT + 4))]; + nat_bitnr = c->nat_bitnr[reg - (UNW_IA64_NAT + 4)]; + if (IA64_IS_FP_LOC (reg_loc)) + /* NaT bit saved as a NaTVal. */ + loc = reg_loc; + break; + + case UNW_IA64_FR + 2: loc = c->loc[IA64_REG_F2]; break; + case UNW_IA64_FR + 3: loc = c->loc[IA64_REG_F3]; break; + case UNW_IA64_FR + 4: loc = c->loc[IA64_REG_F4]; break; + case UNW_IA64_FR + 5: loc = c->loc[IA64_REG_F5]; break; + case UNW_IA64_FR + 16 ... UNW_IA64_FR + 31: + loc = c->loc[IA64_REG_F16 + (reg - (UNW_IA64_FR + 16))]; + break; + + case UNW_IA64_AR_BSP: loc = c->loc[IA64_REG_BSP]; break; + case UNW_IA64_AR_BSPSTORE: loc = c->loc[IA64_REG_BSPSTORE]; break; + case UNW_IA64_AR_PFS: loc = c->loc[IA64_REG_PFS]; break; + case UNW_IA64_AR_RNAT: loc = c->loc[IA64_REG_RNAT]; break; + case UNW_IA64_AR_UNAT: loc = c->loc[IA64_REG_UNAT]; break; + case UNW_IA64_AR_LC: loc = c->loc[IA64_REG_LC]; break; + case UNW_IA64_AR_FPSR: loc = c->loc[IA64_REG_FPSR]; break; + case UNW_IA64_BR + 1: loc = c->loc[IA64_REG_B1]; break; + case UNW_IA64_BR + 2: loc = c->loc[IA64_REG_B2]; break; + case UNW_IA64_BR + 3: loc = c->loc[IA64_REG_B3]; break; + case UNW_IA64_BR + 4: loc = c->loc[IA64_REG_B4]; break; + case UNW_IA64_BR + 5: loc = c->loc[IA64_REG_B5]; break; + case UNW_IA64_CFM: loc = c->cfm_loc; break; + case UNW_IA64_PR: loc = c->loc[IA64_REG_PR]; break; + + case UNW_IA64_GR + 32 ... UNW_IA64_GR + 127: /* stacked reg */ + reg = rotate_gr (c, reg - UNW_IA64_GR); + ret = ia64_get_stacked (c, reg, &loc, NULL); + if (ret < 0) + return ret; + break; + + case UNW_IA64_NAT + 32 ... UNW_IA64_NAT + 127: /* stacked reg */ + reg = rotate_gr (c, reg - UNW_IA64_NAT); + ret = ia64_get_stacked (c, reg, NULL, &loc); + break; + + case UNW_IA64_AR_EC: + loc = c->cfm_loc; + break; + + /* scratch & special registers: */ + + case UNW_IA64_GR + 0: + case UNW_IA64_GR + 1: /* global pointer */ + case UNW_IA64_NAT + 0: + case UNW_IA64_NAT + 1: /* global pointer */ + case UNW_IA64_FR + 0: + case UNW_IA64_FR + 1: + break; + + case UNW_IA64_NAT + 2 ... UNW_IA64_NAT + 3: + case UNW_IA64_NAT + 8 ... UNW_IA64_NAT + 31: + loc = ia64_scratch_loc (c, reg, &nat_bitnr); + break; + + case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3: + case UNW_IA64_GR + 8 ... UNW_IA64_GR + 31: + case UNW_IA64_BR + 0: + case UNW_IA64_BR + 6: + case UNW_IA64_BR + 7: + case UNW_IA64_AR_RSC: + case UNW_IA64_AR_CSD: + case UNW_IA64_AR_SSD: + case UNW_IA64_AR_CCV: + loc = ia64_scratch_loc (c, reg, NULL); + break; + + case UNW_IA64_FR + 6 ... UNW_IA64_FR + 15: + loc = ia64_scratch_loc (c, reg, NULL); + break; + + case UNW_IA64_FR + 32 ... UNW_IA64_FR + 127: + reg = rotate_fr (c, reg - UNW_IA64_FR) + UNW_IA64_FR; + loc = ia64_scratch_loc (c, reg, NULL); + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (IA64_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (IA64_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = IA64_GET_REG (loc); + sloc->extra.nat_bitnr = nat_bitnr; + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = IA64_GET_ADDR (loc); + sloc->extra.nat_bitnr = nat_bitnr; + } + return 0; +} diff --git a/src/libs/libunwind/ia64/Gglobal.c b/src/libs/libunwind/ia64/Gglobal.c new file mode 100644 index 0000000000..5c6156f0e2 --- /dev/null +++ b/src/libs/libunwind/ia64/Gglobal.c @@ -0,0 +1,122 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +HIDDEN struct ia64_global_unwind_state unw = + { + .lock = PTHREAD_MUTEX_INITIALIZER, + .save_order = { + IA64_REG_IP, IA64_REG_PFS, IA64_REG_PSP, IA64_REG_PR, + IA64_REG_UNAT, IA64_REG_LC, IA64_REG_FPSR, IA64_REG_PRI_UNAT_GR + }, +#if UNW_DEBUG + .preg_name = { + "pri_unat_gr", "pri_unat_mem", "psp", "bsp", "bspstore", + "ar.pfs", "ar.rnat", "rp", + "r4", "r5", "r6", "r7", + "nat4", "nat5", "nat6", "nat7", + "ar.unat", "pr", "ar.lc", "ar.fpsr", + "b1", "b2", "b3", "b4", "b5", + "f2", "f3", "f4", "f5", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" + } +#endif +}; + +HIDDEN void +tdep_init (void) +{ + const uint8_t f1_bytes[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + const uint8_t nat_val_bytes[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + const uint8_t int_val_bytes[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + intrmask_t saved_mask; + uint8_t *lep, *bep; + long i; + + sigfillset (&unwi_full_mask); + + lock_acquire (&unw.lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + mempool_init (&unw.reg_state_pool, sizeof (struct ia64_reg_state), 0); + mempool_init (&unw.labeled_state_pool, + sizeof (struct ia64_labeled_state), 0); + + unw.read_only.r0 = 0; + unw.read_only.f0.raw.bits[0] = 0; + unw.read_only.f0.raw.bits[1] = 0; + + lep = (uint8_t *) &unw.read_only.f1_le + 16; + bep = (uint8_t *) &unw.read_only.f1_be; + for (i = 0; i < 16; ++i) + { + *--lep = f1_bytes[i]; + *bep++ = f1_bytes[i]; + } + + lep = (uint8_t *) &unw.nat_val_le + 16; + bep = (uint8_t *) &unw.nat_val_be; + for (i = 0; i < 16; ++i) + { + *--lep = nat_val_bytes[i]; + *bep++ = nat_val_bytes[i]; + } + + lep = (uint8_t *) &unw.int_val_le + 16; + bep = (uint8_t *) &unw.int_val_be; + for (i = 0; i < 16; ++i) + { + *--lep = int_val_bytes[i]; + *bep++ = int_val_bytes[i]; + } + + assert (8*sizeof(unw_hash_index_t) >= IA64_LOG_UNW_HASH_SIZE); + +#ifndef UNW_REMOTE_ONLY + ia64_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&unw.lock, saved_mask); +} diff --git a/src/libs/libunwind/ia64/Ginit.c b/src/libs/libunwind/ia64/Ginit.c new file mode 100644 index 0000000000..7b64f0c1e1 --- /dev/null +++ b/src/libs/libunwind/ia64/Ginit.c @@ -0,0 +1,505 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +#ifdef HAVE_SYS_UC_ACCESS_H +# include +#endif + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +PROTECTED unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space; + +#ifdef HAVE_SYS_UC_ACCESS_H + +#else /* !HAVE_SYS_UC_ACCESS_H */ + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg, uint8_t *nat_bitnr) +{ + return inlined_uc_addr (uc, reg, nat_bitnr); +} + +#endif /* !HAVE_SYS_UC_ACCESS_H */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + *dyn_info_list_addr = _U_dyn_info_list_addr (); + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (12, "mem[%lx] <- %lx\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "mem[%lx] -> %lx\n", addr, *val); + } + return 0; +} + +#ifdef HAVE_SYS_UC_ACCESS_H + +#define SYSCALL_CFM_SAVE_REG 11 /* on a syscall, ar.pfs is saved in r11 */ +#define REASON_SYSCALL 0 + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + ucontext_t *uc = arg; + unsigned int nat, mask; + uint64_t value; + uint16_t reason; + int ret; + + __uc_get_reason (uc, &reason); + + switch (reg) + { + case UNW_IA64_GR ... UNW_IA64_GR + 31: + if ((ret = __uc_get_grs (uc, (reg - UNW_IA64_GR), 1, &value, &nat))) + break; + + if (write) + ret = __uc_set_grs (uc, (reg - UNW_IA64_GR), 1, val, nat); + else + *val = value; + break; + + case UNW_IA64_NAT ... UNW_IA64_NAT + 31: + if ((ret = __uc_get_grs (uc, (reg - UNW_IA64_GR), 1, &value, &nat))) + break; + + mask = 1 << (reg - UNW_IA64_GR); + + if (write) + { + if (*val) + nat |= mask; + else + nat &= ~mask; + ret = __uc_set_grs (uc, (reg - UNW_IA64_GR), 1, &value, nat); + } + else + *val = (nat & mask) != 0; + break; + + case UNW_IA64_AR ... UNW_IA64_AR + 127: + if (reg == UNW_IA64_AR_BSP) + { + if (write) + ret = __uc_set_ar (uc, (reg - UNW_IA64_AR), *val); + else + ret = __uc_get_ar (uc, (reg - UNW_IA64_AR), val); + } + else if (reg == UNW_IA64_AR_PFS && reason == REASON_SYSCALL) + { + /* As of HP-UX 11.22, getcontext() does not have unwind info + and because of that, we need to hack thins manually here. + Hopefully, this is OK because the HP-UX kernel also needs + to know where AR.PFS has been saved, so the use of + register r11 for this purpose is pretty much nailed + down. */ + if (write) + ret = __uc_set_grs (uc, SYSCALL_CFM_SAVE_REG, 1, val, 0); + else + ret = __uc_get_grs (uc, SYSCALL_CFM_SAVE_REG, 1, val, &nat); + } + else + { + if (write) + ret = __uc_set_ar (uc, (reg - UNW_IA64_AR), *val); + else + ret = __uc_get_ar (uc, (reg - UNW_IA64_AR), val); + } + break; + + case UNW_IA64_BR ... UNW_IA64_BR + 7: + if (write) + ret = __uc_set_brs (uc, (reg - UNW_IA64_BR), 1, val); + else + ret = __uc_get_brs (uc, (reg - UNW_IA64_BR), 1, val); + break; + + case UNW_IA64_PR: + if (write) + ret = __uc_set_prs (uc, *val); + else + ret = __uc_get_prs (uc, val); + break; + + case UNW_IA64_IP: + if (write) + ret = __uc_set_ip (uc, *val); + else + ret = __uc_get_ip (uc, val); + break; + + case UNW_IA64_CFM: + if (write) + ret = __uc_set_cfm (uc, *val); + else + ret = __uc_get_cfm (uc, val); + break; + + case UNW_IA64_FR ... UNW_IA64_FR + 127: + default: + ret = EINVAL; + break; + } + + if (ret != 0) + { + Debug (1, "failed to %s %s (ret = %d)\n", + write ? "write" : "read", unw_regname (reg), ret); + return -UNW_EBADREG; + } + + if (write) + Debug (12, "%s <- %lx\n", unw_regname (reg), *val); + else + Debug (12, "%s -> %lx\n", unw_regname (reg), *val); + return 0; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + fp_regval_t fp_regval; + int ret; + + switch (reg) + { + case UNW_IA64_FR ... UNW_IA64_FR + 127: + if (write) + { + memcpy (&fp_regval, val, sizeof (fp_regval)); + ret = __uc_set_frs (uc, (reg - UNW_IA64_FR), 1, &fp_regval); + } + else + { + ret = __uc_get_frs (uc, (reg - UNW_IA64_FR), 1, &fp_regval); + memcpy (val, &fp_regval, sizeof (*val)); + } + break; + + default: + ret = EINVAL; + break; + } + if (ret != 0) + return -UNW_EBADREG; + + return 0; +} + +#else /* !HAVE_SYS_UC_ACCESS_H */ + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr, mask; + ucontext_t *uc = arg; + + if (reg >= UNW_IA64_NAT + 4 && reg <= UNW_IA64_NAT + 7) + { + mask = ((unw_word_t) 1) << (reg - UNW_IA64_NAT); + if (write) + { + if (*val) + uc->uc_mcontext.sc_nat |= mask; + else + uc->uc_mcontext.sc_nat &= ~mask; + } + else + *val = (uc->uc_mcontext.sc_nat & mask) != 0; + + if (write) + Debug (12, "%s <- %lx\n", unw_regname (reg), *val); + else + Debug (12, "%s -> %lx\n", unw_regname (reg), *val); + return 0; + } + + addr = tdep_uc_addr (uc, reg, NULL); + if (!addr) + goto badreg; + + if (write) + { + if (ia64_read_only_reg (addr)) + { + Debug (16, "attempt to write read-only register\n"); + return -UNW_EREADONLYREG; + } + *addr = *val; + Debug (12, "%s <- %lx\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %lx\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + unw_fpreg_t *addr; + + if (reg < UNW_IA64_FR || reg >= UNW_IA64_FR + 128) + goto badreg; + + addr = tdep_uc_addr (uc, reg, NULL); + if (!addr) + goto badreg; + + if (write) + { + if (ia64_read_only_reg (addr)) + { + Debug (16, "attempt to write read-only register\n"); + return -UNW_EREADONLYREG; + } + *addr = *val; + Debug (12, "%s <- %016lx.%016lx\n", + unw_regname (reg), val->raw.bits[1], val->raw.bits[0]); + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %016lx.%016lx\n", + unw_regname (reg), val->raw.bits[1], val->raw.bits[0]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +#endif /* !HAVE_SYS_UC_ACCESS_H */ + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +ia64_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); +#if defined(__linux) + local_addr_space.abi = ABI_LINUX; +#elif defined(__hpux) + local_addr_space.abi = ABI_HPUX; +#endif + local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.acc.find_proc_info = tdep_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = ia64_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ + +#ifndef UNW_LOCAL_ONLY + +HIDDEN int +ia64_uc_access_reg (struct cursor *c, ia64_loc_t loc, unw_word_t *valp, + int write) +{ +#ifdef HAVE_SYS_UC_ACCESS_H + unw_word_t uc_addr = IA64_GET_AUX_ADDR (loc); + ucontext_t *ucp; + int ret; + + Debug (16, "%s location %s\n", + write ? "writing" : "reading", ia64_strloc (loc)); + + if (c->as == unw_local_addr_space) + ucp = (ucontext_t *) uc_addr; + else + { + unw_word_t *dst, src; + + /* Need to copy-in ucontext_t first. */ + ucp = alloca (sizeof (ucontext_t)); + if (!ucp) + return -UNW_ENOMEM; + + /* For now, there is no non-HP-UX implementation of the + uc_access(3) interface. Because of that, we cannot, e.g., + unwind an HP-UX program from a Linux program. Should that + become possible at some point in the future, the + copy-in/copy-out needs to be adjusted to do byte-swapping if + necessary. */ + assert (c->as->big_endian == (__BYTE_ORDER == __BIG_ENDIAN)); + + dst = (unw_word_t *) ucp; + for (src = uc_addr; src < uc_addr + sizeof (ucontext_t); src += 8) + if ((ret = (*c->as->acc.access_mem) (c->as, src, dst++, 0, c->as_arg)) + < 0) + return ret; + } + + if (IA64_IS_REG_LOC (loc)) + ret = access_reg (unw_local_addr_space, IA64_GET_REG (loc), valp, write, + ucp); + else + { + /* Must be an access to the RSE backing store in ucontext_t. */ + unw_word_t addr = IA64_GET_ADDR (loc); + + if (write) + ret = __uc_set_rsebs (ucp, (uint64_t *) addr, 1, valp); + else + ret = __uc_get_rsebs (ucp, (uint64_t *) addr, 1, valp); + if (ret != 0) + ret = -UNW_EBADREG; + } + if (ret < 0) + return ret; + + if (write && c->as != unw_local_addr_space) + { + /* need to copy-out ucontext_t: */ + unw_word_t dst, *src = (unw_word_t *) ucp; + for (dst = uc_addr; dst < uc_addr + sizeof (ucontext_t); dst += 8) + if ((ret = (*c->as->acc.access_mem) (c->as, dst, src++, 1, c->as_arg)) + < 0) + return ret; + } + return 0; +#else /* !HAVE_SYS_UC_ACCESS_H */ + return -UNW_EINVAL; +#endif /* !HAVE_SYS_UC_ACCESS_H */ +} + +HIDDEN int +ia64_uc_access_fpreg (struct cursor *c, ia64_loc_t loc, unw_fpreg_t *valp, + int write) +{ +#ifdef HAVE_SYS_UC_ACCESS_H + unw_word_t uc_addr = IA64_GET_AUX_ADDR (loc); + ucontext_t *ucp; + int ret; + + if (c->as == unw_local_addr_space) + ucp = (ucontext_t *) uc_addr; + else + { + unw_word_t *dst, src; + + /* Need to copy-in ucontext_t first. */ + ucp = alloca (sizeof (ucontext_t)); + if (!ucp) + return -UNW_ENOMEM; + + /* For now, there is no non-HP-UX implementation of the + uc_access(3) interface. Because of that, we cannot, e.g., + unwind an HP-UX program from a Linux program. Should that + become possible at some point in the future, the + copy-in/copy-out needs to be adjusted to do byte-swapping if + necessary. */ + assert (c->as->big_endian == (__BYTE_ORDER == __BIG_ENDIAN)); + + dst = (unw_word_t *) ucp; + for (src = uc_addr; src < uc_addr + sizeof (ucontext_t); src += 8) + if ((ret = (*c->as->acc.access_mem) (c->as, src, dst++, 0, c->as_arg)) + < 0) + return ret; + } + + if ((ret = access_fpreg (unw_local_addr_space, IA64_GET_REG (loc), valp, + write, ucp)) < 0) + return ret; + + if (write && c->as != unw_local_addr_space) + { + /* need to copy-out ucontext_t: */ + unw_word_t dst, *src = (unw_word_t *) ucp; + for (dst = uc_addr; dst < uc_addr + sizeof (ucontext_t); dst += 8) + if ((ret = (*c->as->acc.access_mem) (c->as, dst, src++, 1, c->as_arg)) + < 0) + return ret; + } + return 0; +#else /* !HAVE_SYS_UC_ACCESS_H */ + return -UNW_EINVAL; +#endif /* !HAVE_SYS_UC_ACCESS_H */ +} + +#endif /* UNW_LOCAL_ONLY */ diff --git a/src/libs/libunwind/ia64/Ginit_local.c b/src/libs/libunwind/ia64/Ginit_local.c new file mode 100644 index 0000000000..8c727e1d31 --- /dev/null +++ b/src/libs/libunwind/ia64/Ginit_local.c @@ -0,0 +1,110 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2003, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +static inline void +set_as_arg (struct cursor *c, unw_context_t *uc) +{ +#if defined(__linux) && defined(__KERNEL__) + c->task = current; + c->as_arg = &uc->sw; +#else + c->as_arg = uc; +#endif +} + +static inline int +get_initial_stack_pointers (struct cursor *c, unw_context_t *uc, + unw_word_t *sp, unw_word_t *bsp) +{ +#if defined(__linux) + unw_word_t sol, bspstore; + +#ifdef __KERNEL__ + sol = (uc->sw.ar_pfs >> 7) & 0x7f; + bspstore = uc->sw.ar_bspstore; + *sp = uc->ksp; +# else + sol = (uc->uc_mcontext.sc_ar_pfs >> 7) & 0x7f; + bspstore = uc->uc_mcontext.sc_ar_bsp; + *sp = uc->uc_mcontext.sc_gr[12]; +# endif + *bsp = rse_skip_regs (bspstore, -sol); +#elif defined(__hpux) + int ret; + + if ((ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_GR + 12), sp)) < 0 + || (ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_AR_BSP), bsp)) < 0) + return ret; +#else +# error Fix me. +#endif + return 0; +} + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t sp, bsp; + int ret; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->as = unw_local_addr_space; + set_as_arg (c, uc); + + if ((ret = get_initial_stack_pointers (c, uc, &sp, &bsp)) < 0) + return ret; + + Debug (4, "initial bsp=%lx, sp=%lx\n", bsp, sp); + + if ((ret = common_init (c, sp, bsp)) < 0) + return ret; + +#ifdef __hpux + /* On HP-UX, the context created by getcontext() points to the + getcontext() system call stub. Step over it: */ + ret = unw_step (cursor); +#endif + return ret; +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/ia64/Ginit_remote.c b/src/libs/libunwind/ia64/Ginit_remote.c new file mode 100644 index 0000000000..e26a4e4b78 --- /dev/null +++ b/src/libs/libunwind/ia64/Ginit_remote.c @@ -0,0 +1,61 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +PROTECTED int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + unw_word_t sp, bsp; + int ret; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + if (as == unw_local_addr_space) + /* This special-casing is unfortunate and shouldn't be needed; + however, both Linux and HP-UX need to adjust the context a bit + before it's usable. Try to think of a cleaner way of doing + this. Not sure it's possible though, as long as we want to be + able to use the context returned by getcontext() et al. */ + return unw_init_local (cursor, as_arg); + + c->as = as; + c->as_arg = as_arg; + + if ((ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_GR + 12), &sp)) < 0 + || (ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_AR_BSP), &bsp)) < 0) + return ret; + + return common_init (c, sp, bsp); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/libs/libunwind/ia64/Ginstall_cursor.S b/src/libs/libunwind/ia64/Ginstall_cursor.S new file mode 100644 index 0000000000..6fb4401faa --- /dev/null +++ b/src/libs/libunwind/ia64/Ginstall_cursor.S @@ -0,0 +1,348 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "ucontext_i.h" + +#ifdef UNW_LOCAL_ONLY +# include "Lcursor_i.h" +# define ia64_install_cursor _ULia64_install_cursor +#else +# include "Gcursor_i.h" +# define ia64_install_cursor _Uia64_install_cursor +#endif + +#define SYS_sigreturn 1181 + +#ifndef UNW_REMOTE_ONLY + +/* ia64_install_cursor (const cursor *c, long pri_unat, long *extra, + long bspstore, long dirty_size, long *dirty_partition, + long dirty_rnat) + + Restores the machine-state represented by C and thereby resumes execution + in that frame. If the frame or one of its descendants was interrupted + by a signal, all registers are restored (including the signal mask). + Otherwise, only the preserved registers, the global-pointer (r1), and + the exception-arguments (r15-r18) are restored. */ + +#define pRet p6 +#define pSig p7 + + .align 32 + .hidden ia64_install_cursor + .global ia64_install_cursor + .proc ia64_install_cursor +ia64_install_cursor: + alloc r3 = ar.pfs, 7, 0, 0, 0 + invala + add r2 = FR_LOC_OFF, in0 + ;; + + ld8 r16 = [r2], LOC_SIZE // r16 = loc[IA64_REG_FR16] + mov.m r10 = ar.rsc // (ar.rsc: ~ 12 cycle latency) + add r3 = FR_LOC_OFF + 16, in0 + ;; + + ld8 r17 = [r2], 2*LOC_SIZE // r17 = loc[IA64_REG_FR17] + ld8 r18 = [r3], 2*LOC_SIZE // r18 = loc[IA64_REG_FR18] + and r16 = -4, r16 + ;; + + ld8 r19 = [r2], 2*LOC_SIZE // r19 = loc[IA64_REG_FR19] + ld8 r20 = [r3], 2*LOC_SIZE // r20 = loc[IA64_REG_FR20] + and r17 = -4, r17 + ;; + + ldf.fill f16 = [r16] // f16 restored (don't touch no more) + ldf.fill f17 = [r17] // f17 restored (don't touch no more) + and r18 = -4, r18 + + ld8 r21 = [r2], 2*LOC_SIZE // r21 = loc[IA64_REG_FR21] + ld8 r22 = [r3], 2*LOC_SIZE // r22 = loc[IA64_REG_FR22] + and r19 = -4, r19 + ;; + + ldf.fill f18 = [r18] // f18 restored (don't touch no more) + ldf.fill f19 = [r19] // f19 restored (don't touch no more) + and r20 = -4, r20 + + ld8 r23 = [r2], 2*LOC_SIZE // r23 = loc[IA64_REG_FR23] + ld8 r24 = [r3], 2*LOC_SIZE // r24 = loc[IA64_REG_FR24] + and r21 = -4, r21 + ;; + + ldf.fill f20 = [r20] // f20 restored (don't touch no more) + ldf.fill f21 = [r21] // f21 restored (don't touch no more) + and r22 = -4, r22 + + ld8 r25 = [r2], 2*LOC_SIZE // r25 = loc[IA64_REG_FR25] + ld8 r26 = [r3], 2*LOC_SIZE // r26 = loc[IA64_REG_FR26] + and r23 = -4, r23 + ;; + + ldf.fill f22 = [r22] // f22 restored (don't touch no more) + ldf.fill f23 = [r23] // f23 restored (don't touch no more) + and r24 = -4, r24 + + ld8 r27 = [r2], 2*LOC_SIZE // r27 = loc[IA64_REG_FR27] + ld8 r28 = [r3], 2*LOC_SIZE // r28 = loc[IA64_REG_FR28] + and r25 = -4, r25 + ;; + + ldf.fill f24 = [r24] // f24 restored (don't touch no more) + ldf.fill f25 = [r25] // f25 restored (don't touch no more) + and r26 = -4, r26 + + ld8 r29 = [r2], 2*LOC_SIZE // r29 = loc[IA64_REG_FR29] + ld8 r30 = [r3], 2*LOC_SIZE // r30 = loc[IA64_REG_FR30] + and r27 = -4, r27 + ;; + + ldf.fill f26 = [r26] // f26 restored (don't touch no more) + ldf.fill f27 = [r27] // f27 restored (don't touch no more) + and r28 = -4, r28 + + ld8 r31 = [r2] // r31 = loc[IA64_REG_FR31] + mov.m ar.unat = in1 + and r29 = -4, r29 + ;; + + ldf.fill f28 = [r28] // f28 restored (don't touch no more) + ldf.fill f29 = [r29] // f29 restored (don't touch no more) + and r30 = -4, r30 + + ld8 r1 = [in2], 8 // gp restored (don't touch no more) + add r8 = SIGCONTEXT_ADDR_OFF, in0 + and r31 = -4, r31 + ;; + + ld8 r8 = [r8] // r8 = sigcontext_addr + and r11 = 0x1c, r10 // clear all but rsc.be and rsc.pl + add r2 = PFS_LOC_OFF, in0 + + ldf.fill f30 = [r30] // f30 restored (don't touch no more) + ldf.fill f31 = [r31] // f31 restored (don't touch no more) + add r3 = 8, in2 + ;; + + ld8.fill r4 = [in2], 16 // r4 restored (don't touch no more) + ld8.fill r5 = [r3], 16 // r5 restored (don't touch no more) + cmp.eq pRet, pSig = r0, r8 // sigcontext_addr == NULL? + ;; + ld8.fill r6 = [in2], 16 // r6 restored (don't touch no more) + ld8.fill r7 = [r3] // r7 restored (don't touch no more) + add r3 = IP_OFF, in0 + ;; + + ld8 r14 = [r2], (B1_LOC_OFF - PFS_LOC_OFF) // r14 = pfs_loc + ld8 r15 = [r3] // r15 = ip + add r3 = (B2_LOC_OFF - IP_OFF), r3 + ;; + + ld8 r16 = [r2], (B3_LOC_OFF - B1_LOC_OFF) // r16 = b1_loc + ld8 r17= [r3], (B4_LOC_OFF - B2_LOC_OFF) // r17 = b2_loc + and r14 = -4, r14 + ;; + + ld8 r18 = [r2], (B5_LOC_OFF - B3_LOC_OFF) // r18 = b3_loc + ld8 r19 = [r3], (F2_LOC_OFF - B4_LOC_OFF) // r19 = b4_loc + and r16 = -4, r16 + ;; + + ld8 r20 = [r2], (F3_LOC_OFF - B5_LOC_OFF) // r20 = b5_loc + ld8 r21 = [r3], (F4_LOC_OFF - F2_LOC_OFF) // r21 = f2_loc + and r17 = -4, r17 + ;; + + ld8 r16 = [r16] // r16 = *b1_loc + ld8 r17 = [r17] // r17 = *b2_loc + and r18 = -4, r18 + + ld8 r22 = [r2], (F5_LOC_OFF - F3_LOC_OFF) // r21 = f3_loc + ld8 r23 = [r3], (UNAT_LOC_OFF - F4_LOC_OFF) // r22 = f4_loc + and r19 = -4, r19 + ;; + + ld8 r18 = [r18] // r18 = *b3_loc + ld8 r19 = [r19] // r19 = *b4_loc + and r20 = -4, r20 + + ld8 r24 = [r2], (LC_LOC_OFF - F5_LOC_OFF) // r24 = f5_loc + ld8 r25 = [r3], (FPSR_LOC_OFF - UNAT_LOC_OFF) // r25 = unat_loc + and r21 = -4, r21 + ;; + + and r22 = -4, r22 + and r23 = -4, r23 + and r24 = -4, r24 + + ld8 r20 = [r20] // r20 = *b5_loc + ldf.fill f2 = [r21] // f2 restored (don't touch no more) + mov b1 = r16 // b1 restored (don't touch no more) + ;; + + ldf.fill f3 = [r22] // f3 restored (don't touch no more) + ldf.fill f4 = [r23] // f4 restored (don't touch no more) + mov b2 = r17 // b2 restored (don't touch no more) + + ld8 r26 = [r2], (RNAT_LOC_OFF - LC_LOC_OFF) // r26 = lc_loc + ld8 r27 = [r3] // r27 = fpsr_loc + and r25 = -4, r25 + + add r3 = (PSP_OFF - FPSR_LOC_OFF), r3 + nop 0 + nop 0 + ;; + + ldf.fill f5 = [r24] // f5 restored (don't touch no more) +(pRet) ld8 r25 = [r25] // r25 = *unat_loc + mov b3 = r18 // b3 restored (don't touch no more) + + ld8 r28 = [r2], (BSP_OFF - RNAT_LOC_OFF) // r28 = rnat_loc + ld8 r29 = [r3], (PR_OFF - PSP_OFF) // r29 = sp + mov b4 = r19 // b4 restored (don't touch no more) + + and r26 = -4, r26 + and r27 = -4, r27 + mov b5 = r20 // b5 restored (don't touch no more) + ;; + + ld8 r26 = [r26] // r26 = *lc_loc + ld8 r27 = [r27] // r27 = *fpsr_loc + and r28 = -4, r28 + + mov r30 = in3 // make backup-copy of new bsp + ld8 r31 = [r3] // r31 = pr + mov rp = r15 + ;; + + ld8 r28 = [r28] // r28 = rnat + mov.m ar.rsc = r11 // put RSE into enforced lazy mode + mov.i ar.lc = r26 // lc restored (don't touch no more) + ;; + + loadrs // drop dirty partition + mov r9 = in2 // make backup-copy of &extra[r16] + cmp.eq p8, p0 = in4, r0 // dirty-size == 0? +(p8) br.cond.dpnt.many .skip_load_dirty + + mov r2 = in4 // make backup-copy of dirty_size + mov r15 = in5 // make backup-copy of dirty_partition + mov r16 = in6 // make backup-copy of dirty_rnat + ;; + + alloc r3 = ar.pfs, 0, 0, 0, 0 // drop register frame + dep r11 = r2, r11, 16, 16 + ;; + mov.m ar.bspstore = r15 + ;; + mov.m ar.rnat = r16 + mov.m ar.rsc = r11 // 14 cycles latency to loadrs + ;; + loadrs // loadup new dirty partition + ;; + +.skip_load_dirty: + mov.m ar.bspstore = r30 // restore register backing-store + add r3 = 8, r9 // r3 = &extra[r16] + ;; + +(pRet) mov.m ar.fpsr = r27 // fpsr restored (don't touch no more) + mov.m ar.rnat = r28 +(pSig) br.cond.dpnt.many .next + +/****** Return via br.ret: */ + + ld8 r14 = [r14] // r14 = *pfs_loc + ld8 r15 = [r9], 16 // r15 restored (don't touch no more) + mov pr = r31, -1 // pr restored (don't touch no more) + ;; + + ld8 r16 = [r3], 16 // r16 restored (don't touch no more) + ld8 r17 = [r9] // r17 restored (don't touch no more) + nop.i 0 + ;; + + ld8 r18 = [r3] // r18 restored (don't touch no more) + mov.m ar.rsc = r10 // restore original ar.rsc + mov sp = r29 + + mov.m ar.unat = r25 // unat restored (don't touch no more) + mov.i ar.pfs = r14 + br.ret.sptk.many rp + ;; + +/****** Return via sigreturn(): */ + +.next: mov.m ar.rsc = r10 // restore original ar.rsc + add r2 = (SC_FR + 6*16), r8 + add r3 = (SC_FR + 7*16), r8 + ;; + + ldf.fill f6 = [r2], 32 + ldf.fill f7 = [r3], 32 + nop 0 + ;; + + ldf.fill f8 = [r2], 32 + ldf.fill f9 = [r3], 32 + nop 0 + ;; + + ldf.fill f10 = [r2], 32 + ldf.fill f11 = [r3], 32 + nop 0 + ;; + + ldf.fill f12 = [r2], 32 + ldf.fill f13 = [r3], 32 + nop 0 + ;; + + ldf.fill f14 = [r2], 32 + ldf.fill f15 = [r3], 32 + mov sp = r29 + ;; + +#if NEW_SYSCALL + add r2 = 8, tp;; + ld8 r2 = [r2] + mov r15 = SYS_sigreturn + mov b7 = r2 + br.call.sptk.many b6 = b7 + ;; +#else + mov r15 = SYS_sigreturn + break 0x100000 +#endif + break 0 // bug out if sigreturn() returns + + .endp ia64_install_cursor + +#endif /* !UNW_REMOTE_ONLY */ +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/ia64/Gis_signal_frame.c b/src/libs/libunwind/ia64/Gis_signal_frame.c new file mode 100644 index 0000000000..0b7e19cbf9 --- /dev/null +++ b/src/libs/libunwind/ia64/Gis_signal_frame.c @@ -0,0 +1,54 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + struct ia64_state_record sr; + int ret; + + /* Crude and slow, but we need to peek ahead into the unwind + descriptors to find out if the current IP is inside the signal + trampoline. */ + ret = ia64_fetch_proc_info (c, c->ip, 1); + if (ret < 0) + return ret; + + ret = ia64_create_state_record (c, &sr); + if (ret < 0) + return ret; + + /* For now, we assume that any non-zero abi marker implies a signal frame. + This should get us pretty far. */ + ret = (sr.abi_marker != 0); + + ia64_free_state_record (&sr); + + Debug (1, "(cursor=%p, ip=0x%016lx) -> %d\n", c, c->ip, ret); + return ret; +} diff --git a/src/libs/libunwind/ia64/Gparser.c b/src/libs/libunwind/ia64/Gparser.c new file mode 100644 index 0000000000..b1f0f4a118 --- /dev/null +++ b/src/libs/libunwind/ia64/Gparser.c @@ -0,0 +1,1131 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* forward declaration: */ +static int create_state_record_for (struct cursor *c, + struct ia64_state_record *sr, + unw_word_t ip); + +typedef unsigned long unw_word; + +#define alloc_reg_state() (mempool_alloc (&unw.reg_state_pool)) +#define free_reg_state(rs) (mempool_free (&unw.reg_state_pool, rs)) +#define alloc_labeled_state() (mempool_alloc (&unw.labeled_state_pool)) +#define free_labeled_state(s) (mempool_free (&unw.labeled_state_pool, s)) + +/* Routines to manipulate the state stack. */ + +static inline void +push (struct ia64_state_record *sr) +{ + struct ia64_reg_state *rs; + + rs = alloc_reg_state (); + if (!rs) + { + print_error ("libunwind: cannot stack reg state!\n"); + return; + } + memcpy (rs, &sr->curr, sizeof (*rs)); + sr->curr.next = rs; +} + +static void +pop (struct ia64_state_record *sr) +{ + struct ia64_reg_state *rs = sr->curr.next; + + if (!rs) + { + print_error ("libunwind: stack underflow!\n"); + return; + } + memcpy (&sr->curr, rs, sizeof (*rs)); + free_reg_state (rs); +} + +/* Make a copy of the state stack. Non-recursive to avoid stack overflows. */ +static struct ia64_reg_state * +dup_state_stack (struct ia64_reg_state *rs) +{ + struct ia64_reg_state *copy, *prev = NULL, *first = NULL; + + while (rs) + { + copy = alloc_reg_state (); + if (!copy) + { + print_error ("unwind.dup_state_stack: out of memory\n"); + return NULL; + } + memcpy (copy, rs, sizeof (*copy)); + if (first) + prev->next = copy; + else + first = copy; + rs = rs->next; + prev = copy; + } + return first; +} + +/* Free all stacked register states (but not RS itself). */ +static void +free_state_stack (struct ia64_reg_state *rs) +{ + struct ia64_reg_state *p, *next; + + for (p = rs->next; p != NULL; p = next) + { + next = p->next; + free_reg_state (p); + } + rs->next = NULL; +} + +/* Unwind decoder routines */ + +static enum ia64_pregnum CONST_ATTR +decode_abreg (unsigned char abreg, int memory) +{ + switch (abreg) + { + case 0x04 ... 0x07: + return IA64_REG_R4 + (abreg - 0x04); + case 0x22 ... 0x25: + return IA64_REG_F2 + (abreg - 0x22); + case 0x30 ... 0x3f: + return IA64_REG_F16 + (abreg - 0x30); + case 0x41 ... 0x45: + return IA64_REG_B1 + (abreg - 0x41); + case 0x60: + return IA64_REG_PR; + case 0x61: + return IA64_REG_PSP; + case 0x62: + return memory ? IA64_REG_PRI_UNAT_MEM : IA64_REG_PRI_UNAT_GR; + case 0x63: + return IA64_REG_IP; + case 0x64: + return IA64_REG_BSP; + case 0x65: + return IA64_REG_BSPSTORE; + case 0x66: + return IA64_REG_RNAT; + case 0x67: + return IA64_REG_UNAT; + case 0x68: + return IA64_REG_FPSR; + case 0x69: + return IA64_REG_PFS; + case 0x6a: + return IA64_REG_LC; + default: + break; + } + Dprintf ("libunwind: bad abreg=0x%x\n", abreg); + return IA64_REG_LC; +} + +static void +set_reg (struct ia64_reg_info *reg, enum ia64_where where, int when, + unsigned long val) +{ + reg->val = val; + reg->where = where; + if (reg->when == IA64_WHEN_NEVER) + reg->when = when; +} + +static void +alloc_spill_area (unsigned long *offp, unsigned long regsize, + struct ia64_reg_info *lo, struct ia64_reg_info *hi) +{ + struct ia64_reg_info *reg; + + for (reg = hi; reg >= lo; --reg) + { + if (reg->where == IA64_WHERE_SPILL_HOME) + { + reg->where = IA64_WHERE_PSPREL; + *offp -= regsize; + reg->val = *offp; + } + } +} + +static inline void +spill_next_when (struct ia64_reg_info **regp, struct ia64_reg_info *lim, + unw_word t) +{ + struct ia64_reg_info *reg; + + for (reg = *regp; reg <= lim; ++reg) + { + if (reg->where == IA64_WHERE_SPILL_HOME) + { + reg->when = t; + *regp = reg + 1; + return; + } + } + Dprintf ("libunwind: excess spill!\n"); +} + +static inline void +finish_prologue (struct ia64_state_record *sr) +{ + struct ia64_reg_info *reg; + unsigned long off; + int i; + + /* First, resolve implicit register save locations (see Section + "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */ + for (i = 0; i < (int) ARRAY_SIZE (unw.save_order); ++i) + { + reg = sr->curr.reg + unw.save_order[i]; + if (reg->where == IA64_WHERE_GR_SAVE) + { + reg->where = IA64_WHERE_GR; + reg->val = sr->gr_save_loc++; + } + } + + /* Next, compute when the fp, general, and branch registers get + saved. This must come before alloc_spill_area() because we need + to know which registers are spilled to their home locations. */ + + if (sr->imask) + { + unsigned char kind, mask = 0, *cp = sr->imask; + unsigned long t; + static const unsigned char limit[3] = + { + IA64_REG_F31, IA64_REG_R7, IA64_REG_B5 + }; + struct ia64_reg_info *(regs[3]); + + regs[0] = sr->curr.reg + IA64_REG_F2; + regs[1] = sr->curr.reg + IA64_REG_R4; + regs[2] = sr->curr.reg + IA64_REG_B1; + + for (t = 0; (int) t < sr->region_len; ++t) + { + if ((t & 3) == 0) + mask = *cp++; + kind = (mask >> 2 * (3 - (t & 3))) & 3; + if (kind > 0) + spill_next_when (®s[kind - 1], sr->curr.reg + limit[kind - 1], + sr->region_start + t); + } + } + + /* Next, lay out the memory stack spill area. */ + + if (sr->any_spills) + { + off = sr->spill_offset; + alloc_spill_area (&off, 16, sr->curr.reg + IA64_REG_F2, + sr->curr.reg + IA64_REG_F31); + alloc_spill_area (&off, 8, sr->curr.reg + IA64_REG_B1, + sr->curr.reg + IA64_REG_B5); + alloc_spill_area (&off, 8, sr->curr.reg + IA64_REG_R4, + sr->curr.reg + IA64_REG_R7); + } +} + +/* Region header descriptors. */ + +static void +desc_prologue (int body, unw_word rlen, unsigned char mask, + unsigned char grsave, struct ia64_state_record *sr) +{ + int i, region_start; + + if (!(sr->in_body || sr->first_region)) + finish_prologue (sr); + sr->first_region = 0; + + /* check if we're done: */ + if (sr->when_target < sr->region_start + sr->region_len) + { + sr->done = 1; + return; + } + + region_start = sr->region_start + sr->region_len; + + for (i = 0; i < sr->epilogue_count; ++i) + pop (sr); + sr->epilogue_count = 0; + sr->when_sp_restored = IA64_WHEN_NEVER; + + sr->region_start = region_start; + sr->region_len = rlen; + sr->in_body = body; + + if (!body) + { + push (sr); + + if (mask) + for (i = 0; i < 4; ++i) + { + if (mask & 0x8) + set_reg (sr->curr.reg + unw.save_order[i], IA64_WHERE_GR, + sr->region_start + sr->region_len - 1, grsave++); + mask <<= 1; + } + sr->gr_save_loc = grsave; + sr->any_spills = 0; + sr->imask = 0; + sr->spill_offset = 0x10; /* default to psp+16 */ + } +} + +/* Prologue descriptors. */ + +static inline void +desc_abi (unsigned char abi, unsigned char context, + struct ia64_state_record *sr) +{ + sr->abi_marker = (abi << 8) | context; +} + +static inline void +desc_br_gr (unsigned char brmask, unsigned char gr, + struct ia64_state_record *sr) +{ + int i; + + for (i = 0; i < 5; ++i) + { + if (brmask & 1) + set_reg (sr->curr.reg + IA64_REG_B1 + i, IA64_WHERE_GR, + sr->region_start + sr->region_len - 1, gr++); + brmask >>= 1; + } +} + +static inline void +desc_br_mem (unsigned char brmask, struct ia64_state_record *sr) +{ + int i; + + for (i = 0; i < 5; ++i) + { + if (brmask & 1) + { + set_reg (sr->curr.reg + IA64_REG_B1 + i, IA64_WHERE_SPILL_HOME, + sr->region_start + sr->region_len - 1, 0); + sr->any_spills = 1; + } + brmask >>= 1; + } +} + +static inline void +desc_frgr_mem (unsigned char grmask, unw_word frmask, + struct ia64_state_record *sr) +{ + int i; + + for (i = 0; i < 4; ++i) + { + if ((grmask & 1) != 0) + { + set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_SPILL_HOME, + sr->region_start + sr->region_len - 1, 0); + sr->any_spills = 1; + } + grmask >>= 1; + } + for (i = 0; i < 20; ++i) + { + if ((frmask & 1) != 0) + { + int base = (i < 4) ? IA64_REG_F2 : IA64_REG_F16 - 4; + set_reg (sr->curr.reg + base + i, IA64_WHERE_SPILL_HOME, + sr->region_start + sr->region_len - 1, 0); + sr->any_spills = 1; + } + frmask >>= 1; + } +} + +static inline void +desc_fr_mem (unsigned char frmask, struct ia64_state_record *sr) +{ + int i; + + for (i = 0; i < 4; ++i) + { + if ((frmask & 1) != 0) + { + set_reg (sr->curr.reg + IA64_REG_F2 + i, IA64_WHERE_SPILL_HOME, + sr->region_start + sr->region_len - 1, 0); + sr->any_spills = 1; + } + frmask >>= 1; + } +} + +static inline void +desc_gr_gr (unsigned char grmask, unsigned char gr, + struct ia64_state_record *sr) +{ + int i; + + for (i = 0; i < 4; ++i) + { + if ((grmask & 1) != 0) + set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_GR, + sr->region_start + sr->region_len - 1, gr++); + grmask >>= 1; + } +} + +static inline void +desc_gr_mem (unsigned char grmask, struct ia64_state_record *sr) +{ + int i; + + for (i = 0; i < 4; ++i) + { + if ((grmask & 1) != 0) + { + set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_SPILL_HOME, + sr->region_start + sr->region_len - 1, 0); + sr->any_spills = 1; + } + grmask >>= 1; + } +} + +static inline void +desc_mem_stack_f (unw_word t, unw_word size, struct ia64_state_record *sr) +{ + set_reg (sr->curr.reg + IA64_REG_PSP, IA64_WHERE_NONE, + sr->region_start + MIN ((int) t, sr->region_len - 1), 16 * size); +} + +static inline void +desc_mem_stack_v (unw_word t, struct ia64_state_record *sr) +{ + sr->curr.reg[IA64_REG_PSP].when = + sr->region_start + MIN ((int) t, sr->region_len - 1); +} + +static inline void +desc_reg_gr (unsigned char reg, unsigned char dst, + struct ia64_state_record *sr) +{ + set_reg (sr->curr.reg + reg, IA64_WHERE_GR, + sr->region_start + sr->region_len - 1, dst); +} + +static inline void +desc_reg_psprel (unsigned char reg, unw_word pspoff, + struct ia64_state_record *sr) +{ + set_reg (sr->curr.reg + reg, IA64_WHERE_PSPREL, + sr->region_start + sr->region_len - 1, 0x10 - 4 * pspoff); +} + +static inline void +desc_reg_sprel (unsigned char reg, unw_word spoff, + struct ia64_state_record *sr) +{ + set_reg (sr->curr.reg + reg, IA64_WHERE_SPREL, + sr->region_start + sr->region_len - 1, 4 * spoff); +} + +static inline void +desc_rp_br (unsigned char dst, struct ia64_state_record *sr) +{ + sr->return_link_reg = dst; +} + +static inline void +desc_reg_when (unsigned char regnum, unw_word t, struct ia64_state_record *sr) +{ + struct ia64_reg_info *reg = sr->curr.reg + regnum; + + if (reg->where == IA64_WHERE_NONE) + reg->where = IA64_WHERE_GR_SAVE; + reg->when = sr->region_start + MIN ((int) t, sr->region_len - 1); +} + +static inline void +desc_spill_base (unw_word pspoff, struct ia64_state_record *sr) +{ + sr->spill_offset = 0x10 - 4 * pspoff; +} + +static inline unsigned char * +desc_spill_mask (unsigned char *imaskp, struct ia64_state_record *sr) +{ + sr->imask = imaskp; + return imaskp + (2 * sr->region_len + 7) / 8; +} + +/* Body descriptors. */ + +static inline void +desc_epilogue (unw_word t, unw_word ecount, struct ia64_state_record *sr) +{ + sr->when_sp_restored = sr->region_start + sr->region_len - 1 - t; + sr->epilogue_count = ecount + 1; +} + +static inline void +desc_copy_state (unw_word label, struct ia64_state_record *sr) +{ + struct ia64_labeled_state *ls; + + for (ls = sr->labeled_states; ls; ls = ls->next) + { + if (ls->label == label) + { + free_state_stack (&sr->curr); + memcpy (&sr->curr, &ls->saved_state, sizeof (sr->curr)); + sr->curr.next = dup_state_stack (ls->saved_state.next); + return; + } + } + print_error ("libunwind: failed to find labeled state\n"); +} + +static inline void +desc_label_state (unw_word label, struct ia64_state_record *sr) +{ + struct ia64_labeled_state *ls; + + ls = alloc_labeled_state (); + if (!ls) + { + print_error ("unwind.desc_label_state(): out of memory\n"); + return; + } + ls->label = label; + memcpy (&ls->saved_state, &sr->curr, sizeof (ls->saved_state)); + ls->saved_state.next = dup_state_stack (sr->curr.next); + + /* insert into list of labeled states: */ + ls->next = sr->labeled_states; + sr->labeled_states = ls; +} + +/* General descriptors. */ + +static inline int +desc_is_active (unsigned char qp, unw_word t, struct ia64_state_record *sr) +{ + if (sr->when_target <= sr->region_start + MIN ((int) t, sr->region_len - 1)) + return 0; + if (qp > 0) + { + if ((sr->pr_val & ((unw_word_t) 1 << qp)) == 0) + return 0; + sr->pr_mask |= ((unw_word_t) 1 << qp); + } + return 1; +} + +static inline void +desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg, + struct ia64_state_record *sr) +{ + struct ia64_reg_info *r; + + if (!desc_is_active (qp, t, sr)) + return; + + r = sr->curr.reg + decode_abreg (abreg, 0); + r->where = IA64_WHERE_NONE; + r->when = IA64_WHEN_NEVER; + r->val = 0; +} + +static inline void +desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg, + unsigned char x, unsigned char ytreg, + struct ia64_state_record *sr) +{ + enum ia64_where where = IA64_WHERE_GR; + struct ia64_reg_info *r; + + if (!desc_is_active (qp, t, sr)) + return; + + if (x) + where = IA64_WHERE_BR; + else if (ytreg & 0x80) + where = IA64_WHERE_FR; + + r = sr->curr.reg + decode_abreg (abreg, 0); + r->where = where; + r->when = sr->region_start + MIN ((int) t, sr->region_len - 1); + r->val = (ytreg & 0x7f); +} + +static inline void +desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg, + unw_word pspoff, struct ia64_state_record *sr) +{ + struct ia64_reg_info *r; + + if (!desc_is_active (qp, t, sr)) + return; + + r = sr->curr.reg + decode_abreg (abreg, 1); + r->where = IA64_WHERE_PSPREL; + r->when = sr->region_start + MIN ((int) t, sr->region_len - 1); + r->val = 0x10 - 4 * pspoff; +} + +static inline void +desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg, + unw_word spoff, struct ia64_state_record *sr) +{ + struct ia64_reg_info *r; + + if (!desc_is_active (qp, t, sr)) + return; + + r = sr->curr.reg + decode_abreg (abreg, 1); + r->where = IA64_WHERE_SPREL; + r->when = sr->region_start + MIN ((int) t, sr->region_len - 1); + r->val = 4 * spoff; +} + +#define UNW_DEC_BAD_CODE(code) \ + print_error ("libunwind: unknown code encountered\n") + +/* Register names. */ +#define UNW_REG_BSP IA64_REG_BSP +#define UNW_REG_BSPSTORE IA64_REG_BSPSTORE +#define UNW_REG_FPSR IA64_REG_FPSR +#define UNW_REG_LC IA64_REG_LC +#define UNW_REG_PFS IA64_REG_PFS +#define UNW_REG_PR IA64_REG_PR +#define UNW_REG_RNAT IA64_REG_RNAT +#define UNW_REG_PSP IA64_REG_PSP +#define UNW_REG_RP IA64_REG_IP +#define UNW_REG_UNAT IA64_REG_UNAT + +/* Region headers. */ +#define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg) +#define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg) + +/* Prologue descriptors. */ +#define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg) +#define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg) +#define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg) +#define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg) +#define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg) +#define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg) +#define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg) +#define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg) +#define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg) +#define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg) +#define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg) +#define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg) +#define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg) +#define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) \ + desc_reg_when(IA64_REG_PRI_UNAT_GR,t,arg) +#define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) \ + desc_reg_when(IA64_REG_PRI_UNAT_MEM,t,arg) +#define UNW_DEC_PRIUNAT_GR(fmt,r,arg) \ + desc_reg_gr(IA64_REG_PRI_UNAT_GR,r,arg) +#define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) \ + desc_reg_psprel(IA64_REG_PRI_UNAT_MEM,o,arg) +#define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) \ + desc_reg_sprel(IA64_REG_PRI_UNAT_MEM,o,arg) +#define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg) +#define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg) +#define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg)) + +/* Body descriptors. */ +#define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg) +#define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg) +#define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg) + +/* General unwind descriptors. */ +#define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg) +#define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg) +#define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) \ + desc_spill_psprel_p(p,t,a,o,arg) +#define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) \ + desc_spill_psprel_p(0,t,a,o,arg) +#define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg) +#define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg) +#define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg) +#define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg) + +#include "unwind_decoder.h" + +#ifdef _U_dyn_op + +/* parse dynamic unwind info */ + +static struct ia64_reg_info * +lookup_preg (int regnum, int memory, struct ia64_state_record *sr) +{ + int preg; + + switch (regnum) + { + case UNW_IA64_AR_BSP: preg = IA64_REG_BSP; break; + case UNW_IA64_AR_BSPSTORE: preg = IA64_REG_BSPSTORE; break; + case UNW_IA64_AR_FPSR: preg = IA64_REG_FPSR; break; + case UNW_IA64_AR_LC: preg = IA64_REG_LC; break; + case UNW_IA64_AR_PFS: preg = IA64_REG_PFS; break; + case UNW_IA64_AR_RNAT: preg = IA64_REG_RNAT; break; + case UNW_IA64_AR_UNAT: preg = IA64_REG_UNAT; break; + case UNW_IA64_BR + 0: preg = IA64_REG_IP; break; + case UNW_IA64_PR: preg = IA64_REG_PR; break; + case UNW_IA64_SP: preg = IA64_REG_PSP; break; + + case UNW_IA64_NAT: + if (memory) + preg = IA64_REG_PRI_UNAT_MEM; + else + preg = IA64_REG_PRI_UNAT_GR; + break; + + case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: + preg = IA64_REG_R4 + (regnum - (UNW_IA64_GR + 4)); + break; + + case UNW_IA64_BR + 1 ... UNW_IA64_BR + 5: + preg = IA64_REG_B1 + (regnum - UNW_IA64_BR); + break; + + case UNW_IA64_FR + 2 ... UNW_IA64_FR + 5: + preg = IA64_REG_F2 + (regnum - (UNW_IA64_FR + 2)); + break; + + case UNW_IA64_FR + 16 ... UNW_IA64_FR + 31: + preg = IA64_REG_F16 + (regnum - (UNW_IA64_FR + 16)); + break; + + default: + Dprintf ("%s: invalid register number %d\n", __FUNCTION__, regnum); + return NULL; + } + return sr->curr.reg + preg; +} + +/* An alias directive inside a region of length RLEN is interpreted to + mean that the region behaves exactly like the first RLEN + instructions at the aliased IP. RLEN=0 implies that the current + state matches exactly that of before the instruction at the aliased + IP is executed. */ + +static int +desc_alias (unw_dyn_op_t *op, struct cursor *c, struct ia64_state_record *sr) +{ + struct ia64_state_record orig_sr = *sr; + int i, ret, when, rlen = sr->region_len; + unw_word_t new_ip; + + when = MIN (sr->when_target, rlen); + new_ip = op->val + ((when / 3) * 16 + (when % 3)); + + if ((ret = ia64_fetch_proc_info (c, new_ip, 1)) < 0) + return ret; + + if ((ret = create_state_record_for (c, sr, new_ip)) < 0) + return ret; + + sr->first_region = orig_sr.first_region; + sr->done = 0; + sr->any_spills |= orig_sr.any_spills; + sr->in_body = orig_sr.in_body; + sr->region_start = orig_sr.region_start; + sr->region_len = orig_sr.region_len; + if (sr->when_sp_restored != IA64_WHEN_NEVER) + sr->when_sp_restored = op->when + MIN (orig_sr.when_sp_restored, rlen); + sr->epilogue_count = orig_sr.epilogue_count; + sr->when_target = orig_sr.when_target; + + for (i = 0; i < IA64_NUM_PREGS; ++i) + if (sr->curr.reg[i].when != IA64_WHEN_NEVER) + sr->curr.reg[i].when = op->when + MIN (sr->curr.reg[i].when, rlen); + + ia64_free_state_record (sr); + sr->labeled_states = orig_sr.labeled_states; + sr->curr.next = orig_sr.curr.next; + return 0; +} + +static inline int +parse_dynamic (struct cursor *c, struct ia64_state_record *sr) +{ + unw_dyn_info_t *di = c->pi.unwind_info; + unw_dyn_proc_info_t *proc = &di->u.pi; + unw_dyn_region_info_t *r; + struct ia64_reg_info *ri; + enum ia64_where where; + int32_t when, len; + unw_dyn_op_t *op; + unw_word_t val; + int memory, ret; + int8_t qp; + + for (r = proc->regions; r; r = r->next) + { + len = r->insn_count; + if (len < 0) + { + if (r->next) + { + Debug (1, "negative region length allowed in last region only!"); + return -UNW_EINVAL; + } + len = -len; + /* hack old region info to set the start where we need it: */ + sr->region_start = (di->end_ip - di->start_ip) / 0x10 * 3 - len; + sr->region_len = 0; + } + /* all regions are treated as prologue regions: */ + desc_prologue (0, len, 0, 0, sr); + + if (sr->done) + return 0; + + for (op = r->op; op < r->op + r->op_count; ++op) + { + when = op->when; + val = op->val; + qp = op->qp; + + if (!desc_is_active (qp, when, sr)) + continue; + + when = sr->region_start + MIN ((int) when, sr->region_len - 1); + + switch (op->tag) + { + case UNW_DYN_SAVE_REG: + memory = 0; + if ((unsigned) (val - UNW_IA64_GR) < 128) + where = IA64_WHERE_GR; + else if ((unsigned) (val - UNW_IA64_FR) < 128) + where = IA64_WHERE_FR; + else if ((unsigned) (val - UNW_IA64_BR) < 8) + where = IA64_WHERE_BR; + else + { + Dprintf ("%s: can't save to register number %d\n", + __FUNCTION__, (int) op->reg); + return -UNW_EBADREG; + } + /* fall through */ + update_reg_info: + ri = lookup_preg (op->reg, memory, sr); + if (!ri) + return -UNW_EBADREG; + ri->where = where; + ri->when = when; + ri->val = val; + break; + + case UNW_DYN_SPILL_FP_REL: + memory = 1; + where = IA64_WHERE_PSPREL; + val = 0x10 - val; + goto update_reg_info; + + case UNW_DYN_SPILL_SP_REL: + memory = 1; + where = IA64_WHERE_SPREL; + goto update_reg_info; + + case UNW_DYN_ADD: + if (op->reg == UNW_IA64_SP) + { + if (val & 0xf) + { + Dprintf ("%s: frame-size %ld not an integer " + "multiple of 16\n", + __FUNCTION__, (long) op->val); + return -UNW_EINVAL; + } + desc_mem_stack_f (when, -((int64_t) val / 16), sr); + } + else + { + Dprintf ("%s: can only ADD to stack-pointer\n", + __FUNCTION__); + return -UNW_EBADREG; + } + break; + + case UNW_DYN_POP_FRAMES: + sr->when_sp_restored = when; + sr->epilogue_count = op->val; + break; + + case UNW_DYN_LABEL_STATE: + desc_label_state (op->val, sr); + break; + + case UNW_DYN_COPY_STATE: + desc_copy_state (op->val, sr); + break; + + case UNW_DYN_ALIAS: + if ((ret = desc_alias (op, c, sr)) < 0) + return ret; + + case UNW_DYN_STOP: + goto end_of_ops; + } + } + end_of_ops: + ; + } + return 0; +} +#else +# define parse_dynamic(c,sr) (-UNW_EINVAL) +#endif /* _U_dyn_op */ + + +HIDDEN int +ia64_fetch_proc_info (struct cursor *c, unw_word_t ip, int need_unwind_info) +{ + int ret, dynamic = 1; + + if (c->pi_valid && !need_unwind_info) + return 0; + + /* check dynamic info first --- it overrides everything else */ + ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, need_unwind_info, + c->as_arg); + if (ret == -UNW_ENOINFO) + { + dynamic = 0; + ret = ia64_find_proc_info (c, ip, need_unwind_info); + } + + c->pi_valid = 1; + c->pi_is_dynamic = dynamic; + return ret; +} + +static inline void +put_unwind_info (struct cursor *c, unw_proc_info_t *pi) +{ + if (!c->pi_valid) + return; + + if (c->pi_is_dynamic) + unwi_put_dynamic_unwind_info (c->as, pi, c->as_arg); + else + ia64_put_unwind_info (c, pi); +} + +static int +create_state_record_for (struct cursor *c, struct ia64_state_record *sr, + unw_word_t ip) +{ + unw_word_t predicates = c->pr; + struct ia64_reg_info *r; + uint8_t *dp, *desc_end; + int ret; + + assert (c->pi_valid); + + /* build state record */ + memset (sr, 0, sizeof (*sr)); + for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r) + r->when = IA64_WHEN_NEVER; + sr->pr_val = predicates; + sr->first_region = 1; + + if (!c->pi.unwind_info) + { + /* No info, return default unwinder (leaf proc, no mem stack, no + saved regs), rp in b0, pfs in ar.pfs. */ + Debug (1, "no unwind info for ip=0x%lx (gp=%lx)\n", + (long) ip, (long) c->pi.gp); + sr->curr.reg[IA64_REG_IP].where = IA64_WHERE_BR; + sr->curr.reg[IA64_REG_IP].when = -1; + sr->curr.reg[IA64_REG_IP].val = 0; + goto out; + } + + sr->when_target = (3 * ((ip & ~(unw_word_t) 0xf) - c->pi.start_ip) / 16 + + (ip & 0xf)); + + switch (c->pi.format) + { + case UNW_INFO_FORMAT_TABLE: + case UNW_INFO_FORMAT_REMOTE_TABLE: + dp = c->pi.unwind_info; + desc_end = dp + c->pi.unwind_info_size; + while (!sr->done && dp < desc_end) + dp = unw_decode (dp, sr->in_body, sr); + ret = 0; + break; + + case UNW_INFO_FORMAT_DYNAMIC: + ret = parse_dynamic (c, sr); + break; + + default: + ret = -UNW_EINVAL; + } + + put_unwind_info (c, &c->pi); + + if (ret < 0) + return ret; + + if (sr->when_target > sr->when_sp_restored) + { + /* sp has been restored and all values on the memory stack below + psp also have been restored. */ + sr->curr.reg[IA64_REG_PSP].val = 0; + sr->curr.reg[IA64_REG_PSP].where = IA64_WHERE_NONE; + sr->curr.reg[IA64_REG_PSP].when = IA64_WHEN_NEVER; + for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r) + if ((r->where == IA64_WHERE_PSPREL && r->val <= 0x10) + || r->where == IA64_WHERE_SPREL) + { + r->val = 0; + r->where = IA64_WHERE_NONE; + r->when = IA64_WHEN_NEVER; + } + } + + /* If RP did't get saved, generate entry for the return link + register. */ + if (sr->curr.reg[IA64_REG_IP].when >= sr->when_target) + { + sr->curr.reg[IA64_REG_IP].where = IA64_WHERE_BR; + sr->curr.reg[IA64_REG_IP].when = -1; + sr->curr.reg[IA64_REG_IP].val = sr->return_link_reg; + } + + if (sr->when_target > sr->curr.reg[IA64_REG_BSP].when + && sr->when_target > sr->curr.reg[IA64_REG_BSPSTORE].when + && sr->when_target > sr->curr.reg[IA64_REG_RNAT].when) + { + Debug (8, "func 0x%lx may switch the register-backing-store\n", + c->pi.start_ip); + c->pi.flags |= UNW_PI_FLAG_IA64_RBS_SWITCH; + } + out: +#if UNW_DEBUG + if (unwi_debug_level > 2) + { + Dprintf ("%s: state record for func 0x%lx, t=%u (flags=0x%lx):\n", + __FUNCTION__, + (long) c->pi.start_ip, sr->when_target, (long) c->pi.flags); + for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r) + { + if (r->where != IA64_WHERE_NONE || r->when != IA64_WHEN_NEVER) + { + Dprintf (" %s <- ", unw.preg_name[r - sr->curr.reg]); + switch (r->where) + { + case IA64_WHERE_GR: + Dprintf ("r%lu", (long) r->val); + break; + case IA64_WHERE_FR: + Dprintf ("f%lu", (long) r->val); + break; + case IA64_WHERE_BR: + Dprintf ("b%lu", (long) r->val); + break; + case IA64_WHERE_SPREL: + Dprintf ("[sp+0x%lx]", (long) r->val); + break; + case IA64_WHERE_PSPREL: + Dprintf ("[psp+0x%lx]", (long) r->val); + break; + case IA64_WHERE_NONE: + Dprintf ("%s+0x%lx", + unw.preg_name[r - sr->curr.reg], (long) r->val); + break; + default: + Dprintf ("BADWHERE(%d)", r->where); + break; + } + Dprintf ("\t\t%d\n", r->when); + } + } + } +#endif + return 0; +} + +/* The proc-info must be valid for IP before this routine can be + called. */ +HIDDEN int +ia64_create_state_record (struct cursor *c, struct ia64_state_record *sr) +{ + return create_state_record_for (c, sr, c->ip); +} + +HIDDEN int +ia64_free_state_record (struct ia64_state_record *sr) +{ + struct ia64_labeled_state *ls, *next; + + /* free labeled register states & stack: */ + + for (ls = sr->labeled_states; ls; ls = next) + { + next = ls->next; + free_state_stack (&ls->saved_state); + free_labeled_state (ls); + } + free_state_stack (&sr->curr); + + return 0; +} + +HIDDEN int +ia64_make_proc_info (struct cursor *c) +{ + int ret, caching = c->as->caching_policy != UNW_CACHE_NONE; + + if (!caching || ia64_get_cached_proc_info (c) < 0) + { + /* Lookup it up the slow way... */ + if ((ret = ia64_fetch_proc_info (c, c->ip, 0)) < 0) + return ret; + if (caching) + ia64_cache_proc_info (c); + } + return 0; +} diff --git a/src/libs/libunwind/ia64/Grbs.c b/src/libs/libunwind/ia64/Grbs.c new file mode 100644 index 0000000000..e7c01fe219 --- /dev/null +++ b/src/libs/libunwind/ia64/Grbs.c @@ -0,0 +1,319 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Logically, we like to think of the stack as a contiguous region of +memory. Unfortunately, this logical view doesn't work for the +register backing store, because the RSE is an asynchronous engine and +because UNIX/Linux allow for stack-switching via sigaltstack(2). +Specifically, this means that any given stacked register may or may +not be backed up by memory in the current stack. If not, then the +backing memory may be found in any of the "more inner" (younger) +stacks. The routines in this file help manage the discontiguous +nature of the register backing store. The routines are completely +independent of UNIX/Linux, but each stack frame that switches the +backing store is expected to reserve 4 words for use by libunwind. For +example, in the Linux sigcontext, sc_fr[0] and sc_fr[1] serve this +purpose. */ + +#include "unwind_i.h" + +#if UNW_DEBUG + +HIDDEN const char * +ia64_strloc (ia64_loc_t loc) +{ + static char buf[128]; + + if (IA64_IS_NULL_LOC (loc)) + return ""; + + buf[0] = '\0'; + + if (IA64_IS_MEMSTK_NAT (loc)) + strcat (buf, "memstk_nat("); + if (IA64_IS_UC_LOC (loc)) + strcat (buf, "uc("); + if (IA64_IS_FP_LOC (loc)) + strcat (buf, "fp("); + + if (IA64_IS_REG_LOC (loc)) + sprintf (buf + strlen (buf), "%s", unw_regname (IA64_GET_REG (loc))); + else + sprintf (buf + strlen (buf), "0x%llx", + (unsigned long long) IA64_GET_ADDR (loc)); + + if (IA64_IS_FP_LOC (loc)) + strcat (buf, ")"); + if (IA64_IS_UC_LOC (loc)) + strcat (buf, ")"); + if (IA64_IS_MEMSTK_NAT (loc)) + strcat (buf, ")"); + + return buf; +} + +#endif /* UNW_DEBUG */ + +HIDDEN int +rbs_switch (struct cursor *c, + unw_word_t saved_bsp, unw_word_t saved_bspstore, + ia64_loc_t saved_rnat_loc) +{ + struct rbs_area *rbs = &c->rbs_area[c->rbs_curr]; + unw_word_t lo, ndirty, rbs_base; + int ret; + + Debug (10, "(left=%u, curr=%u)\n", c->rbs_left_edge, c->rbs_curr); + + /* Calculate address "lo" at which the backing store starts: */ + ndirty = rse_num_regs (saved_bspstore, saved_bsp); + lo = rse_skip_regs (c->bsp, -ndirty); + + rbs->size = (rbs->end - lo); + + /* If the previously-recorded rbs-area is empty we don't need to + track it and we can simply overwrite it... */ + if (rbs->size) + { + Debug (10, "inner=[0x%lx-0x%lx)\n", + (long) (rbs->end - rbs->size), (long) rbs->end); + + c->rbs_curr = (c->rbs_curr + 1) % ARRAY_SIZE (c->rbs_area); + rbs = c->rbs_area + c->rbs_curr; + + if (c->rbs_curr == c->rbs_left_edge) + c->rbs_left_edge = (c->rbs_left_edge + 1) % ARRAY_SIZE (c->rbs_area); + } + + if ((ret = rbs_get_base (c, saved_bspstore, &rbs_base)) < 0) + return ret; + + rbs->end = saved_bspstore; + rbs->size = saved_bspstore - rbs_base; + rbs->rnat_loc = saved_rnat_loc; + + c->bsp = saved_bsp; + + Debug (10, "outer=[0x%llx-0x%llx), rnat@%s\n", (long long) rbs_base, + (long long) rbs->end, ia64_strloc (rbs->rnat_loc)); + return 0; +} + +HIDDEN int +rbs_find_stacked (struct cursor *c, unw_word_t regs_to_skip, + ia64_loc_t *locp, ia64_loc_t *rnat_locp) +{ + unw_word_t nregs, bsp = c->bsp, curr = c->rbs_curr, n; + unw_word_t left_edge = c->rbs_left_edge; +#if UNW_DEBUG + int reg = 32 + regs_to_skip; +#endif + + while (!rbs_contains (&c->rbs_area[curr], bsp)) + { + if (curr == left_edge) + { + Debug (1, "could not find register r%d!\n", reg); + return -UNW_EBADREG; + } + + n = rse_num_regs (c->rbs_area[curr].end, bsp); + curr = (curr + ARRAY_SIZE (c->rbs_area) - 1) % ARRAY_SIZE (c->rbs_area); + bsp = rse_skip_regs (c->rbs_area[curr].end - c->rbs_area[curr].size, n); + } + + while (1) + { + nregs = rse_num_regs (bsp, c->rbs_area[curr].end); + + if (regs_to_skip < nregs) + { + /* found it: */ + unw_word_t addr; + + addr = rse_skip_regs (bsp, regs_to_skip); + if (locp) + *locp = rbs_loc (c->rbs_area + curr, addr); + if (rnat_locp) + *rnat_locp = rbs_get_rnat_loc (c->rbs_area + curr, addr); + return 0; + } + + if (curr == left_edge) + { + Debug (1, "could not find register r%d!\n", reg); + return -UNW_EBADREG; + } + + regs_to_skip -= nregs; + + curr = (curr + ARRAY_SIZE (c->rbs_area) - 1) % ARRAY_SIZE (c->rbs_area); + bsp = c->rbs_area[curr].end - c->rbs_area[curr].size; + } +} + +#ifdef NEED_RBS_COVER_AND_FLUSH + +static inline int +get_rnat (struct cursor *c, struct rbs_area *rbs, unw_word_t bsp, + unw_word_t *__restrict rnatp) +{ + ia64_loc_t rnat_locp = rbs_get_rnat_loc (rbs, bsp); + + return ia64_get (c, rnat_locp, rnatp); +} + +/* Simulate the effect of "cover" followed by a "flushrs" for the + target-frame. However, since the target-frame's backing store + may not have space for the registers that got spilled onto other + rbs-areas, we save those registers to DIRTY_PARTITION where + we can then load them via a single "loadrs". + + This function returns the size of the dirty-partition that was + created or a negative error-code in case of error. + + Note: This does not modify the rbs_area[] structure in any way. */ +HIDDEN int +rbs_cover_and_flush (struct cursor *c, unw_word_t nregs, + unw_word_t *dirty_partition, unw_word_t *dirty_rnat, + unw_word_t *bspstore) +{ + unw_word_t n, src_mask, dst_mask, bsp, *dst, src_rnat, dst_rnat = 0; + unw_word_t curr = c->rbs_curr, left_edge = c->rbs_left_edge; + struct rbs_area *rbs = c->rbs_area + curr; + int ret; + + bsp = c->bsp; + c->bsp = rse_skip_regs (bsp, nregs); + + if (likely (rbs_contains (rbs, bsp))) + { + /* at least _some_ registers are on rbs... */ + n = rse_num_regs (bsp, rbs->end); + if (likely (n >= nregs)) + { + /* common case #1: all registers are on current rbs... */ + /* got lucky: _all_ registers are on rbs... */ + ia64_loc_t rnat_loc = rbs_get_rnat_loc (rbs, c->bsp); + + *bspstore = c->bsp; + + if (IA64_IS_REG_LOC (rnat_loc)) + { + unw_word_t rnat_addr = (unw_word_t) + tdep_uc_addr (c->as_arg, UNW_IA64_AR_RNAT, NULL); + rnat_loc = IA64_LOC_ADDR (rnat_addr, 0); + } + c->loc[IA64_REG_RNAT] = rnat_loc; + return 0; /* all done */ + } + nregs -= n; /* account for registers already on the rbs */ + + assert (rse_skip_regs (c->bsp, -nregs) == rse_skip_regs (rbs->end, 0)); + } + else + /* Earlier frames also didn't get spilled; need to "loadrs" those, + too... */ + nregs += rse_num_regs (rbs->end, bsp); + + /* OK, we need to copy NREGS registers to the dirty partition. */ + + *bspstore = bsp = rbs->end; + c->loc[IA64_REG_RNAT] = rbs->rnat_loc; + assert (!IA64_IS_REG_LOC (rbs->rnat_loc)); + + dst = dirty_partition; + + while (nregs > 0) + { + if (unlikely (!rbs_contains (rbs, bsp))) + { + /* switch to next non-empty rbs-area: */ + do + { + if (curr == left_edge) + { + Debug (0, "rbs-underflow while flushing %lu regs, " + "bsp=0x%lx, dst=0x%p\n", (unsigned long) nregs, + (unsigned long) bsp, dst); + return -UNW_EBADREG; + } + + assert (rse_num_regs (rbs->end, bsp) == 0); + + curr = (curr + ARRAY_SIZE (c->rbs_area) - 1) + % ARRAY_SIZE (c->rbs_area); + rbs = c->rbs_area + curr; + bsp = rbs->end - rbs->size; + } + while (rbs->size == 0); + + if ((ret = get_rnat (c, rbs, bsp, &src_rnat)) < 0) + return ret; + } + + if (unlikely (rse_is_rnat_slot (bsp))) + { + bsp += 8; + if ((ret = get_rnat (c, rbs, bsp, &src_rnat)) < 0) + return ret; + } + if (unlikely (rse_is_rnat_slot ((unw_word_t) dst))) + { + *dst++ = dst_rnat; + dst_rnat = 0; + } + + src_mask = ((unw_word_t) 1) << rse_slot_num (bsp); + dst_mask = ((unw_word_t) 1) << rse_slot_num ((unw_word_t) dst); + + if (src_rnat & src_mask) + dst_rnat |= dst_mask; + else + dst_rnat &= ~dst_mask; + + /* copy one slot: */ + if ((ret = ia64_get (c, rbs_loc (rbs, bsp), dst)) < 0) + return ret; + + /* advance to next slot: */ + --nregs; + bsp += 8; + ++dst; + } + if (unlikely (rse_is_rnat_slot ((unw_word_t) dst))) + { + /* The LOADRS instruction loads "the N bytes below the current + BSP" but BSP can never point to an RNaT slot so if the last + destination word happens to be an RNaT slot, we need to write + that slot now. */ + *dst++ = dst_rnat; + dst_rnat = 0; + } + *dirty_rnat = dst_rnat; + return (char *) dst - (char *) dirty_partition; +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/ia64/Gregs.c b/src/libs/libunwind/ia64/Gregs.c new file mode 100644 index 0000000000..ac6f738a6c --- /dev/null +++ b/src/libs/libunwind/ia64/Gregs.c @@ -0,0 +1,612 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" +#include "regs.h" +#include "unwind_i.h" + +static inline ia64_loc_t +linux_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr) +{ +#if !defined(UNW_LOCAL_ONLY) || defined(__linux) + unw_word_t addr = c->sigcontext_addr, flags, tmp_addr; + int i; + + if (ia64_get_abi_marker (c) == ABI_MARKER_LINUX_SIGTRAMP + || ia64_get_abi_marker (c) == ABI_MARKER_OLD_LINUX_SIGTRAMP) + { + switch (reg) + { + case UNW_IA64_NAT + 2 ... UNW_IA64_NAT + 3: + case UNW_IA64_NAT + 8 ... UNW_IA64_NAT + 31: + /* Linux sigcontext contains the NaT bit of scratch register + N in bit position N of the sc_nat member. */ + *nat_bitnr = (reg - UNW_IA64_NAT); + addr += LINUX_SC_NAT_OFF; + break; + + case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3: + case UNW_IA64_GR + 8 ... UNW_IA64_GR + 31: + addr += LINUX_SC_GR_OFF + 8 * (reg - UNW_IA64_GR); + break; + + case UNW_IA64_FR + 6 ... UNW_IA64_FR + 15: + addr += LINUX_SC_FR_OFF + 16 * (reg - UNW_IA64_FR); + return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); + + case UNW_IA64_FR + 32 ... UNW_IA64_FR + 127: + if (ia64_get (c, IA64_LOC_ADDR (addr + LINUX_SC_FLAGS_OFF, 0), + &flags) < 0) + return IA64_NULL_LOC; + + if (!(flags & IA64_SC_FLAG_FPH_VALID)) + { + /* initialize fph partition: */ + tmp_addr = addr + LINUX_SC_FR_OFF + 32*16; + for (i = 32; i < 128; ++i, tmp_addr += 16) + if (ia64_putfp (c, IA64_LOC_ADDR (tmp_addr, 0), + unw.read_only.f0) < 0) + return IA64_NULL_LOC; + /* mark fph partition as valid: */ + if (ia64_put (c, IA64_LOC_ADDR (addr + LINUX_SC_FLAGS_OFF, 0), + flags | IA64_SC_FLAG_FPH_VALID) < 0) + return IA64_NULL_LOC; + } + + addr += LINUX_SC_FR_OFF + 16 * (reg - UNW_IA64_FR); + return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); + + case UNW_IA64_BR + 0: addr += LINUX_SC_BR_OFF + 0; break; + case UNW_IA64_BR + 6: addr += LINUX_SC_BR_OFF + 6*8; break; + case UNW_IA64_BR + 7: addr += LINUX_SC_BR_OFF + 7*8; break; + case UNW_IA64_AR_RSC: addr += LINUX_SC_AR_RSC_OFF; break; + case UNW_IA64_AR_CSD: addr += LINUX_SC_AR_CSD_OFF; break; + case UNW_IA64_AR_SSD: addr += LINUX_SC_AR_SSD_OFF; break; + case UNW_IA64_AR_CCV: addr += LINUX_SC_AR_CCV; break; + + default: + if (unw_is_fpreg (reg)) + return IA64_FPREG_LOC (c, reg); + else + return IA64_REG_LOC (c, reg); + } + return IA64_LOC_ADDR (addr, 0); + } + else + { + int is_nat = 0; + + if ((unsigned) (reg - UNW_IA64_NAT) < 128) + { + is_nat = 1; + reg -= (UNW_IA64_NAT - UNW_IA64_GR); + } + if (ia64_get_abi_marker (c) == ABI_MARKER_LINUX_INTERRUPT) + { + switch (reg) + { + case UNW_IA64_BR + 6 ... UNW_IA64_BR + 7: + addr += LINUX_PT_B6_OFF + 8 * (reg - (UNW_IA64_BR + 6)); + break; + + case UNW_IA64_AR_CSD: addr += LINUX_PT_CSD_OFF; break; + case UNW_IA64_AR_SSD: addr += LINUX_PT_SSD_OFF; break; + + case UNW_IA64_GR + 8 ... UNW_IA64_GR + 11: + addr += LINUX_PT_R8_OFF + 8 * (reg - (UNW_IA64_GR + 8)); + break; + + case UNW_IA64_IP: addr += LINUX_PT_IIP_OFF; break; + case UNW_IA64_CFM: addr += LINUX_PT_IFS_OFF; break; + case UNW_IA64_AR_UNAT: addr += LINUX_PT_UNAT_OFF; break; + case UNW_IA64_AR_PFS: addr += LINUX_PT_PFS_OFF; break; + case UNW_IA64_AR_RSC: addr += LINUX_PT_RSC_OFF; break; + case UNW_IA64_AR_RNAT: addr += LINUX_PT_RNAT_OFF; break; + case UNW_IA64_AR_BSPSTORE: addr += LINUX_PT_BSPSTORE_OFF; break; + case UNW_IA64_PR: addr += LINUX_PT_PR_OFF; break; + case UNW_IA64_BR + 0: addr += LINUX_PT_B0_OFF; break; + + case UNW_IA64_GR + 1: + /* The saved r1 value is valid only in the frame in which + it was saved; for everything else we need to look up + the appropriate gp value. */ + if (c->sigcontext_addr != c->sp + 0x10) + return IA64_NULL_LOC; + addr += LINUX_PT_R1_OFF; + break; + + case UNW_IA64_GR + 12: addr += LINUX_PT_R12_OFF; break; + case UNW_IA64_GR + 13: addr += LINUX_PT_R13_OFF; break; + case UNW_IA64_AR_FPSR: addr += LINUX_PT_FPSR_OFF; break; + case UNW_IA64_GR + 15: addr += LINUX_PT_R15_OFF; break; + case UNW_IA64_GR + 14: addr += LINUX_PT_R14_OFF; break; + case UNW_IA64_GR + 2: addr += LINUX_PT_R2_OFF; break; + case UNW_IA64_GR + 3: addr += LINUX_PT_R3_OFF; break; + + case UNW_IA64_GR + 16 ... UNW_IA64_GR + 31: + addr += LINUX_PT_R16_OFF + 8 * (reg - (UNW_IA64_GR + 16)); + break; + + case UNW_IA64_AR_CCV: addr += LINUX_PT_CCV_OFF; break; + + case UNW_IA64_FR + 6 ... UNW_IA64_FR + 11: + addr += LINUX_PT_F6_OFF + 16 * (reg - (UNW_IA64_FR + 6)); + return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); + + default: + if (unw_is_fpreg (reg)) + return IA64_FPREG_LOC (c, reg); + else + return IA64_REG_LOC (c, reg); + } + } + else if (ia64_get_abi_marker (c) == ABI_MARKER_OLD_LINUX_INTERRUPT) + { + switch (reg) + { + case UNW_IA64_GR + 1: + /* The saved r1 value is valid only in the frame in which + it was saved; for everything else we need to look up + the appropriate gp value. */ + if (c->sigcontext_addr != c->sp + 0x10) + return IA64_NULL_LOC; + addr += LINUX_OLD_PT_R1_OFF; + break; + + case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3: + addr += LINUX_OLD_PT_R2_OFF + 8 * (reg - (UNW_IA64_GR + 2)); + break; + + case UNW_IA64_GR + 8 ... UNW_IA64_GR + 11: + addr += LINUX_OLD_PT_R8_OFF + 8 * (reg - (UNW_IA64_GR + 8)); + break; + + case UNW_IA64_GR + 16 ... UNW_IA64_GR + 31: + addr += LINUX_OLD_PT_R16_OFF + 8 * (reg - (UNW_IA64_GR + 16)); + break; + + case UNW_IA64_FR + 6 ... UNW_IA64_FR + 9: + addr += LINUX_OLD_PT_F6_OFF + 16 * (reg - (UNW_IA64_FR + 6)); + return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); + + case UNW_IA64_BR + 0: addr += LINUX_OLD_PT_B0_OFF; break; + case UNW_IA64_BR + 6: addr += LINUX_OLD_PT_B6_OFF; break; + case UNW_IA64_BR + 7: addr += LINUX_OLD_PT_B7_OFF; break; + + case UNW_IA64_AR_RSC: addr += LINUX_OLD_PT_RSC_OFF; break; + case UNW_IA64_AR_CCV: addr += LINUX_OLD_PT_CCV_OFF; break; + + default: + if (unw_is_fpreg (reg)) + return IA64_FPREG_LOC (c, reg); + else + return IA64_REG_LOC (c, reg); + } + } + if (is_nat) + { + /* For Linux pt-regs structure, bit number is determined by + the UNaT slot number (as determined by st8.spill) and the + bits are saved wherever the (primary) UNaT was saved. */ + *nat_bitnr = ia64_unat_slot_num (addr); + return c->loc[IA64_REG_PRI_UNAT_MEM]; + } + return IA64_LOC_ADDR (addr, 0); + } +#endif + return IA64_NULL_LOC; +} + +static inline ia64_loc_t +hpux_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr) +{ +#if !defined(UNW_LOCAL_ONLY) || defined(__hpux) + return IA64_LOC_UC_REG (reg, c->sigcontext_addr); +#else + return IA64_NULL_LOC; +#endif +} + +HIDDEN ia64_loc_t +ia64_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr) +{ + if (c->sigcontext_addr) + { + if (ia64_get_abi (c) == ABI_LINUX) + return linux_scratch_loc (c, reg, nat_bitnr); + else if (ia64_get_abi (c) == ABI_HPUX) + return hpux_scratch_loc (c, reg, nat_bitnr); + else + return IA64_NULL_LOC; + } + else + return IA64_REG_LOC (c, reg); +} + +static inline int +update_nat (struct cursor *c, ia64_loc_t nat_loc, unw_word_t mask, + unw_word_t *valp, int write) +{ + unw_word_t nat_word; + int ret; + + ret = ia64_get (c, nat_loc, &nat_word); + if (ret < 0) + return ret; + + if (write) + { + if (*valp) + nat_word |= mask; + else + nat_word &= ~mask; + ret = ia64_put (c, nat_loc, nat_word); + } + else + *valp = (nat_word & mask) != 0; + return ret; +} + +static int +access_nat (struct cursor *c, + ia64_loc_t nat_loc, ia64_loc_t reg_loc, uint8_t nat_bitnr, + unw_word_t *valp, int write) +{ + unw_word_t mask = 0; + unw_fpreg_t tmp; + int ret; + + if (IA64_IS_FP_LOC (reg_loc)) + { + /* NaT bit is saved as a NaTVal. This happens when a general + register is saved to a floating-point register. */ + if (write) + { + if (*valp) + { + if (ia64_is_big_endian (c)) + ret = ia64_putfp (c, reg_loc, unw.nat_val_be); + else + ret = ia64_putfp (c, reg_loc, unw.nat_val_le); + } + else + { + unw_word_t *src, *dst; + unw_fpreg_t tmp; + + ret = ia64_getfp (c, reg_loc, &tmp); + if (ret < 0) + return ret; + + /* Reset the exponent to 0x1003e so that the significand + will be interpreted as an integer value. */ + src = (unw_word_t *) &unw.int_val_be; + dst = (unw_word_t *) &tmp; + if (!ia64_is_big_endian (c)) + ++src, ++dst; + *dst = *src; + + ret = ia64_putfp (c, reg_loc, tmp); + } + } + else + { + ret = ia64_getfp (c, reg_loc, &tmp); + if (ret < 0) + return ret; + + if (ia64_is_big_endian (c)) + *valp = (memcmp (&tmp, &unw.nat_val_be, sizeof (tmp)) == 0); + else + *valp = (memcmp (&tmp, &unw.nat_val_le, sizeof (tmp)) == 0); + } + return ret; + } + + if ((IA64_IS_REG_LOC (nat_loc) + && (unsigned) (IA64_GET_REG (nat_loc) - UNW_IA64_NAT) < 128) + || IA64_IS_UC_LOC (reg_loc)) + { + if (write) + return ia64_put (c, nat_loc, *valp); + else + return ia64_get (c, nat_loc, valp); + } + + if (IA64_IS_NULL_LOC (nat_loc)) + { + /* NaT bit is not saved. This happens if a general register is + saved to a branch register. Since the NaT bit gets lost, we + need to drop it here, too. Note that if the NaT bit had been + set when the save occurred, it would have caused a NaT + consumption fault. */ + if (write) + { + if (*valp) + return -UNW_EBADREG; /* can't set NaT bit */ + } + else + *valp = 0; + return 0; + } + + mask = (unw_word_t) 1 << nat_bitnr; + return update_nat (c, nat_loc, mask, valp, write); +} + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + ia64_loc_t loc, reg_loc, nat_loc; + unw_word_t mask, val; + uint8_t nat_bitnr; + int ret; + + switch (reg) + { + /* frame registers: */ + + case UNW_IA64_BSP: + if (write) + c->bsp = *valp; + else + *valp = c->bsp; + return 0; + + case UNW_REG_SP: + if (write) + c->sp = *valp; + else + *valp = c->sp; + return 0; + + case UNW_REG_IP: + if (write) + { + c->ip = *valp; /* also update the IP cache */ + if (c->pi_valid && (*valp < c->pi.start_ip || *valp >= c->pi.end_ip)) + c->pi_valid = 0; /* new IP outside of current proc */ + } + loc = c->loc[IA64_REG_IP]; + break; + + /* preserved registers: */ + + case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: + loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_GR + 4))]; + break; + + case UNW_IA64_NAT + 4 ... UNW_IA64_NAT + 7: + loc = c->loc[IA64_REG_NAT4 + (reg - (UNW_IA64_NAT + 4))]; + reg_loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_NAT + 4))]; + nat_bitnr = c->nat_bitnr[reg - (UNW_IA64_NAT + 4)]; + return access_nat (c, loc, reg_loc, nat_bitnr, valp, write); + + case UNW_IA64_AR_BSP: loc = c->loc[IA64_REG_BSP]; break; + case UNW_IA64_AR_BSPSTORE: loc = c->loc[IA64_REG_BSPSTORE]; break; + case UNW_IA64_AR_PFS: loc = c->loc[IA64_REG_PFS]; break; + case UNW_IA64_AR_RNAT: loc = c->loc[IA64_REG_RNAT]; break; + case UNW_IA64_AR_UNAT: loc = c->loc[IA64_REG_UNAT]; break; + case UNW_IA64_AR_LC: loc = c->loc[IA64_REG_LC]; break; + case UNW_IA64_AR_FPSR: loc = c->loc[IA64_REG_FPSR]; break; + case UNW_IA64_BR + 1: loc = c->loc[IA64_REG_B1]; break; + case UNW_IA64_BR + 2: loc = c->loc[IA64_REG_B2]; break; + case UNW_IA64_BR + 3: loc = c->loc[IA64_REG_B3]; break; + case UNW_IA64_BR + 4: loc = c->loc[IA64_REG_B4]; break; + case UNW_IA64_BR + 5: loc = c->loc[IA64_REG_B5]; break; + + case UNW_IA64_CFM: + if (write) + c->cfm = *valp; /* also update the CFM cache */ + loc = c->cfm_loc; + break; + + case UNW_IA64_PR: + /* + * Note: broad-side access to the predicates is NOT rotated + * (i.e., it is done as if CFM.rrb.pr == 0. + */ + if (write) + { + c->pr = *valp; /* update the predicate cache */ + return ia64_put (c, c->loc[IA64_REG_PR], *valp); + } + else + return ia64_get (c, c->loc[IA64_REG_PR], valp); + + case UNW_IA64_GR + 32 ... UNW_IA64_GR + 127: /* stacked reg */ + reg = rotate_gr (c, reg - UNW_IA64_GR); + if (reg < 0) + return -UNW_EBADREG; + ret = ia64_get_stacked (c, reg, &loc, NULL); + if (ret < 0) + return ret; + break; + + case UNW_IA64_NAT + 32 ... UNW_IA64_NAT + 127: /* stacked reg */ + reg = rotate_gr (c, reg - UNW_IA64_NAT); + if (reg < 0) + return -UNW_EBADREG; + ret = ia64_get_stacked (c, reg, &loc, &nat_loc); + if (ret < 0) + return ret; + assert (!IA64_IS_REG_LOC (loc)); + mask = (unw_word_t) 1 << rse_slot_num (IA64_GET_ADDR (loc)); + return update_nat (c, nat_loc, mask, valp, write); + + case UNW_IA64_AR_EC: + if ((ret = ia64_get (c, c->ec_loc, &val)) < 0) + return ret; + + if (write) + { + val = ((val & ~((unw_word_t) 0x3f << 52)) | ((*valp & 0x3f) << 52)); + return ia64_put (c, c->ec_loc, val); + } + else + { + *valp = (val >> 52) & 0x3f; + return 0; + } + + /* scratch & special registers: */ + + case UNW_IA64_GR + 0: + if (write) + return -UNW_EREADONLYREG; + *valp = 0; + return 0; + + case UNW_IA64_NAT + 0: + if (write) + return -UNW_EREADONLYREG; + *valp = 0; + return 0; + + case UNW_IA64_NAT + 1: + case UNW_IA64_NAT + 2 ... UNW_IA64_NAT + 3: + case UNW_IA64_NAT + 8 ... UNW_IA64_NAT + 31: + loc = ia64_scratch_loc (c, reg, &nat_bitnr); + if (IA64_IS_NULL_LOC (loc) && reg == UNW_IA64_NAT + 1) + { + /* access to GP */ + if (write) + return -UNW_EREADONLYREG; + *valp = 0; + return 0; + } + if (!(IA64_IS_REG_LOC (loc) || IA64_IS_UC_LOC (loc) + || IA64_IS_FP_LOC (loc))) + /* We're dealing with a NaT bit stored in memory. */ + return update_nat(c, loc, (unw_word_t) 1 << nat_bitnr, valp, write); + break; + + case UNW_IA64_GR + 15 ... UNW_IA64_GR + 18: + mask = 1 << (reg - (UNW_IA64_GR + 15)); + if (write) + { + c->eh_args[reg - (UNW_IA64_GR + 15)] = *valp; + c->eh_valid_mask |= mask; + return 0; + } + else if ((c->eh_valid_mask & mask) != 0) + { + *valp = c->eh_args[reg - (UNW_IA64_GR + 15)]; + return 0; + } + else + loc = ia64_scratch_loc (c, reg, NULL); + break; + + case UNW_IA64_GR + 1: /* global pointer */ + case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3: + case UNW_IA64_GR + 8 ... UNW_IA64_GR + 14: + case UNW_IA64_GR + 19 ... UNW_IA64_GR + 31: + case UNW_IA64_BR + 0: + case UNW_IA64_BR + 6: + case UNW_IA64_BR + 7: + case UNW_IA64_AR_RSC: + case UNW_IA64_AR_CSD: + case UNW_IA64_AR_SSD: + case UNW_IA64_AR_CCV: + loc = ia64_scratch_loc (c, reg, NULL); + if (IA64_IS_NULL_LOC (loc) && reg == UNW_IA64_GR + 1) + { + /* access to GP */ + if (write) + return -UNW_EREADONLYREG; + + /* ensure c->pi is up-to-date: */ + if ((ret = ia64_make_proc_info (c)) < 0) + return ret; + *valp = c->pi.gp; + return 0; + } + break; + + default: + Debug (1, "bad register number %d\n", reg); + return -UNW_EBADREG; + } + + if (write) + return ia64_put (c, loc, *valp); + else + return ia64_get (c, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, int reg, unw_fpreg_t *valp, + int write) +{ + ia64_loc_t loc; + + switch (reg) + { + case UNW_IA64_FR + 0: + if (write) + return -UNW_EREADONLYREG; + *valp = unw.read_only.f0; + return 0; + + case UNW_IA64_FR + 1: + if (write) + return -UNW_EREADONLYREG; + + if (ia64_is_big_endian (c)) + *valp = unw.read_only.f1_be; + else + *valp = unw.read_only.f1_le; + return 0; + + case UNW_IA64_FR + 2: loc = c->loc[IA64_REG_F2]; break; + case UNW_IA64_FR + 3: loc = c->loc[IA64_REG_F3]; break; + case UNW_IA64_FR + 4: loc = c->loc[IA64_REG_F4]; break; + case UNW_IA64_FR + 5: loc = c->loc[IA64_REG_F5]; break; + + case UNW_IA64_FR + 16 ... UNW_IA64_FR + 31: + loc = c->loc[IA64_REG_F16 + (reg - (UNW_IA64_FR + 16))]; + break; + + case UNW_IA64_FR + 6 ... UNW_IA64_FR + 15: + loc = ia64_scratch_loc (c, reg, NULL); + break; + + case UNW_IA64_FR + 32 ... UNW_IA64_FR + 127: + reg = rotate_fr (c, reg - UNW_IA64_FR) + UNW_IA64_FR; + loc = ia64_scratch_loc (c, reg, NULL); + break; + + default: + Debug (1, "bad register number %d\n", reg); + return -UNW_EBADREG; + } + + if (write) + return ia64_putfp (c, loc, *valp); + else + return ia64_getfp (c, loc, valp); +} diff --git a/src/libs/libunwind/ia64/Gresume.c b/src/libs/libunwind/ia64/Gresume.c new file mode 100644 index 0000000000..aa395b69a3 --- /dev/null +++ b/src/libs/libunwind/ia64/Gresume.c @@ -0,0 +1,274 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" +#include "offsets.h" + +#ifndef UNW_REMOTE_ONLY + +static inline int +local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ +#if defined(__linux) + unw_word_t dirty_partition[2048]; /* AR.RSC.LOADRS is a 14-bit field */ + unw_word_t val, sol, sof, pri_unat, n, pfs, bspstore, dirty_rnat; + struct cursor *c = (struct cursor *) cursor; + struct + { + unw_word_t r1; + unw_word_t r4; + unw_word_t r5; + unw_word_t r6; + unw_word_t r7; + unw_word_t r15; + unw_word_t r16; + unw_word_t r17; + unw_word_t r18; + } + extra; + int ret, dirty_size; +# define GET_NAT(n) \ + do \ + { \ + ret = tdep_access_reg (c, UNW_IA64_NAT + (n), &val, 0); \ + if (ret < 0) \ + return ret; \ + if (val) \ + pri_unat |= (unw_word_t) 1 << n; \ + } \ + while (0) + + /* ensure c->pi is up-to-date: */ + if ((ret = ia64_make_proc_info (c)) < 0) + return ret; + + /* Copy contents of r4-r7 into "extra", so that their values end up + contiguous, so we can use a single (primary-) UNaT value. */ + if ((ret = ia64_get (c, c->loc[IA64_REG_R4], &extra.r4)) < 0 + || (ret = ia64_get (c, c->loc[IA64_REG_R5], &extra.r5)) < 0 + || (ret = ia64_get (c, c->loc[IA64_REG_R6], &extra.r6)) < 0 + || (ret = ia64_get (c, c->loc[IA64_REG_R7], &extra.r7)) < 0) + return ret; + + /* Form the primary UNaT value: */ + pri_unat = 0; + GET_NAT (4); GET_NAT(5); + GET_NAT (6); GET_NAT(7); + n = (((uintptr_t) &extra.r4) / 8 - 4) % 64; + pri_unat = (pri_unat << n) | (pri_unat >> (64 - n)); + + if (unlikely (c->sigcontext_addr)) + { + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; +# define PR_SCRATCH 0xffc0 /* p6-p15 are scratch */ +# define PR_PRESERVED (~(PR_SCRATCH | 1)) + + /* We're returning to a frame that was (either directly or + indirectly) interrupted by a signal. We have to restore + _both_ "preserved" and "scratch" registers. That doesn't + leave us any registers to work with, and the only way we can + achieve this is by doing a sigreturn(). + + Note: it might be tempting to think that we don't have to + restore the scratch registers when returning to a frame that + was indirectly interrupted by a signal. However, that is not + safe because that frame and its descendants could have been + using a special convention that stores "preserved" state in + scratch registers. For example, the Linux fsyscall + convention does this with r11 (to save ar.pfs) and b6 (to + save "rp"). */ + + sc->sc_gr[12] = c->psp; + c->psp = c->sigcontext_addr - c->sigcontext_off; + + sof = (c->cfm & 0x7f); + if ((dirty_size = rbs_cover_and_flush (c, sof, dirty_partition, + &dirty_rnat, &bspstore)) < 0) + return dirty_size; + + /* Clear the "in-syscall" flag, because in general we won't be + returning to the interruption-point and we need all registers + restored. */ + sc->sc_flags &= ~IA64_SC_FLAG_IN_SYSCALL; + sc->sc_ip = c->ip; + sc->sc_cfm = c->cfm & (((unw_word_t) 1 << 38) - 1); + sc->sc_pr = (c->pr & ~PR_SCRATCH) | (sc->sc_pr & ~PR_PRESERVED); + if ((ret = ia64_get (c, c->loc[IA64_REG_PFS], &sc->sc_ar_pfs)) < 0 + || (ret = ia64_get (c, c->loc[IA64_REG_FPSR], &sc->sc_ar_fpsr)) < 0 + || (ret = ia64_get (c, c->loc[IA64_REG_UNAT], &sc->sc_ar_unat)) < 0) + return ret; + + sc->sc_gr[1] = c->pi.gp; + if (c->eh_valid_mask & 0x1) sc->sc_gr[15] = c->eh_args[0]; + if (c->eh_valid_mask & 0x2) sc->sc_gr[16] = c->eh_args[1]; + if (c->eh_valid_mask & 0x4) sc->sc_gr[17] = c->eh_args[2]; + if (c->eh_valid_mask & 0x8) sc->sc_gr[18] = c->eh_args[3]; + Debug (9, "sc: r15=%lx,r16=%lx,r17=%lx,r18=%lx\n", + (long) sc->sc_gr[15], (long) sc->sc_gr[16], + (long) sc->sc_gr[17], (long) sc->sc_gr[18]); + } + else + { + /* Account for the fact that _Uia64_install_context() will + return via br.ret, which will decrement bsp by size-of-locals. */ + if ((ret = ia64_get (c, c->loc[IA64_REG_PFS], &pfs)) < 0) + return ret; + sol = (pfs >> 7) & 0x7f; + if ((dirty_size = rbs_cover_and_flush (c, sol, dirty_partition, + &dirty_rnat, &bspstore)) < 0) + return dirty_size; + + extra.r1 = c->pi.gp; + extra.r15 = c->eh_args[0]; + extra.r16 = c->eh_args[1]; + extra.r17 = c->eh_args[2]; + extra.r18 = c->eh_args[3]; + Debug (9, "extra: r15=%lx,r16=%lx,r17=%lx,r18=%lx\n", + (long) extra.r15, (long) extra.r16, + (long) extra.r17, (long) extra.r18); + } + Debug (8, "resuming at ip=%lx\n", (long) c->ip); + ia64_install_cursor (c, pri_unat, (unw_word_t *) &extra, + bspstore, dirty_size, dirty_partition + dirty_size/8, + dirty_rnat); +#elif defined(__hpux) + struct cursor *c = (struct cursor *) cursor; + + setcontext (c->as_arg); /* should not return */ +#endif + return -UNW_EINVAL; +} + +HIDDEN int +ia64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + return local_resume (as, cursor, arg); +} + +#endif /* !UNW_REMOTE_ONLY */ + +#ifndef UNW_LOCAL_ONLY + +static inline int +remote_install_cursor (struct cursor *c) +{ + int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, + int write, void *); + int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, + int write, void *); + unw_fpreg_t fpval; + unw_word_t val; + int reg; + +#if defined(__linux) && !defined(UNW_REMOTE_ONLY) + if (c->as == unw_local_addr_space) + { + /* Take a short-cut: we directly resume out of the cursor and + all we need to do is make sure that all locations point to + memory, not registers. Furthermore, R4-R7 and NAT4-NAT7 are + taken care of by ia64_local_resume() so they don't need to be + handled here. */ +# define MEMIFY(preg, reg) \ + do { \ + if (IA64_IS_REG_LOC (c->loc[(preg)])) \ + c->loc[(preg)] = IA64_LOC_ADDR ((unw_word_t) \ + tdep_uc_addr(c->as_arg, (reg), \ + NULL), 0); \ + } while (0) + MEMIFY (IA64_REG_PR, UNW_IA64_PR); + MEMIFY (IA64_REG_PFS, UNW_IA64_AR_PFS); + MEMIFY (IA64_REG_RNAT, UNW_IA64_AR_RNAT); + MEMIFY (IA64_REG_UNAT, UNW_IA64_AR_UNAT); + MEMIFY (IA64_REG_LC, UNW_IA64_AR_LC); + MEMIFY (IA64_REG_FPSR, UNW_IA64_AR_FPSR); + MEMIFY (IA64_REG_IP, UNW_IA64_BR + 0); + MEMIFY (IA64_REG_B1, UNW_IA64_BR + 1); + MEMIFY (IA64_REG_B2, UNW_IA64_BR + 2); + MEMIFY (IA64_REG_B3, UNW_IA64_BR + 3); + MEMIFY (IA64_REG_B4, UNW_IA64_BR + 4); + MEMIFY (IA64_REG_B5, UNW_IA64_BR + 5); + MEMIFY (IA64_REG_F2, UNW_IA64_FR + 2); + MEMIFY (IA64_REG_F3, UNW_IA64_FR + 3); + MEMIFY (IA64_REG_F4, UNW_IA64_FR + 4); + MEMIFY (IA64_REG_F5, UNW_IA64_FR + 5); + MEMIFY (IA64_REG_F16, UNW_IA64_FR + 16); + MEMIFY (IA64_REG_F17, UNW_IA64_FR + 17); + MEMIFY (IA64_REG_F18, UNW_IA64_FR + 18); + MEMIFY (IA64_REG_F19, UNW_IA64_FR + 19); + MEMIFY (IA64_REG_F20, UNW_IA64_FR + 20); + MEMIFY (IA64_REG_F21, UNW_IA64_FR + 21); + MEMIFY (IA64_REG_F22, UNW_IA64_FR + 22); + MEMIFY (IA64_REG_F23, UNW_IA64_FR + 23); + MEMIFY (IA64_REG_F24, UNW_IA64_FR + 24); + MEMIFY (IA64_REG_F25, UNW_IA64_FR + 25); + MEMIFY (IA64_REG_F26, UNW_IA64_FR + 26); + MEMIFY (IA64_REG_F27, UNW_IA64_FR + 27); + MEMIFY (IA64_REG_F28, UNW_IA64_FR + 28); + MEMIFY (IA64_REG_F29, UNW_IA64_FR + 29); + MEMIFY (IA64_REG_F30, UNW_IA64_FR + 30); + MEMIFY (IA64_REG_F31, UNW_IA64_FR + 31); + } + else +#endif /* __linux && !UNW_REMOTE_ONLY */ + { + access_reg = c->as->acc.access_reg; + access_fpreg = c->as->acc.access_fpreg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + (*access_fpreg) (c->as, reg, &fpval, 1, c->as_arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + (*access_reg) (c->as, reg, &val, 1, c->as_arg); + } + } + } + return (*c->as->acc.resume) (c->as, (unw_cursor_t *) c, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +PROTECTED int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + + Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->ip); + +#ifdef UNW_LOCAL_ONLY + return local_resume (c->as, cursor, c->as_arg); +#else + return remote_install_cursor (c); +#endif +} diff --git a/src/libs/libunwind/ia64/Gscript.c b/src/libs/libunwind/ia64/Gscript.c new file mode 100644 index 0000000000..e96e89e0e8 --- /dev/null +++ b/src/libs/libunwind/ia64/Gscript.c @@ -0,0 +1,765 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" +#include "regs.h" +#include "unwind_i.h" + +enum ia64_script_insn_opcode + { + IA64_INSN_INC_PSP, /* psp += val */ + IA64_INSN_LOAD_PSP, /* psp = *psp_loc */ + IA64_INSN_ADD_PSP, /* s[dst] = (s.psp + val) */ + IA64_INSN_ADD_PSP_NAT, /* like above, but with NaT info */ + IA64_INSN_ADD_SP, /* s[dst] = (s.sp + val) */ + IA64_INSN_ADD_SP_NAT, /* like above, but with NaT info */ + IA64_INSN_MOVE, /* s[dst] = s[val] */ + IA64_INSN_MOVE_NAT, /* like above, but with NaT info */ + IA64_INSN_MOVE_NO_NAT, /* like above, but clear NaT info */ + IA64_INSN_MOVE_STACKED, /* s[dst] = rse_skip(*s.bsp_loc, val) */ + IA64_INSN_MOVE_STACKED_NAT, /* like above, but with NaT info */ + IA64_INSN_MOVE_SCRATCH, /* s[dst] = scratch reg "val" */ + IA64_INSN_MOVE_SCRATCH_NAT, /* like above, but with NaT info */ + IA64_INSN_MOVE_SCRATCH_NO_NAT /* like above, but clear NaT info */ + }; + +#ifdef HAVE___THREAD +static __thread struct ia64_script_cache ia64_per_thread_cache = + { +#ifdef HAVE_ATOMIC_OPS_H + .busy = AO_TS_INITIALIZER +#else + .lock = PTHREAD_MUTEX_INITIALIZER +#endif + }; +#endif + +static inline unw_hash_index_t CONST_ATTR +hash (unw_word_t ip) +{ + /* based on (sqrt(5)/2-1)*2^64 */ +# define magic ((unw_word_t) 0x9e3779b97f4a7c16ULL) + + return (ip >> 4) * magic >> (64 - IA64_LOG_UNW_HASH_SIZE); +} + +static inline long +cache_match (struct ia64_script *script, unw_word_t ip, unw_word_t pr) +{ + if (ip == script->ip && ((pr ^ script->pr_val) & script->pr_mask) == 0) + return 1; + return 0; +} + +static inline void +flush_script_cache (struct ia64_script_cache *cache) +{ + int i; + + cache->lru_head = IA64_UNW_CACHE_SIZE - 1; + cache->lru_tail = 0; + + for (i = 0; i < IA64_UNW_CACHE_SIZE; ++i) + { + if (i > 0) + cache->buckets[i].lru_chain = (i - 1); + cache->buckets[i].coll_chain = -1; + cache->buckets[i].ip = 0; + } + for (i = 0; ihash[i] = -1; +} + +static inline struct ia64_script_cache * +get_script_cache (unw_addr_space_t as, intrmask_t *saved_maskp) +{ + struct ia64_script_cache *cache = &as->global_cache; + unw_caching_policy_t caching = as->caching_policy; + + if (caching == UNW_CACHE_NONE) + return NULL; + +#ifdef HAVE_ATOMIC_H + if (!spin_trylock_irqsave (&cache->busy, *saved_maskp)) + return NULL; +#else +# ifdef HAVE___THREAD + if (as->caching_policy == UNW_CACHE_PER_THREAD) + cache = &ia64_per_thread_cache; +# endif +# ifdef HAVE_ATOMIC_OPS_H + if (AO_test_and_set (&cache->busy) == AO_TS_SET) + return NULL; +# else + if (likely (caching == UNW_CACHE_GLOBAL)) + { + Debug (16, "acquiring lock\n"); + lock_acquire (&cache->lock, *saved_maskp); + } +# endif +#endif + + if (atomic_read (&as->cache_generation) != atomic_read (&cache->generation)) + { + flush_script_cache (cache); + cache->generation = as->cache_generation; + } + return cache; +} + +static inline void +put_script_cache (unw_addr_space_t as, struct ia64_script_cache *cache, + intrmask_t *saved_maskp) +{ + assert (as->caching_policy != UNW_CACHE_NONE); + + Debug (16, "unmasking signals/interrupts and releasing lock\n"); +#ifdef HAVE_ATOMIC_H + spin_unlock_irqrestore (&cache->busy, *saved_maskp); +#else +# ifdef HAVE_ATOMIC_OPS_H + AO_CLEAR (&cache->busy); +# else + if (likely (as->caching_policy == UNW_CACHE_GLOBAL)) + lock_release (&cache->lock, *saved_maskp); +# endif +#endif +} + +static struct ia64_script * +script_lookup (struct ia64_script_cache *cache, struct cursor *c) +{ + struct ia64_script *script = cache->buckets + c->hint; + unsigned short index; + unw_word_t ip, pr; + + ip = c->ip; + pr = c->pr; + + if (cache_match (script, ip, pr)) + return script; + + index = cache->hash[hash (ip)]; + if (index >= IA64_UNW_CACHE_SIZE) + return 0; + + script = cache->buckets + index; + while (1) + { + if (cache_match (script, ip, pr)) + { + /* update hint; no locking needed: single-word writes are atomic */ + c->hint = cache->buckets[c->prev_script].hint = + (script - cache->buckets); + return script; + } + if (script->coll_chain >= IA64_UNW_HASH_SIZE) + return 0; + script = cache->buckets + script->coll_chain; + } +} + +static inline void +script_init (struct ia64_script *script, unw_word_t ip) +{ + script->ip = ip; + script->hint = 0; + script->count = 0; + script->abi_marker = 0; +} + +static inline struct ia64_script * +script_new (struct ia64_script_cache *cache, unw_word_t ip) +{ + struct ia64_script *script, *prev, *tmp; + unw_hash_index_t index; + unsigned short head; + + head = cache->lru_head; + script = cache->buckets + head; + cache->lru_head = script->lru_chain; + + /* re-insert script at the tail of the LRU chain: */ + cache->buckets[cache->lru_tail].lru_chain = head; + cache->lru_tail = head; + + /* remove the old script from the hash table (if it's there): */ + if (script->ip) + { + index = hash (script->ip); + tmp = cache->buckets + cache->hash[index]; + prev = 0; + while (1) + { + if (tmp == script) + { + if (prev) + prev->coll_chain = tmp->coll_chain; + else + cache->hash[index] = tmp->coll_chain; + break; + } + else + prev = tmp; + if (tmp->coll_chain >= IA64_UNW_CACHE_SIZE) + /* old script wasn't in the hash-table */ + break; + tmp = cache->buckets + tmp->coll_chain; + } + } + + /* enter new script in the hash table */ + index = hash (ip); + script->coll_chain = cache->hash[index]; + cache->hash[index] = script - cache->buckets; + + script_init (script, ip); + return script; +} + +static inline void +script_finalize (struct ia64_script *script, struct cursor *c, + struct ia64_state_record *sr) +{ + script->pr_mask = sr->pr_mask; + script->pr_val = sr->pr_val; + script->pi = c->pi; +} + +static inline void +script_emit (struct ia64_script *script, struct ia64_script_insn insn) +{ + if (script->count >= IA64_MAX_SCRIPT_LEN) + { + Dprintf ("%s: script exceeds maximum size of %u instructions!\n", + __FUNCTION__, IA64_MAX_SCRIPT_LEN); + return; + } + script->insn[script->count++] = insn; +} + +static void +compile_reg (struct ia64_state_record *sr, int i, struct ia64_reg_info *r, + struct ia64_script *script) +{ + enum ia64_script_insn_opcode opc; + unsigned long val, rval; + struct ia64_script_insn insn; + long is_preserved_gr; + + if (r->where == IA64_WHERE_NONE || r->when >= sr->when_target) + return; + + opc = IA64_INSN_MOVE; + val = rval = r->val; + is_preserved_gr = (i >= IA64_REG_R4 && i <= IA64_REG_R7); + + if (r->where == IA64_WHERE_GR) + { + /* Handle most common case first... */ + if (rval >= 32) + { + /* register got spilled to a stacked register */ + if (is_preserved_gr) + opc = IA64_INSN_MOVE_STACKED_NAT; + else + opc = IA64_INSN_MOVE_STACKED; + val = rval; + } + else if (rval >= 4 && rval <= 7) + { + /* register got spilled to a preserved register */ + val = IA64_REG_R4 + (rval - 4); + if (is_preserved_gr) + opc = IA64_INSN_MOVE_NAT; + } + else + { + /* register got spilled to a scratch register */ + if (is_preserved_gr) + opc = IA64_INSN_MOVE_SCRATCH_NAT; + else + opc = IA64_INSN_MOVE_SCRATCH; + val = UNW_IA64_GR + rval; + } + } + else + { + switch (r->where) + { + case IA64_WHERE_FR: + /* Note: There is no need to handle NaT-bit info here + (indepent of is_preserved_gr), because for floating-point + NaTs are represented as NaTVal, so the NaT-info never + needs to be consulated. */ + if (rval >= 2 && rval <= 5) + val = IA64_REG_F2 + (rval - 2); + else if (rval >= 16 && rval <= 31) + val = IA64_REG_F16 + (rval - 16); + else + { + opc = IA64_INSN_MOVE_SCRATCH; + val = UNW_IA64_FR + rval; + } + break; + + case IA64_WHERE_BR: + if (rval >= 1 && rval <= 5) + { + val = IA64_REG_B1 + (rval - 1); + if (is_preserved_gr) + opc = IA64_INSN_MOVE_NO_NAT; + } + else + { + opc = IA64_INSN_MOVE_SCRATCH; + if (is_preserved_gr) + opc = IA64_INSN_MOVE_SCRATCH_NO_NAT; + val = UNW_IA64_BR + rval; + } + break; + + case IA64_WHERE_SPREL: + if (is_preserved_gr) + opc = IA64_INSN_ADD_SP_NAT; + else + { + opc = IA64_INSN_ADD_SP; + if (i >= IA64_REG_F2 && i <= IA64_REG_F31) + val |= IA64_LOC_TYPE_FP; + } + break; + + case IA64_WHERE_PSPREL: + if (is_preserved_gr) + opc = IA64_INSN_ADD_PSP_NAT; + else + { + opc = IA64_INSN_ADD_PSP; + if (i >= IA64_REG_F2 && i <= IA64_REG_F31) + val |= IA64_LOC_TYPE_FP; + } + break; + + default: + Dprintf ("%s: register %u has unexpected `where' value of %u\n", + __FUNCTION__, i, r->where); + break; + } + } + insn.opc = opc; + insn.dst = i; + insn.val = val; + script_emit (script, insn); + + if (i == IA64_REG_PSP) + { + /* c->psp must contain the _value_ of the previous sp, not it's + save-location. We get this by dereferencing the value we + just stored in loc[IA64_REG_PSP]: */ + insn.opc = IA64_INSN_LOAD_PSP; + script_emit (script, insn); + } +} + +/* Sort the registers which got saved in decreasing order of WHEN + value. This is needed to ensure that the save-locations are + updated in the proper order. For example, suppose r4 gets spilled + to memory and then r5 gets saved in r4. In this case, we need to + update the save location of r5 before the one of r4. */ + +static inline int +sort_regs (struct ia64_state_record *sr, int regorder[]) +{ + int r, i, j, max, max_reg, max_when, num_regs = 0; + + assert (IA64_REG_BSP == 3); + + for (r = IA64_REG_BSP; r < IA64_NUM_PREGS; ++r) + { + if (sr->curr.reg[r].where == IA64_WHERE_NONE + || sr->curr.reg[r].when >= sr->when_target) + continue; + + regorder[num_regs++] = r; + } + + /* Simple insertion-sort. Involves about N^2/2 comparisons and N + exchanges. N is often small (say, 2-5) so a fancier sorting + algorithm may not be worthwhile. */ + + for (i = max = 0; i < num_regs - 1; ++i) + { + max_reg = regorder[max]; + max_when = sr->curr.reg[max_reg].when; + + for (j = i + 1; j < num_regs; ++j) + if (sr->curr.reg[regorder[j]].when > max_when) + { + max = j; + max_reg = regorder[j]; + max_when = sr->curr.reg[max_reg].when; + } + if (i != max) + { + regorder[max] = regorder[i]; + regorder[i] = max_reg; + } + } + return num_regs; +} + +/* Build an unwind script that unwinds from state OLD_STATE to the + entrypoint of the function that called OLD_STATE. */ + +static inline int +build_script (struct cursor *c, struct ia64_script *script) +{ + int num_regs, i, ret, regorder[IA64_NUM_PREGS - 3]; + struct ia64_reg_info *pri_unat; + struct ia64_state_record sr; + struct ia64_script_insn insn; + + ret = ia64_create_state_record (c, &sr); + if (ret < 0) + return ret; + + /* First, compile the update for IA64_REG_PSP. This is important + because later save-locations may depend on it's correct (updated) + value. Fixed-size frames are handled specially and variable-size + frames get handled via the normal compile_reg(). */ + + if (sr.when_target > sr.curr.reg[IA64_REG_PSP].when + && (sr.curr.reg[IA64_REG_PSP].where == IA64_WHERE_NONE) + && sr.curr.reg[IA64_REG_PSP].val != 0) + { + /* new psp is psp plus frame size */ + insn.opc = IA64_INSN_INC_PSP; + insn.val = sr.curr.reg[IA64_REG_PSP].val; /* frame size */ + script_emit (script, insn); + } + else + compile_reg (&sr, IA64_REG_PSP, sr.curr.reg + IA64_REG_PSP, script); + + /* Second, compile the update for the primary UNaT, if any: */ + + if (sr.when_target >= sr.curr.reg[IA64_REG_PRI_UNAT_GR].when + || sr.when_target >= sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when) + { + if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_GR].when) + /* (primary) NaT bits were saved to memory only */ + pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_MEM; + else if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when) + /* (primary) NaT bits were saved to a register only */ + pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_GR; + else if (sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when > + sr.curr.reg[IA64_REG_PRI_UNAT_GR].when) + /* (primary) NaT bits were last saved to memory */ + pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_MEM; + else + /* (primary) NaT bits were last saved to a register */ + pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_GR; + + /* Note: we always store the final primary-UNaT location in UNAT_MEM. */ + compile_reg (&sr, IA64_REG_PRI_UNAT_MEM, pri_unat, script); + } + + /* Third, compile the other register in decreasing order of WHEN values. */ + + num_regs = sort_regs (&sr, regorder); + for (i = 0; i < num_regs; ++i) + compile_reg (&sr, regorder[i], sr.curr.reg + regorder[i], script); + + script->abi_marker = sr.abi_marker; + script_finalize (script, c, &sr); + + ia64_free_state_record (&sr); + return 0; +} + +static inline void +set_nat_info (struct cursor *c, unsigned long dst, + ia64_loc_t nat_loc, uint8_t bitnr) +{ + assert (dst >= IA64_REG_R4 && dst <= IA64_REG_R7); + + c->loc[dst - IA64_REG_R4 + IA64_REG_NAT4] = nat_loc; + c->nat_bitnr[dst - IA64_REG_R4] = bitnr; +} + +/* Apply the unwinding actions represented by OPS and update SR to + reflect the state that existed upon entry to the function that this + unwinder represents. */ + +static inline int +run_script (struct ia64_script *script, struct cursor *c) +{ + struct ia64_script_insn *ip, *limit, next_insn; + ia64_loc_t loc, nat_loc; + unsigned long opc, dst; + uint8_t nat_bitnr; + unw_word_t val; + int ret; + + c->pi = script->pi; + ip = script->insn; + limit = script->insn + script->count; + next_insn = *ip; + c->abi_marker = script->abi_marker; + + while (ip++ < limit) + { + opc = next_insn.opc; + dst = next_insn.dst; + val = next_insn.val; + next_insn = *ip; + + /* This is by far the most common operation: */ + if (likely (opc == IA64_INSN_MOVE_STACKED)) + { + if ((ret = ia64_get_stacked (c, val, &loc, NULL)) < 0) + return ret; + } + else + switch (opc) + { + case IA64_INSN_INC_PSP: + c->psp += val; + continue; + + case IA64_INSN_LOAD_PSP: + if ((ret = ia64_get (c, c->loc[IA64_REG_PSP], &c->psp)) < 0) + return ret; + continue; + + case IA64_INSN_ADD_PSP: + loc = IA64_LOC_ADDR (c->psp + val, (val & IA64_LOC_TYPE_FP)); + break; + + case IA64_INSN_ADD_SP: + loc = IA64_LOC_ADDR (c->sp + val, (val & IA64_LOC_TYPE_FP)); + break; + + case IA64_INSN_MOVE_NO_NAT: + set_nat_info (c, dst, IA64_NULL_LOC, 0); + case IA64_INSN_MOVE: + loc = c->loc[val]; + break; + + case IA64_INSN_MOVE_SCRATCH_NO_NAT: + set_nat_info (c, dst, IA64_NULL_LOC, 0); + case IA64_INSN_MOVE_SCRATCH: + loc = ia64_scratch_loc (c, val, NULL); + break; + + case IA64_INSN_ADD_PSP_NAT: + loc = IA64_LOC_ADDR (c->psp + val, 0); + assert (!IA64_IS_REG_LOC (loc)); + set_nat_info (c, dst, + c->loc[IA64_REG_PRI_UNAT_MEM], + ia64_unat_slot_num (IA64_GET_ADDR (loc))); + break; + + case IA64_INSN_ADD_SP_NAT: + loc = IA64_LOC_ADDR (c->sp + val, 0); + assert (!IA64_IS_REG_LOC (loc)); + set_nat_info (c, dst, + c->loc[IA64_REG_PRI_UNAT_MEM], + ia64_unat_slot_num (IA64_GET_ADDR (loc))); + break; + + case IA64_INSN_MOVE_NAT: + loc = c->loc[val]; + set_nat_info (c, dst, + c->loc[val - IA64_REG_R4 + IA64_REG_NAT4], + c->nat_bitnr[val - IA64_REG_R4]); + break; + + case IA64_INSN_MOVE_STACKED_NAT: + if ((ret = ia64_get_stacked (c, val, &loc, &nat_loc)) < 0) + return ret; + assert (!IA64_IS_REG_LOC (loc)); + set_nat_info (c, dst, nat_loc, rse_slot_num (IA64_GET_ADDR (loc))); + break; + + case IA64_INSN_MOVE_SCRATCH_NAT: + loc = ia64_scratch_loc (c, val, NULL); + nat_loc = ia64_scratch_loc (c, val + (UNW_IA64_NAT - UNW_IA64_GR), + &nat_bitnr); + set_nat_info (c, dst, nat_loc, nat_bitnr); + break; + } + c->loc[dst] = loc; + } + return 0; +} + +static int +uncached_find_save_locs (struct cursor *c) +{ + struct ia64_script script; + int ret = 0; + + if ((ret = ia64_fetch_proc_info (c, c->ip, 1)) < 0) + return ret; + + script_init (&script, c->ip); + if ((ret = build_script (c, &script)) < 0) + { + if (ret != -UNW_ESTOPUNWIND) + Dprintf ("%s: failed to build unwind script for ip %lx\n", + __FUNCTION__, (long) c->ip); + return ret; + } + return run_script (&script, c); +} + +HIDDEN int +ia64_find_save_locs (struct cursor *c) +{ + struct ia64_script_cache *cache = NULL; + struct ia64_script *script = NULL; + intrmask_t saved_mask; + int ret = 0; + + if (c->as->caching_policy == UNW_CACHE_NONE) + return uncached_find_save_locs (c); + + cache = get_script_cache (c->as, &saved_mask); + if (!cache) + { + Debug (1, "contention on script-cache; doing uncached lookup\n"); + return uncached_find_save_locs (c); + } + { + script = script_lookup (cache, c); + Debug (8, "ip %lx %s in script cache\n", (long) c->ip, + script ? "hit" : "missed"); + + if (!script || (script->count == 0 && !script->pi.unwind_info)) + { + if ((ret = ia64_fetch_proc_info (c, c->ip, 1)) < 0) + goto out; + } + + if (!script) + { + script = script_new (cache, c->ip); + if (!script) + { + Dprintf ("%s: failed to create unwind script\n", __FUNCTION__); + ret = -UNW_EUNSPEC; + goto out; + } + } + cache->buckets[c->prev_script].hint = script - cache->buckets; + + if (script->count == 0) + ret = build_script (c, script); + + assert (script->count > 0); + + c->hint = script->hint; + c->prev_script = script - cache->buckets; + + if (ret < 0) + { + if (ret != -UNW_ESTOPUNWIND) + Dprintf ("%s: failed to locate/build unwind script for ip %lx\n", + __FUNCTION__, (long) c->ip); + goto out; + } + + ret = run_script (script, c); + } + out: + put_script_cache (c->as, cache, &saved_mask); + return ret; +} + +HIDDEN void +ia64_validate_cache (unw_addr_space_t as, void *arg) +{ +#ifndef UNW_REMOTE_ONLY + if (as == unw_local_addr_space && ia64_local_validate_cache (as, arg) == 1) + return; +#endif + +#ifndef UNW_LOCAL_ONLY + /* local info is up-to-date, check dynamic info. */ + unwi_dyn_validate_cache (as, arg); +#endif +} + +HIDDEN int +ia64_cache_proc_info (struct cursor *c) +{ + struct ia64_script_cache *cache; + struct ia64_script *script; + intrmask_t saved_mask; + int ret = 0; + + cache = get_script_cache (c->as, &saved_mask); + if (!cache) + return ret; /* cache is busy */ + + /* Re-check to see if a cache entry has been added in the meantime: */ + script = script_lookup (cache, c); + if (script) + goto out; + + script = script_new (cache, c->ip); + if (!script) + { + Dprintf ("%s: failed to create unwind script\n", __FUNCTION__); + ret = -UNW_EUNSPEC; + goto out; + } + + script->pi = c->pi; + + out: + put_script_cache (c->as, cache, &saved_mask); + return ret; +} + +HIDDEN int +ia64_get_cached_proc_info (struct cursor *c) +{ + struct ia64_script_cache *cache; + struct ia64_script *script; + intrmask_t saved_mask; + + cache = get_script_cache (c->as, &saved_mask); + if (!cache) + return -UNW_ENOINFO; /* cache is busy */ + { + script = script_lookup (cache, c); + if (script) + c->pi = script->pi; + } + put_script_cache (c->as, cache, &saved_mask); + return script ? 0 : -UNW_ENOINFO; +} diff --git a/src/libs/libunwind/ia64/Gstep.c b/src/libs/libunwind/ia64/Gstep.c new file mode 100644 index 0000000000..0191f642a4 --- /dev/null +++ b/src/libs/libunwind/ia64/Gstep.c @@ -0,0 +1,359 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" +#include "unwind_i.h" + +static inline int +linux_sigtramp (struct cursor *c, ia64_loc_t prev_cfm_loc, + unw_word_t *num_regsp) +{ +#if defined(UNW_LOCAL_ONLY) && !defined(__linux) + return -UNW_EINVAL; +#else + unw_word_t sc_addr; + int ret; + + if ((ret = ia64_get (c, IA64_LOC_ADDR (c->sp + 0x10 + + LINUX_SIGFRAME_ARG2_OFF, 0), + &sc_addr)) < 0) + return ret; + + c->sigcontext_addr = sc_addr; + + if (!IA64_IS_REG_LOC (c->loc[IA64_REG_IP]) + && IA64_GET_ADDR (c->loc[IA64_REG_IP]) == sc_addr + LINUX_SC_BR_OFF + 8) + { + /* Linux kernels before 2.4.19 and 2.5.10 had buggy + unwind info for sigtramp. Fix it up here. */ + c->loc[IA64_REG_IP] = IA64_LOC_ADDR (sc_addr + LINUX_SC_IP_OFF, 0); + c->cfm_loc = IA64_LOC_ADDR (sc_addr + LINUX_SC_CFM_OFF, 0); + } + + /* do what can't be described by unwind directives: */ + c->loc[IA64_REG_PFS] = IA64_LOC_ADDR (sc_addr + LINUX_SC_AR_PFS_OFF, 0); + c->ec_loc = prev_cfm_loc; + *num_regsp = c->cfm & 0x7f; /* size of frame */ + return 0; +#endif +} + +static inline int +linux_interrupt (struct cursor *c, ia64_loc_t prev_cfm_loc, + unw_word_t *num_regsp, int marker) +{ +#if defined(UNW_LOCAL_ONLY) && !(defined(__linux) && defined(__KERNEL__)) + return -UNW_EINVAL; +#else + unw_word_t sc_addr, num_regs; + ia64_loc_t pfs_loc; + + sc_addr = c->sigcontext_addr = c->sp + 0x10; + + if ((c->pr & (1UL << LINUX_PT_P_NONSYS)) != 0) + num_regs = c->cfm & 0x7f; + else + num_regs = 0; + + /* do what can't be described by unwind directives: */ + if (marker == ABI_MARKER_OLD_LINUX_INTERRUPT) + pfs_loc = IA64_LOC_ADDR (sc_addr + LINUX_OLD_PT_PFS_OFF, 0); + else + pfs_loc = IA64_LOC_ADDR (sc_addr + LINUX_PT_PFS_OFF, 0); + c->loc[IA64_REG_PFS] = pfs_loc; + c->ec_loc = prev_cfm_loc; + *num_regsp = num_regs; /* size of frame */ + return 0; +#endif +} + +static inline int +hpux_sigtramp (struct cursor *c, ia64_loc_t prev_cfm_loc, + unw_word_t *num_regsp) +{ +#if defined(UNW_LOCAL_ONLY) && !defined(__hpux) + return -UNW_EINVAL; +#else + unw_word_t sc_addr, bsp, bspstore; + ia64_loc_t sc_loc; + int ret, i; + + /* HP-UX passes the address of ucontext_t in r32: */ + if ((ret = ia64_get_stacked (c, 32, &sc_loc, NULL)) < 0) + return ret; + if ((ret = ia64_get (c, sc_loc, &sc_addr)) < 0) + return ret; + + c->sigcontext_addr = sc_addr; + + /* Now mark all (preserved) registers as coming from the + signal context: */ + c->cfm_loc = IA64_LOC_UC_REG (UNW_IA64_CFM, sc_addr); + c->loc[IA64_REG_PRI_UNAT_MEM] = IA64_NULL_LOC; + c->loc[IA64_REG_PSP] = IA64_LOC_UC_REG (UNW_IA64_GR + 12, sc_addr); + c->loc[IA64_REG_BSP] = IA64_LOC_UC_REG (UNW_IA64_AR_BSP, sc_addr); + c->loc[IA64_REG_BSPSTORE] = IA64_LOC_UC_REG (UNW_IA64_AR_BSPSTORE, sc_addr); + c->loc[IA64_REG_PFS] = IA64_LOC_UC_REG (UNW_IA64_AR_PFS, sc_addr); + c->loc[IA64_REG_RNAT] = IA64_LOC_UC_REG (UNW_IA64_AR_RNAT, sc_addr); + c->loc[IA64_REG_IP] = IA64_LOC_UC_REG (UNW_IA64_IP, sc_addr); + c->loc[IA64_REG_R4] = IA64_LOC_UC_REG (UNW_IA64_GR + 4, sc_addr); + c->loc[IA64_REG_R5] = IA64_LOC_UC_REG (UNW_IA64_GR + 5, sc_addr); + c->loc[IA64_REG_R6] = IA64_LOC_UC_REG (UNW_IA64_GR + 6, sc_addr); + c->loc[IA64_REG_R7] = IA64_LOC_UC_REG (UNW_IA64_GR + 7, sc_addr); + c->loc[IA64_REG_NAT4] = IA64_LOC_UC_REG (UNW_IA64_NAT + 4, sc_addr); + c->loc[IA64_REG_NAT5] = IA64_LOC_UC_REG (UNW_IA64_NAT + 5, sc_addr); + c->loc[IA64_REG_NAT6] = IA64_LOC_UC_REG (UNW_IA64_NAT + 6, sc_addr); + c->loc[IA64_REG_NAT7] = IA64_LOC_UC_REG (UNW_IA64_NAT + 7, sc_addr); + c->loc[IA64_REG_UNAT] = IA64_LOC_UC_REG (UNW_IA64_AR_UNAT, sc_addr); + c->loc[IA64_REG_PR] = IA64_LOC_UC_REG (UNW_IA64_PR, sc_addr); + c->loc[IA64_REG_LC] = IA64_LOC_UC_REG (UNW_IA64_AR_LC, sc_addr); + c->loc[IA64_REG_FPSR] = IA64_LOC_UC_REG (UNW_IA64_AR_FPSR, sc_addr); + c->loc[IA64_REG_B1] = IA64_LOC_UC_REG (UNW_IA64_BR + 1, sc_addr); + c->loc[IA64_REG_B2] = IA64_LOC_UC_REG (UNW_IA64_BR + 2, sc_addr); + c->loc[IA64_REG_B3] = IA64_LOC_UC_REG (UNW_IA64_BR + 3, sc_addr); + c->loc[IA64_REG_B4] = IA64_LOC_UC_REG (UNW_IA64_BR + 4, sc_addr); + c->loc[IA64_REG_B5] = IA64_LOC_UC_REG (UNW_IA64_BR + 5, sc_addr); + c->loc[IA64_REG_F2] = IA64_LOC_UC_REG (UNW_IA64_FR + 2, sc_addr); + c->loc[IA64_REG_F3] = IA64_LOC_UC_REG (UNW_IA64_FR + 3, sc_addr); + c->loc[IA64_REG_F4] = IA64_LOC_UC_REG (UNW_IA64_FR + 4, sc_addr); + c->loc[IA64_REG_F5] = IA64_LOC_UC_REG (UNW_IA64_FR + 5, sc_addr); + for (i = 0; i < 16; ++i) + c->loc[IA64_REG_F16 + i] = IA64_LOC_UC_REG (UNW_IA64_FR + 16 + i, sc_addr); + + c->pi.flags |= UNW_PI_FLAG_IA64_RBS_SWITCH; + + /* update the CFM cache: */ + if ((ret = ia64_get (c, c->cfm_loc, &c->cfm)) < 0) + return ret; + /* update the PSP cache: */ + if ((ret = ia64_get (c, c->loc[IA64_REG_PSP], &c->psp)) < 0) + return ret; + + if ((ret = ia64_get (c, c->loc[IA64_REG_BSP], &bsp)) < 0 + || (ret = ia64_get (c, c->loc[IA64_REG_BSPSTORE], &bspstore)) < 0) + return ret; + if (bspstore < bsp) + /* Dirty partition got spilled into the ucontext_t structure + itself. We'll need to access it via uc_access(3). */ + rbs_switch (c, bsp, bspstore, IA64_LOC_UC_ADDR (bsp | 0x1f8, 0)); + + c->ec_loc = prev_cfm_loc; + + *num_regsp = 0; + return 0; +#endif +} + + +static inline int +check_rbs_switch (struct cursor *c) +{ + unw_word_t saved_bsp, saved_bspstore, loadrs, ndirty; + int ret = 0; + + saved_bsp = c->bsp; + if (c->pi.flags & UNW_PI_FLAG_IA64_RBS_SWITCH) + { + /* Got ourselves a frame that has saved ar.bspstore, ar.bsp, + and ar.rnat, so we're all set for rbs-switching: */ + if ((ret = ia64_get (c, c->loc[IA64_REG_BSP], &saved_bsp)) < 0 + || (ret = ia64_get (c, c->loc[IA64_REG_BSPSTORE], &saved_bspstore))) + return ret; + } + else if ((c->abi_marker == ABI_MARKER_LINUX_SIGTRAMP + || c->abi_marker == ABI_MARKER_OLD_LINUX_SIGTRAMP) + && !IA64_IS_REG_LOC (c->loc[IA64_REG_BSP]) + && (IA64_GET_ADDR (c->loc[IA64_REG_BSP]) + == c->sigcontext_addr + LINUX_SC_AR_BSP_OFF)) + { + /* When Linux delivers a signal on an alternate stack, it + does things a bit differently from what the unwind + conventions allow us to describe: instead of saving + ar.rnat, ar.bsp, and ar.bspstore, it saves the former two + plus the "loadrs" value. Because of this, we need to + detect & record a potential rbs-area switch + manually... */ + + /* If ar.bsp has been saved already AND the current bsp is + not equal to the saved value, then we know for sure that + we're past the point where the backing store has been + switched (and before the point where it's restored). */ + if ((ret = ia64_get (c, IA64_LOC_ADDR (c->sigcontext_addr + + LINUX_SC_AR_BSP_OFF, 0), + &saved_bsp) < 0) + || (ret = ia64_get (c, IA64_LOC_ADDR (c->sigcontext_addr + + LINUX_SC_LOADRS_OFF, 0), + &loadrs) < 0)) + return ret; + loadrs >>= 16; + ndirty = rse_num_regs (c->bsp - loadrs, c->bsp); + saved_bspstore = rse_skip_regs (saved_bsp, -ndirty); + } + + if (saved_bsp == c->bsp) + return 0; + + return rbs_switch (c, saved_bsp, saved_bspstore, c->loc[IA64_REG_RNAT]); +} + +static inline int +update_frame_state (struct cursor *c) +{ + unw_word_t prev_ip, prev_sp, prev_bsp, ip, num_regs; + ia64_loc_t prev_cfm_loc; + int ret; + + prev_cfm_loc = c->cfm_loc; + prev_ip = c->ip; + prev_sp = c->sp; + prev_bsp = c->bsp; + + /* Update the IP cache (do this first: if we reach the end of the + frame-chain, the rest of the info may not be valid/useful + anymore. */ + ret = ia64_get (c, c->loc[IA64_REG_IP], &ip); + if (ret < 0) + return ret; + c->ip = ip; + + if ((ip & 0xc) != 0) + { + /* don't let obviously bad addresses pollute the cache */ + Debug (1, "rejecting bad ip=0x%lx\n", (long) c->ip); + return -UNW_EINVALIDIP; + } + + c->cfm_loc = c->loc[IA64_REG_PFS]; + /* update the CFM cache: */ + ret = ia64_get (c, c->cfm_loc, &c->cfm); + if (ret < 0) + return ret; + + /* Normally, AR.EC is stored in the CFM save-location. That + save-location contains the full function-state as defined by + AR.PFS. However, interruptions only save the frame-marker, not + any other info in CFM. Instead, AR.EC gets saved on the first + call by the interruption-handler. Thus, interruption-related + frames need to track the _previous_ CFM save-location since + that's were AR.EC is saved. We support this by setting ec_loc to + cfm_loc by default and giving frames marked with an ABI-marker + the chance to override this value with prev_cfm_loc. */ + c->ec_loc = c->cfm_loc; + + num_regs = 0; + if (unlikely (c->abi_marker)) + { + c->last_abi_marker = c->abi_marker; + switch (ia64_get_abi_marker (c)) + { + case ABI_MARKER_LINUX_SIGTRAMP: + case ABI_MARKER_OLD_LINUX_SIGTRAMP: + ia64_set_abi (c, ABI_LINUX); + if ((ret = linux_sigtramp (c, prev_cfm_loc, &num_regs)) < 0) + return ret; + break; + + case ABI_MARKER_OLD_LINUX_INTERRUPT: + case ABI_MARKER_LINUX_INTERRUPT: + ia64_set_abi (c, ABI_LINUX); + if ((ret = linux_interrupt (c, prev_cfm_loc, &num_regs, + c->abi_marker)) < 0) + return ret; + break; + + case ABI_MARKER_HP_UX_SIGTRAMP: + ia64_set_abi (c, ABI_HPUX); + if ((ret = hpux_sigtramp (c, prev_cfm_loc, &num_regs)) < 0) + return ret; + break; + + default: + Debug (1, "unknown ABI marker: ABI=%u, context=%u\n", + c->abi_marker >> 8, c->abi_marker & 0xff); + return -UNW_EINVAL; + } + Debug (12, "sigcontext_addr=%lx (ret=%d)\n", + (unsigned long) c->sigcontext_addr, ret); + + c->sigcontext_off = c->sigcontext_addr - c->sp; + + /* update the IP cache: */ + if ((ret = ia64_get (c, c->loc[IA64_REG_IP], &ip)) < 0) + return ret; + c->ip = ip; + if (ip == 0) + /* end of frame-chain reached */ + return 0; + } + else + num_regs = (c->cfm >> 7) & 0x7f; /* size of locals */ + + if (!IA64_IS_NULL_LOC (c->loc[IA64_REG_BSP])) + { + ret = check_rbs_switch (c); + if (ret < 0) + return ret; + } + + c->bsp = rse_skip_regs (c->bsp, -num_regs); + + c->sp = c->psp; + c->abi_marker = 0; + + if (c->ip == prev_ip && c->sp == prev_sp && c->bsp == prev_bsp) + { + Dprintf ("%s: ip, sp, and bsp unchanged; stopping here (ip=0x%lx)\n", + __FUNCTION__, (long) ip); + return -UNW_EBADFRAME; + } + + /* as we unwind, the saved ar.unat becomes the primary unat: */ + c->loc[IA64_REG_PRI_UNAT_MEM] = c->loc[IA64_REG_UNAT]; + + /* restore the predicates: */ + ret = ia64_get (c, c->loc[IA64_REG_PR], &c->pr); + if (ret < 0) + return ret; + + c->pi_valid = 0; + return 0; +} + + +PROTECTED int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->ip); + + if ((ret = ia64_find_save_locs (c)) >= 0 + && (ret = update_frame_state (c)) >= 0) + ret = (c->ip == 0) ? 0 : 1; + + Debug (2, "returning %d (ip=0x%016lx)\n", ret, (unsigned long) c->ip); + return ret; +} diff --git a/src/libs/libunwind/ia64/Gtables.c b/src/libs/libunwind/ia64/Gtables.c new file mode 100644 index 0000000000..6959cae98b --- /dev/null +++ b/src/libs/libunwind/ia64/Gtables.c @@ -0,0 +1,731 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2001-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include + +#include "unwind_i.h" + +#ifdef HAVE_IA64INTRIN_H +# include +#endif + +extern unw_addr_space_t _ULia64_local_addr_space; + +struct ia64_table_entry + { + uint64_t start_offset; + uint64_t end_offset; + uint64_t info_offset; + }; + +#ifdef UNW_LOCAL_ONLY + +static inline int +is_local_addr_space (unw_addr_space_t as) +{ + return 1; +} + +static inline int +read_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *valp, void *arg) +{ + *valp = *(unw_word_t *) addr; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ + +static inline int +is_local_addr_space (unw_addr_space_t as) +{ + return as == unw_local_addr_space; +} + +static inline int +read_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *valp, void *arg) +{ + unw_accessors_t *a = unw_get_accessors (as); + + return (*a->access_mem) (as, addr, valp, 0, arg); +} + +/* Helper macro for reading an ia64_table_entry from remote memory. */ +#define remote_read(addr, member) \ + (*a->access_mem) (as, (addr) + offsetof (struct ia64_table_entry, \ + member), &member, 0, arg) + +/* Lookup an unwind-table entry in remote memory. Returns 1 if an + entry is found, 0 if no entry is found, negative if an error + occurred reading remote memory. */ +static int +remote_lookup (unw_addr_space_t as, + unw_word_t table, size_t table_size, unw_word_t rel_ip, + struct ia64_table_entry *e, void *arg) +{ + unw_word_t e_addr = 0, start_offset, end_offset, info_offset; + unw_accessors_t *a = unw_get_accessors (as); + unsigned long lo, hi, mid; + int ret; + + /* do a binary search for right entry: */ + for (lo = 0, hi = table_size / sizeof (struct ia64_table_entry); lo < hi;) + { + mid = (lo + hi) / 2; + e_addr = table + mid * sizeof (struct ia64_table_entry); + if ((ret = remote_read (e_addr, start_offset)) < 0) + return ret; + + if (rel_ip < start_offset) + hi = mid; + else + { + if ((ret = remote_read (e_addr, end_offset)) < 0) + return ret; + + if (rel_ip >= end_offset) + lo = mid + 1; + else + break; + } + } + if (rel_ip < start_offset || rel_ip >= end_offset) + return 0; + e->start_offset = start_offset; + e->end_offset = end_offset; + + if ((ret = remote_read (e_addr, info_offset)) < 0) + return ret; + e->info_offset = info_offset; + return 1; +} + +HIDDEN void +tdep_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) +{ + if (!pi->unwind_info) + return; + + if (is_local_addr_space (as)) + { + free (pi->unwind_info); + pi->unwind_info = NULL; + } +} + +PROTECTED unw_word_t +_Uia64_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg) +{ + unw_word_t hdr_addr, info_addr, hdr, directives, pers, cookie, off; + unw_word_t start_offset, end_offset, info_offset, segbase; + struct ia64_table_entry *e; + size_t table_size; + unw_word_t gp = di->gp; + int ret; + + switch (di->format) + { + case UNW_INFO_FORMAT_DYNAMIC: + default: + return 0; + + case UNW_INFO_FORMAT_TABLE: + e = (struct ia64_table_entry *) di->u.ti.table_data; + table_size = di->u.ti.table_len * sizeof (di->u.ti.table_data[0]); + segbase = di->u.ti.segbase; + if (table_size < sizeof (struct ia64_table_entry)) + return 0; + start_offset = e[0].start_offset; + end_offset = e[0].end_offset; + info_offset = e[0].info_offset; + break; + + case UNW_INFO_FORMAT_REMOTE_TABLE: + { + unw_accessors_t *a = unw_get_accessors (as); + unw_word_t e_addr = di->u.rti.table_data; + + table_size = di->u.rti.table_len * sizeof (unw_word_t); + segbase = di->u.rti.segbase; + if (table_size < sizeof (struct ia64_table_entry)) + return 0; + + if ( (ret = remote_read (e_addr, start_offset) < 0) + || (ret = remote_read (e_addr, end_offset) < 0) + || (ret = remote_read (e_addr, info_offset) < 0)) + return ret; + } + break; + } + + if (start_offset != end_offset) + /* dyn-list entry cover a zero-length "procedure" and should be + first entry (note: technically a binary could contain code + below the segment base, but this doesn't happen for normal + binaries and certainly doesn't happen when libunwind is a + separate shared object. For weird cases, the application may + have to provide its own (slower) version of this routine. */ + return 0; + + hdr_addr = info_offset + segbase; + info_addr = hdr_addr + 8; + + /* read the header word: */ + if ((ret = read_mem (as, hdr_addr, &hdr, arg)) < 0) + return ret; + + if (IA64_UNW_VER (hdr) != 1 + || IA64_UNW_FLAG_EHANDLER (hdr) || IA64_UNW_FLAG_UHANDLER (hdr)) + /* dyn-list entry must be version 1 and doesn't have ehandler + or uhandler */ + return 0; + + if (IA64_UNW_LENGTH (hdr) != 1) + /* dyn-list entry must consist of a single word of NOP directives */ + return 0; + + if ( ((ret = read_mem (as, info_addr, &directives, arg)) < 0) + || ((ret = read_mem (as, info_addr + 0x08, &pers, arg)) < 0) + || ((ret = read_mem (as, info_addr + 0x10, &cookie, arg)) < 0) + || ((ret = read_mem (as, info_addr + 0x18, &off, arg)) < 0)) + return 0; + + if (directives != 0 || pers != 0 + || (!as->big_endian && cookie != 0x7473696c2d6e7964ULL) + || ( as->big_endian && cookie != 0x64796e2d6c697374ULL)) + return 0; + + /* OK, we ran the gauntlet and found it: */ + return off + gp; +} + +#endif /* !UNW_LOCAL_ONLY */ + +static inline const struct ia64_table_entry * +lookup (struct ia64_table_entry *table, size_t table_size, unw_word_t rel_ip) +{ + const struct ia64_table_entry *e = 0; + unsigned long lo, hi, mid; + + /* do a binary search for right entry: */ + for (lo = 0, hi = table_size / sizeof (struct ia64_table_entry); lo < hi;) + { + mid = (lo + hi) / 2; + e = table + mid; + if (rel_ip < e->start_offset) + hi = mid; + else if (rel_ip >= e->end_offset) + lo = mid + 1; + else + break; + } + if (rel_ip < e->start_offset || rel_ip >= e->end_offset) + return NULL; + return e; +} + +PROTECTED int +unw_search_ia64_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t *di, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + unw_word_t addr, hdr_addr, info_addr, info_end_addr, hdr, *wp; + const struct ia64_table_entry *e = NULL; + unw_word_t handler_offset, segbase = 0; + int ret, is_local; +#ifndef UNW_LOCAL_ONLY + struct ia64_table_entry ent; +#endif + + assert ((di->format == UNW_INFO_FORMAT_TABLE + || di->format == UNW_INFO_FORMAT_REMOTE_TABLE) + && (ip >= di->start_ip && ip < di->end_ip)); + + pi->flags = 0; + pi->unwind_info = 0; + pi->handler = 0; + + if (likely (di->format == UNW_INFO_FORMAT_TABLE)) + { + segbase = di->u.ti.segbase; + e = lookup ((struct ia64_table_entry *) di->u.ti.table_data, + di->u.ti.table_len * sizeof (unw_word_t), + ip - segbase); + } +#ifndef UNW_LOCAL_ONLY + else + { + segbase = di->u.rti.segbase; + if ((ret = remote_lookup (as, di->u.rti.table_data, + di->u.rti.table_len * sizeof (unw_word_t), + ip - segbase, &ent, arg)) < 0) + return ret; + if (ret) + e = &ent; + } +#endif + if (!e) + { + /* IP is inside this table's range, but there is no explicit + unwind info => use default conventions (i.e., this is NOT an + error). */ + memset (pi, 0, sizeof (*pi)); + pi->start_ip = 0; + pi->end_ip = 0; + pi->gp = di->gp; + pi->lsda = 0; + return 0; + } + + pi->start_ip = e->start_offset + segbase; + pi->end_ip = e->end_offset + segbase; + + hdr_addr = e->info_offset + segbase; + info_addr = hdr_addr + 8; + + /* Read the header word. Note: the actual unwind-info is always + assumed to reside in memory, independent of whether di->format is + UNW_INFO_FORMAT_TABLE or UNW_INFO_FORMAT_REMOTE_TABLE. */ + + if ((ret = read_mem (as, hdr_addr, &hdr, arg)) < 0) + return ret; + + if (IA64_UNW_VER (hdr) != 1) + { + Debug (1, "Unknown header version %ld (hdr word=0x%lx @ 0x%lx)\n", + IA64_UNW_VER (hdr), (unsigned long) hdr, + (unsigned long) hdr_addr); + return -UNW_EBADVERSION; + } + + info_end_addr = info_addr + 8 * IA64_UNW_LENGTH (hdr); + + is_local = is_local_addr_space (as); + + /* If we must have the unwind-info, return it. Also, if we are in + the local address-space, return the unwind-info because it's so + cheap to do so and it may come in handy later on. */ + if (need_unwind_info || is_local) + { + pi->unwind_info_size = 8 * IA64_UNW_LENGTH (hdr); + + if (is_local) + pi->unwind_info = (void *) (uintptr_t) info_addr; + else + { + /* Internalize unwind info. Note: since we're doing this + only for non-local address spaces, there is no + signal-safety issue and it is OK to use malloc()/free(). */ + pi->unwind_info = malloc (8 * IA64_UNW_LENGTH (hdr)); + if (!pi->unwind_info) + return -UNW_ENOMEM; + + wp = (unw_word_t *) pi->unwind_info; + for (addr = info_addr; addr < info_end_addr; addr += 8, ++wp) + { + if ((ret = read_mem (as, addr, wp, arg)) < 0) + { + free (pi->unwind_info); + return ret; + } + } + } + } + + if (IA64_UNW_FLAG_EHANDLER (hdr) || IA64_UNW_FLAG_UHANDLER (hdr)) + { + /* read the personality routine address (address is gp-relative): */ + if ((ret = read_mem (as, info_end_addr, &handler_offset, arg)) < 0) + return ret; + Debug (4, "handler ptr @ offset=%lx, gp=%lx\n", handler_offset, di->gp); + if ((read_mem (as, handler_offset + di->gp, &pi->handler, arg)) < 0) + return ret; + } + pi->lsda = info_end_addr + 8; + pi->gp = di->gp; + pi->format = di->format; + return 0; +} + +#ifndef UNW_REMOTE_ONLY + +# if defined(HAVE_DL_ITERATE_PHDR) +# include +# include + +# if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2) \ + || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && !defined(DT_CONFIG)) +# error You need GLIBC 2.2.4 or later on IA-64 Linux +# endif + +# if defined(HAVE_GETUNWIND) + extern unsigned long getunwind (void *buf, size_t len); +# else /* HAVE_GETUNWIND */ +# include +# include +# ifndef __NR_getunwind +# define __NR_getunwind 1215 +# endif + +static unsigned long +getunwind (void *buf, size_t len) +{ + return syscall (SYS_getunwind, buf, len); +} + +# endif /* HAVE_GETUNWIND */ + +static unw_dyn_info_t kernel_table; + +static int +get_kernel_table (unw_dyn_info_t *di) +{ + struct ia64_table_entry *ktab, *etab; + size_t size; + + Debug (16, "getting kernel table"); + + size = getunwind (NULL, 0); + ktab = sos_alloc (size); + if (!ktab) + { + Dprintf (__FILE__".%s: failed to allocate %zu bytes", + __FUNCTION__, size); + return -UNW_ENOMEM; + } + getunwind (ktab, size); + + /* Determine length of kernel's unwind table & relocate its entries. */ + for (etab = ktab; etab->start_offset; ++etab) + etab->info_offset += (uint64_t) ktab; + + di->format = UNW_INFO_FORMAT_TABLE; + di->gp = 0; + di->start_ip = ktab[0].start_offset; + di->end_ip = etab[-1].end_offset; + di->u.ti.name_ptr = (unw_word_t) ""; + di->u.ti.segbase = 0; + di->u.ti.table_len = ((char *) etab - (char *) ktab) / sizeof (unw_word_t); + di->u.ti.table_data = (unw_word_t *) ktab; + + Debug (16, "found table `%s': [%lx-%lx) segbase=%lx len=%lu\n", + (char *) di->u.ti.name_ptr, di->start_ip, di->end_ip, + di->u.ti.segbase, di->u.ti.table_len); + return 0; +} + +# ifndef UNW_LOCAL_ONLY + +/* This is exported for the benefit of libunwind-ptrace.a. */ +PROTECTED int +_Uia64_get_kernel_table (unw_dyn_info_t *di) +{ + int ret; + + if (!kernel_table.u.ti.table_data) + if ((ret = get_kernel_table (&kernel_table)) < 0) + return ret; + + memcpy (di, &kernel_table, sizeof (*di)); + return 0; +} + +# endif /* !UNW_LOCAL_ONLY */ + +static inline unsigned long +current_gp (void) +{ +# if defined(__GNUC__) && !defined(__INTEL_COMPILER) + register unsigned long gp __asm__("gp"); + return gp; +# elif HAVE_IA64INTRIN_H + return __getReg (_IA64_REG_GP); +# else +# error Implement me. +# endif +} + +static int +callback (struct dl_phdr_info *info, size_t size, void *ptr) +{ + unw_dyn_info_t *di = ptr; + const Elf64_Phdr *phdr, *p_unwind, *p_dynamic, *p_text; + long n; + Elf64_Addr load_base, segbase = 0; + + /* Make sure struct dl_phdr_info is at least as big as we need. */ + if (size < offsetof (struct dl_phdr_info, dlpi_phnum) + + sizeof (info->dlpi_phnum)) + return -1; + + Debug (16, "checking `%s' (load_base=%lx)\n", + info->dlpi_name, info->dlpi_addr); + + phdr = info->dlpi_phdr; + load_base = info->dlpi_addr; + p_text = NULL; + p_unwind = NULL; + p_dynamic = NULL; + + /* See if PC falls into one of the loaded segments. Find the unwind + segment at the same time. */ + for (n = info->dlpi_phnum; --n >= 0; phdr++) + { + if (phdr->p_type == PT_LOAD) + { + Elf64_Addr vaddr = phdr->p_vaddr + load_base; + if (di->u.ti.segbase >= vaddr + && di->u.ti.segbase < vaddr + phdr->p_memsz) + p_text = phdr; + } + else if (phdr->p_type == PT_IA_64_UNWIND) + p_unwind = phdr; + else if (phdr->p_type == PT_DYNAMIC) + p_dynamic = phdr; + } + if (!p_text || !p_unwind) + return 0; + + if (likely (p_unwind->p_vaddr >= p_text->p_vaddr + && p_unwind->p_vaddr < p_text->p_vaddr + p_text->p_memsz)) + /* normal case: unwind table is inside text segment */ + segbase = p_text->p_vaddr + load_base; + else + { + /* Special case: unwind table is in some other segment; this + happens for the Linux kernel's gate DSO, for example. */ + phdr = info->dlpi_phdr; + for (n = info->dlpi_phnum; --n >= 0; phdr++) + { + if (phdr->p_type == PT_LOAD && p_unwind->p_vaddr >= phdr->p_vaddr + && p_unwind->p_vaddr < phdr->p_vaddr + phdr->p_memsz) + { + segbase = phdr->p_vaddr + load_base; + break; + } + } + } + + if (p_dynamic) + { + /* For dynamicly linked executables and shared libraries, + DT_PLTGOT is the gp value for that object. */ + Elf64_Dyn *dyn = (Elf64_Dyn *)(p_dynamic->p_vaddr + load_base); + for (; dyn->d_tag != DT_NULL; ++dyn) + if (dyn->d_tag == DT_PLTGOT) + { + /* On IA-64, _DYNAMIC is writable and GLIBC has relocated it. */ + di->gp = dyn->d_un.d_ptr; + break; + } + } + else + /* Otherwise this is a static executable with no _DYNAMIC. + The gp is constant program-wide. */ + di->gp = current_gp(); + di->format = UNW_INFO_FORMAT_TABLE; + di->start_ip = p_text->p_vaddr + load_base; + di->end_ip = p_text->p_vaddr + load_base + p_text->p_memsz; + di->u.ti.name_ptr = (unw_word_t) info->dlpi_name; + di->u.ti.table_data = (void *) (p_unwind->p_vaddr + load_base); + di->u.ti.table_len = p_unwind->p_memsz / sizeof (unw_word_t); + di->u.ti.segbase = segbase; + + Debug (16, "found table `%s': segbase=%lx, len=%lu, gp=%lx, " + "table_data=%p\n", (char *) di->u.ti.name_ptr, di->u.ti.segbase, + di->u.ti.table_len, di->gp, di->u.ti.table_data); + return 1; +} + +# ifdef HAVE_DL_PHDR_REMOVALS_COUNTER + +static inline int +validate_cache (unw_addr_space_t as) +{ + /* Note: we don't need to serialize here with respect to + dl_iterate_phdr() because if somebody were to remove an object + that is required to complete the unwind on whose behalf we're + validating the cache here, we'd be hosed anyhow. What we're + guarding against here is the case where library FOO gets mapped, + unwind info for FOO gets cached, FOO gets unmapped, BAR gets + mapped in the place where FOO was and then we unwind across a + function in FOO. Since no thread can execute in BAR before FOO + has been removed, we are guaranteed that + dl_phdr_removals_counter() would have been incremented before we + get here. */ + unsigned long long removals = dl_phdr_removals_counter (); + + if (removals == as->shared_object_removals) + return 1; + + as->shared_object_removals = removals; + unw_flush_cache (as, 0, 0); + return -1; +} + +# else /* !HAVE_DL_PHDR_REMOVALS_COUNTER */ + +/* Check whether any phdrs have been removed since we last flushed the + cache. If so we flush the cache and return -1, if not, we do + nothing and return 1. */ + +static int +check_callback (struct dl_phdr_info *info, size_t size, void *ptr) +{ +# ifdef HAVE_STRUCT_DL_PHDR_INFO_DLPI_SUBS + unw_addr_space_t as = ptr; + + if (size < + offsetof (struct dl_phdr_info, dlpi_subs) + sizeof (info->dlpi_subs)) + /* It would be safer to flush the cache here, but that would + disable caching for older libc's which would be incompatible + with the behavior of older versions of libunwind so we return 1 + instead and hope nobody runs into stale cache info... */ + return 1; + + if (info->dlpi_subs == as->shared_object_removals) + return 1; + + as->shared_object_removals = info->dlpi_subs; + unw_flush_cache (as, 0, 0); + return -1; /* indicate that there were removals */ +# else + return 1; +# endif +} + +static inline int +validate_cache (unw_addr_space_t as) +{ + intrmask_t saved_mask; + int ret; + + SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); + ret = dl_iterate_phdr (check_callback, as); + SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); + return ret; +} + +# endif /* HAVE_DL_PHDR_REMOVALS_COUNTER */ + +# elif defined(HAVE_DLMODINFO) + /* Support for HP-UX-style dlmodinfo() */ +# include + +static inline int +validate_cache (unw_addr_space_t as) +{ + return 1; +} + +# endif /* !HAVE_DLMODINFO */ + +HIDDEN int +tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, int need_unwind_info, void *arg) +{ +# if defined(HAVE_DL_ITERATE_PHDR) + unw_dyn_info_t di, *dip = &di; + intrmask_t saved_mask; + int ret; + + di.u.ti.segbase = ip; /* this is cheap... */ + + SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); + ret = dl_iterate_phdr (callback, &di); + SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); + + if (ret <= 0) + { + if (!kernel_table.u.ti.table_data) + { + if ((ret = get_kernel_table (&kernel_table)) < 0) + return ret; + } + if (ip < kernel_table.start_ip || ip >= kernel_table.end_ip) + return -UNW_ENOINFO; + dip = &kernel_table; + } +# elif defined(HAVE_DLMODINFO) +# define UNWIND_TBL_32BIT 0x8000000000000000 + struct load_module_desc lmd; + unw_dyn_info_t di, *dip = &di; + struct unwind_header + { + uint64_t header_version; + uint64_t start_offset; + uint64_t end_offset; + } + *uhdr; + + if (!dlmodinfo (ip, &lmd, sizeof (lmd), NULL, 0, 0)) + return -UNW_ENOINFO; + + di.format = UNW_INFO_FORMAT_TABLE; + di.start_ip = lmd.text_base; + di.end_ip = lmd.text_base + lmd.text_size; + di.gp = lmd.linkage_ptr; + di.u.ti.name_ptr = 0; /* no obvious table-name available */ + di.u.ti.segbase = lmd.text_base; + + uhdr = (struct unwind_header *) lmd.unwind_base; + + if ((uhdr->header_version & ~UNWIND_TBL_32BIT) != 1 + && (uhdr->header_version & ~UNWIND_TBL_32BIT) != 2) + { + Debug (1, "encountered unknown unwind header version %ld\n", + (long) (uhdr->header_version & ~UNWIND_TBL_32BIT)); + return -UNW_EBADVERSION; + } + if (uhdr->header_version & UNWIND_TBL_32BIT) + { + Debug (1, "32-bit unwind tables are not supported yet\n"); + return -UNW_EINVAL; + } + + di.u.ti.table_data = (unw_word_t *) (di.u.ti.segbase + uhdr->start_offset); + di.u.ti.table_len = ((uhdr->end_offset - uhdr->start_offset) + / sizeof (unw_word_t)); + + Debug (16, "found table `%s': segbase=%lx, len=%lu, gp=%lx, " + "table_data=%p\n", (char *) di.u.ti.name_ptr, di.u.ti.segbase, + di.u.ti.table_len, di.gp, di.u.ti.table_data); +# endif + + /* now search the table: */ + return tdep_search_unwind_table (as, ip, dip, pi, need_unwind_info, arg); +} + +/* Returns 1 if the cache is up-to-date or -1 if the cache contained + stale data and had to be flushed. */ + +HIDDEN int +ia64_local_validate_cache (unw_addr_space_t as, void *arg) +{ + return validate_cache (as); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/ia64/Lcreate_addr_space.c b/src/libs/libunwind/ia64/Lcreate_addr_space.c new file mode 100644 index 0000000000..0f2dc6be90 --- /dev/null +++ b/src/libs/libunwind/ia64/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/libs/libunwind/ia64/Lfind_unwind_table.c b/src/libs/libunwind/ia64/Lfind_unwind_table.c new file mode 100644 index 0000000000..68e269f1d7 --- /dev/null +++ b/src/libs/libunwind/ia64/Lfind_unwind_table.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gfind_unwind_table.c" +#endif diff --git a/src/libs/libunwind/ia64/Lget_proc_info.c b/src/libs/libunwind/ia64/Lget_proc_info.c new file mode 100644 index 0000000000..69028b019f --- /dev/null +++ b/src/libs/libunwind/ia64/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/libs/libunwind/ia64/Lget_save_loc.c b/src/libs/libunwind/ia64/Lget_save_loc.c new file mode 100644 index 0000000000..9ea048a907 --- /dev/null +++ b/src/libs/libunwind/ia64/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/libs/libunwind/ia64/Lglobal.c b/src/libs/libunwind/ia64/Lglobal.c new file mode 100644 index 0000000000..6d7b489e14 --- /dev/null +++ b/src/libs/libunwind/ia64/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/libs/libunwind/ia64/Linit.c b/src/libs/libunwind/ia64/Linit.c new file mode 100644 index 0000000000..e9abfdd46a --- /dev/null +++ b/src/libs/libunwind/ia64/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/libs/libunwind/ia64/Linit_local.c b/src/libs/libunwind/ia64/Linit_local.c new file mode 100644 index 0000000000..68a1687e85 --- /dev/null +++ b/src/libs/libunwind/ia64/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/libs/libunwind/ia64/Linit_remote.c b/src/libs/libunwind/ia64/Linit_remote.c new file mode 100644 index 0000000000..58cb04ab7c --- /dev/null +++ b/src/libs/libunwind/ia64/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/libs/libunwind/ia64/Linstall_cursor.S b/src/libs/libunwind/ia64/Linstall_cursor.S new file mode 100644 index 0000000000..8c72339725 --- /dev/null +++ b/src/libs/libunwind/ia64/Linstall_cursor.S @@ -0,0 +1,6 @@ +#define UNW_LOCAL_ONLY +#include "Ginstall_cursor.S" +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/ia64/Lis_signal_frame.c b/src/libs/libunwind/ia64/Lis_signal_frame.c new file mode 100644 index 0000000000..b9a7c4f51a --- /dev/null +++ b/src/libs/libunwind/ia64/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/libs/libunwind/ia64/Lparser.c b/src/libs/libunwind/ia64/Lparser.c new file mode 100644 index 0000000000..f23aaf48e9 --- /dev/null +++ b/src/libs/libunwind/ia64/Lparser.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gparser.c" +#endif diff --git a/src/libs/libunwind/ia64/Lrbs.c b/src/libs/libunwind/ia64/Lrbs.c new file mode 100644 index 0000000000..a91b5f2979 --- /dev/null +++ b/src/libs/libunwind/ia64/Lrbs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Grbs.c" +#endif diff --git a/src/libs/libunwind/ia64/Lregs.c b/src/libs/libunwind/ia64/Lregs.c new file mode 100644 index 0000000000..2c9c75cd7d --- /dev/null +++ b/src/libs/libunwind/ia64/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/libs/libunwind/ia64/Lresume.c b/src/libs/libunwind/ia64/Lresume.c new file mode 100644 index 0000000000..41a8cf003d --- /dev/null +++ b/src/libs/libunwind/ia64/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/libs/libunwind/ia64/Lscript.c b/src/libs/libunwind/ia64/Lscript.c new file mode 100644 index 0000000000..57b926bf80 --- /dev/null +++ b/src/libs/libunwind/ia64/Lscript.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gscript.c" +#endif diff --git a/src/libs/libunwind/ia64/Lstep.c b/src/libs/libunwind/ia64/Lstep.c new file mode 100644 index 0000000000..c1ac3c7547 --- /dev/null +++ b/src/libs/libunwind/ia64/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/libs/libunwind/ia64/Ltables.c b/src/libs/libunwind/ia64/Ltables.c new file mode 100644 index 0000000000..876b0aac03 --- /dev/null +++ b/src/libs/libunwind/ia64/Ltables.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gtables.c" +#endif diff --git a/src/libs/libunwind/ia64/NOTES b/src/libs/libunwind/ia64/NOTES new file mode 100644 index 0000000000..a5805e8345 --- /dev/null +++ b/src/libs/libunwind/ia64/NOTES @@ -0,0 +1,65 @@ +- the frame state consists of the following: + + - ip current instruction pointer + - sp current stack pointer value + - bsp current backing store pointer + - cfm current frame mask + + these are derived from the next younger (more deeply nested) frame + as follows: + + - ip == saved return-link (may be b0 or an alternate branch-reg) + - sp == if younger frame has a fixed-sized frame, sp + size-of-frame, + else saved sp + - cfm == saved ar.pfs + - bsp == if ar.bsp has been saved, saved ar.bsp, otherwise, + ar.bsp \ominus saved ar.pfs.pfm.sol + +The unwind cursor should represent the machine state as it existed at +the address contained in register ip. This state consists of the +*current* frame state and the save locations in the next younger +frame. + +An unwind script current takes the old save locations and updates them +for the next older frame. With the new setup, we need to update the +frame state first, without updating the other save locations. For this +to work, we need the following info: + + - save location of return-link + - save location of ar.pfs + - save location of bsp (if it has been saved) + - size of stack frame (fixed case) or save location of sp + + +setup: + + func: ... + ... + ... + br.call foo <-- call site + ... <-- ip + ... + +initial state: + + The unwind cursor represents the (preserved) machine state + as it existed at "ip". + + Evaluating the unwind descriptors for "ip" yields the following + info: + + - frame size at call site (or previous sp) + - what registers where saved where by func before + the call site was reached + + + Note that there is some procedure info that needs to be obtained + for the new "ip" which is contained in the unwind descriptors. + Specifically, the following is needed: + + - procedure's start address + - personality address + - pointer to language-specific data area + + This info is stored in a separate proc_info structure and needs + to be obtained right after running the unwind script for func. diff --git a/src/libs/libunwind/ia64/dyn_info_list.S b/src/libs/libunwind/ia64/dyn_info_list.S new file mode 100644 index 0000000000..31265f66a0 --- /dev/null +++ b/src/libs/libunwind/ia64/dyn_info_list.S @@ -0,0 +1,26 @@ +#ifndef UNW_REMOTE_ONLY + +/* + * Create a special unwind-table entry which makes it easy for an + * unwinder to locate the dynamic registration list. The special + * entry covers address range [0-0) and is therefore guaranteed to be + * the first in the unwind-table. + */ + .global _U_dyn_info_list + .hidden _U_dyn_info_list + + .section .IA_64.unwind_info,"a","progbits" +.info: data8 (1<<48) | 1 /* v1, length==1 (8-byte word) */ + data8 0 /* 8 empty .prologue directives (nops) */ + data8 0 /* personality routine (ignored) */ + string "dyn-list" /* lsda */ + data8 @gprel(_U_dyn_info_list) + + .section .IA_64.unwind, "a", "progbits" + data8 0, 0, @segrel(.info) + +#endif +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/ia64/getcontext.S b/src/libs/libunwind/ia64/getcontext.S new file mode 100644 index 0000000000..d8da732acc --- /dev/null +++ b/src/libs/libunwind/ia64/getcontext.S @@ -0,0 +1,177 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "ucontext_i.h" + +#define GR(n) (SC_GR + (n)*8) +#define BR(n) (SC_BR + (n)*8) +#define FR(n) (SC_FR + (n)*16) + +/* This should be compatible to the libc's getcontext(), except that + the sc->sc_mask field is always cleared and that the name is + prefixed with _Uia64_ so we don't step on the application's + name-space. */ + + .align 32 + .protected _Uia64_getcontext + .global _Uia64_getcontext + .proc _Uia64_getcontext +_Uia64_getcontext: + .prologue + alloc rPFS = ar.pfs, 1, 0, 0, 0 // M2 + mov rPR = pr // I0, 2 cycles + add r2 = GR(1), in0 // I1 + ;; + + .save ar.unat, rUNAT + mov.m rUNAT = ar.unat // M2, 5 cycles + .body + st8.spill [r2] = r1, (SC_FLAGS - GR(1)) // M3 + dep.z rFLAGS = -1, IA64_SC_FLAG_SYNCHRONOUS_BIT, 1 // I0, 1 cycle + ;; + + mov.m rRSC = ar.rsc // M2, 12 cyc. + st8 [r2] = rFLAGS, (SC_PR - SC_FLAGS) // M3 + add r3 = FR(2), in0 + ;; + + mov.m rBSP = ar.bsp // M2, 12 cyc. + st8 [r2] = rPR, (GR(12) - SC_PR) // M3 + add r8 = FR(16), in0 + ;; + + mov.m rFPSR = ar.fpsr // M2, 12 cyc. + st8.spill [r2] = r12, (GR(4) - GR(12)) // M3 + add r9 = FR(24), in0 + ;; + + stf.spill [r3] = f2 // M2 + stf.spill [r8] = f16 // M3 + add r3 = GR(7), in0 + ;; + + flushrs // M0 + stf.spill [r9] = f24, (FR(31) - FR(24)) // M2 + mov rB0 = b0 // I0, 2 cycles + ;; + + stf.spill [r9] = f31 // M2 + st8.spill [r2] = r4, (GR(5) - GR(4)) // M3, bank 1 + mov rB1 = b1 // I0, 2 cycles + ;; + +.mem.offset 0,0; st8.spill [r2] = r5, (GR(6) - GR(5)) // M4, bank 0 +.mem.offset 8,0; st8.spill [r3] = r7, (BR(0) - GR(7)) // M3, bank 0 + mov rB2 = b2 // I0, 2 cycles + ;; + + st8.spill [r2] = r6, (BR(1) - GR(6)) // M2, bank 1 + st8 [r3] = rB0, (BR(4) - BR(0)) // M3, bank 1 + mov rB4 = b4 // I0, 2 cycles + ;; + + mov.m rNAT = ar.unat // M2, 5 cycles + st8 [r2] = rB1, (BR(2) - BR(1)) // M3, bank 0 + mov rB3 = b3 + ;; + + st8 [r2] = rB2, (BR(3) - BR(2)) // M2, bank 1 + st8 [r3] = rB4, (SC_LC - BR(4)) // M3, bank 1 + mov rB5 = b5 // I0, 2 cycles + ;; + + and rTMP = ~0x3, rRSC // M0 + add rPOS = GR(0), in0 // rPOS <- &sc_gr[0] // M1 + mov.i rLC = ar.lc // I0, 2 cycles + ;; + + mov.m ar.rsc = rTMP // put RSE into lazy mode // M2, ? cycles + st8 [r2] = rB3, (BR(5) - BR(3)) // M3, bank 0 + extr.u rPOS = rPOS, 3, 6 // get NaT bitnr for r0 // I0 + ;; + + mov.m rRNAT = ar.rnat // M2, 5 cycles + st8 [r2] = rB5, (SC_PFS - BR(5)) // M3, bank 0 + sub rCPOS = 64, rPOS // I0 + ;; + + st8 [r2] = rPFS, (SC_UNAT - SC_PFS) // M2 + st8 [r3] = rLC, (SC_BSP - SC_LC) // M3 + shr.u rTMP = rNAT, rPOS // I0, 3 cycles + ;; + + st8 [r2] = rUNAT, (SC_FPSR - SC_UNAT) // M2 + st8 [r3] = rBSP // M3 + add r8 = FR(3), in0 + ;; + + st8 [r2] = rFPSR, (SC_RNAT - SC_FPSR) // M2 + stf.spill [r8] = f3, (FR(4) - FR(3)) // M3 + add r9 = FR(5), in0 + ;; + + stf.spill [r8] = f4, (FR(17) - FR(4)) // M2 + stf.spill [r9] = f5, (FR(19) - FR(5)) // M3 + shl rNAT = rNAT, rCPOS // I0, 3 cycles + ;; + + st8 [r2] = rRNAT, (SC_NAT - SC_RNAT) // M2 + stf.spill [r8] = f17, (FR(18) - FR(17)) // M3 + nop.i 0 + ;; + + stf.spill [r8] = f18, (FR(20) - FR(18)) // M2 + stf.spill [r9] = f19, (FR(21) - FR(19)) // M3 + nop.i 0 + ;; + + stf.spill [r8] = f20, (FR(22) - FR(20)) // M2 + stf.spill [r9] = f21, (FR(23) - FR(21)) // M3 + or rNAT = rNAT, rTMP // I0 + ;; + + st8 [r2] = rNAT // M2 + stf.spill [r8] = f22, (FR(25) - FR(22)) // M3 + ;; + stf.spill [r9] = f23, (FR(26) - FR(23)) // M2 + stf.spill [r8] = f25, (FR(27) - FR(25)) // M3 + ;; + stf.spill [r9] = f26, (FR(28) - FR(26)) // M2 + stf.spill [r8] = f27, (FR(29) - FR(27)) // M3 + ;; + mov.m ar.rsc = rRSC // restore RSE mode // M2 + stf.spill [r9] = f28, (FR(30) - FR(28)) // M3 + ;; + mov.m ar.unat = rUNAT // restore caller's UNaT // M2 + stf.spill [r8] = f29 // M3 + ;; + stf.spill [r9] = f30 // M2 + mov r8 = 0 + br.ret.sptk.many rp + .endp _Uia64_getcontext +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/ia64/init.h b/src/libs/libunwind/ia64/init.h new file mode 100644 index 0000000000..6628a1d888 --- /dev/null +++ b/src/libs/libunwind/ia64/init.h @@ -0,0 +1,132 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static ALWAYS_INLINE int +common_init (struct cursor *c, unw_word_t sp, unw_word_t bsp) +{ + unw_word_t bspstore, rbs_base; + int ret; + + if (c->as->caching_policy != UNW_CACHE_NONE) + /* ensure cache doesn't have any stale contents: */ + ia64_validate_cache (c->as, c->as_arg); + + c->cfm_loc = IA64_REG_LOC (c, UNW_IA64_CFM); + c->loc[IA64_REG_BSP] = IA64_NULL_LOC; + c->loc[IA64_REG_BSPSTORE] = IA64_REG_LOC (c, UNW_IA64_AR_BSPSTORE); + c->loc[IA64_REG_PFS] = IA64_REG_LOC (c, UNW_IA64_AR_PFS); + c->loc[IA64_REG_RNAT] = IA64_REG_LOC (c, UNW_IA64_AR_RNAT); + c->loc[IA64_REG_IP] = IA64_REG_LOC (c, UNW_IA64_IP); + c->loc[IA64_REG_PRI_UNAT_MEM] = IA64_NULL_LOC; /* no primary UNaT location */ + c->loc[IA64_REG_UNAT] = IA64_REG_LOC (c, UNW_IA64_AR_UNAT); + c->loc[IA64_REG_PR] = IA64_REG_LOC (c, UNW_IA64_PR); + c->loc[IA64_REG_LC] = IA64_REG_LOC (c, UNW_IA64_AR_LC); + c->loc[IA64_REG_FPSR] = IA64_REG_LOC (c, UNW_IA64_AR_FPSR); + + c->loc[IA64_REG_R4] = IA64_REG_LOC (c, UNW_IA64_GR + 4); + c->loc[IA64_REG_R5] = IA64_REG_LOC (c, UNW_IA64_GR + 5); + c->loc[IA64_REG_R6] = IA64_REG_LOC (c, UNW_IA64_GR + 6); + c->loc[IA64_REG_R7] = IA64_REG_LOC (c, UNW_IA64_GR + 7); + + c->loc[IA64_REG_NAT4] = IA64_REG_NAT_LOC (c, UNW_IA64_NAT + 4, &c->nat_bitnr[0]); + c->loc[IA64_REG_NAT5] = IA64_REG_NAT_LOC (c, UNW_IA64_NAT + 5, &c->nat_bitnr[1]); + c->loc[IA64_REG_NAT6] = IA64_REG_NAT_LOC (c, UNW_IA64_NAT + 6, &c->nat_bitnr[2]); + c->loc[IA64_REG_NAT7] = IA64_REG_NAT_LOC (c, UNW_IA64_NAT + 7, &c->nat_bitnr[3]); + + c->loc[IA64_REG_B1] = IA64_REG_LOC (c, UNW_IA64_BR + 1); + c->loc[IA64_REG_B2] = IA64_REG_LOC (c, UNW_IA64_BR + 2); + c->loc[IA64_REG_B3] = IA64_REG_LOC (c, UNW_IA64_BR + 3); + c->loc[IA64_REG_B4] = IA64_REG_LOC (c, UNW_IA64_BR + 4); + c->loc[IA64_REG_B5] = IA64_REG_LOC (c, UNW_IA64_BR + 5); + + c->loc[IA64_REG_F2] = IA64_FPREG_LOC (c, UNW_IA64_FR + 2); + c->loc[IA64_REG_F3] = IA64_FPREG_LOC (c, UNW_IA64_FR + 3); + c->loc[IA64_REG_F4] = IA64_FPREG_LOC (c, UNW_IA64_FR + 4); + c->loc[IA64_REG_F5] = IA64_FPREG_LOC (c, UNW_IA64_FR + 5); + c->loc[IA64_REG_F16] = IA64_FPREG_LOC (c, UNW_IA64_FR + 16); + c->loc[IA64_REG_F17] = IA64_FPREG_LOC (c, UNW_IA64_FR + 17); + c->loc[IA64_REG_F18] = IA64_FPREG_LOC (c, UNW_IA64_FR + 18); + c->loc[IA64_REG_F19] = IA64_FPREG_LOC (c, UNW_IA64_FR + 19); + c->loc[IA64_REG_F20] = IA64_FPREG_LOC (c, UNW_IA64_FR + 20); + c->loc[IA64_REG_F21] = IA64_FPREG_LOC (c, UNW_IA64_FR + 21); + c->loc[IA64_REG_F22] = IA64_FPREG_LOC (c, UNW_IA64_FR + 22); + c->loc[IA64_REG_F23] = IA64_FPREG_LOC (c, UNW_IA64_FR + 23); + c->loc[IA64_REG_F24] = IA64_FPREG_LOC (c, UNW_IA64_FR + 24); + c->loc[IA64_REG_F25] = IA64_FPREG_LOC (c, UNW_IA64_FR + 25); + c->loc[IA64_REG_F26] = IA64_FPREG_LOC (c, UNW_IA64_FR + 26); + c->loc[IA64_REG_F27] = IA64_FPREG_LOC (c, UNW_IA64_FR + 27); + c->loc[IA64_REG_F28] = IA64_FPREG_LOC (c, UNW_IA64_FR + 28); + c->loc[IA64_REG_F29] = IA64_FPREG_LOC (c, UNW_IA64_FR + 29); + c->loc[IA64_REG_F30] = IA64_FPREG_LOC (c, UNW_IA64_FR + 30); + c->loc[IA64_REG_F31] = IA64_FPREG_LOC (c, UNW_IA64_FR + 31); + + ret = ia64_get (c, c->loc[IA64_REG_IP], &c->ip); + if (ret < 0) + return ret; + + ret = ia64_get (c, c->cfm_loc, &c->cfm); + if (ret < 0) + return ret; + + ret = ia64_get (c, c->loc[IA64_REG_PR], &c->pr); + if (ret < 0) + return ret; + + c->sp = c->psp = sp; + c->bsp = bsp; + + ret = ia64_get (c, c->loc[IA64_REG_BSPSTORE], &bspstore); + if (ret < 0) + return ret; + + c->rbs_curr = c->rbs_left_edge = 0; + + /* Try to find a base of the register backing-store. We may default + to a reasonable value (e.g., half the address-space down from + bspstore). If the BSPSTORE looks corrupt, we fail. */ + if ((ret = rbs_get_base (c, bspstore, &rbs_base)) < 0) + return ret; + + c->rbs_area[0].end = bspstore; + c->rbs_area[0].size = bspstore - rbs_base; + c->rbs_area[0].rnat_loc = IA64_REG_LOC (c, UNW_IA64_AR_RNAT); + Debug (10, "initial rbs-area: [0x%llx-0x%llx), rnat@%s\n", + (long long) rbs_base, (long long) c->rbs_area[0].end, + ia64_strloc (c->rbs_area[0].rnat_loc)); + + c->pi.flags = 0; + + c->sigcontext_addr = 0; + c->abi_marker = 0; + c->last_abi_marker = 0; + + c->hint = 0; + c->prev_script = 0; + c->eh_valid_mask = 0; + c->pi_valid = 0; + return 0; +} diff --git a/src/libs/libunwind/ia64/longjmp.S b/src/libs/libunwind/ia64/longjmp.S new file mode 100644 index 0000000000..2a2f286594 --- /dev/null +++ b/src/libs/libunwind/ia64/longjmp.S @@ -0,0 +1,42 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + .global _UI_longjmp_cont + + .align 32 + .proc longjmp_continuation +longjmp_continuation: +_UI_longjmp_cont: // non-function label for {sig,}longjmp.c + .prologue + .save rp, r15 + .body + mov rp = r15 + mov r8 = r16 + br.sptk.many rp + .endp longjmp_continuation +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/ia64/mk_Gcursor_i.c b/src/libs/libunwind/ia64/mk_Gcursor_i.c new file mode 100644 index 0000000000..67b14d52ba --- /dev/null +++ b/src/libs/libunwind/ia64/mk_Gcursor_i.c @@ -0,0 +1,65 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Utility to generate cursor_i.h. */ + +#include "libunwind_i.h" + +#ifdef offsetof +# undef offsetof +#endif + +#define offsetof(type,field) ((char *) &((type *) 0)->field - (char *) 0) + +#define OFFSET(sym, offset) \ + asm volatile("\n->" #sym " %0" : : "i" (offset)) + +int +main (void) +{ + OFFSET("IP_OFF", offsetof (struct cursor, ip)); + OFFSET("PR_OFF", offsetof (struct cursor, pr)); + OFFSET("BSP_OFF", offsetof (struct cursor, bsp)); + OFFSET("PSP_OFF", offsetof (struct cursor, psp)); + OFFSET("PFS_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_PFS])); + OFFSET("RNAT_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_RNAT])); + OFFSET("UNAT_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_UNAT])); + OFFSET("LC_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_LC])); + OFFSET("FPSR_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_FPSR])); + OFFSET("B1_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_B1])); + OFFSET("B2_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_B2])); + OFFSET("B3_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_B3])); + OFFSET("B4_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_B4])); + OFFSET("B5_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_B5])); + OFFSET("F2_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_F2])); + OFFSET("F3_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_F3])); + OFFSET("F4_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_F4])); + OFFSET("F5_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_F5])); + OFFSET("FR_LOC_OFF", offsetof (struct cursor, loc[IA64_REG_F16])); + OFFSET("LOC_SIZE", + (offsetof (struct cursor, loc[1]) - offsetof (struct cursor, loc[0]))); + OFFSET("SIGCONTEXT_ADDR_OFF", offsetof (struct cursor, sigcontext_addr)); + return 0; +} diff --git a/src/libs/libunwind/ia64/mk_Lcursor_i.c b/src/libs/libunwind/ia64/mk_Lcursor_i.c new file mode 100644 index 0000000000..aee2e7eeb8 --- /dev/null +++ b/src/libs/libunwind/ia64/mk_Lcursor_i.c @@ -0,0 +1,2 @@ +#define UNW_LOCAL_ONLY +#include "mk_Gcursor_i.c" diff --git a/src/libs/libunwind/ia64/mk_cursor_i b/src/libs/libunwind/ia64/mk_cursor_i new file mode 100755 index 0000000000..9211f91bbb --- /dev/null +++ b/src/libs/libunwind/ia64/mk_cursor_i @@ -0,0 +1,7 @@ +#!/bin/sh +test -z "$1" && exit 1 +echo "/* GENERATED */" +echo "#ifndef cursor_i_h" +echo "#define cursor_i_h" +sed -ne 's/^->"\(\S*\)" \(\d*\)/#define \1 \2/p' < $1 || exit $? +echo "#endif" diff --git a/src/libs/libunwind/ia64/offsets.h b/src/libs/libunwind/ia64/offsets.h new file mode 100644 index 0000000000..5ab7f8b31e --- /dev/null +++ b/src/libs/libunwind/ia64/offsets.h @@ -0,0 +1,137 @@ +/* Linux-specific definitions: */ + +/* Define various structure offsets to simplify cross-compilation. */ + +/* The first three 64-bit words in a signal frame contain the signal + number, siginfo pointer, and sigcontext pointer passed to the + signal handler. We use this to locate the sigcontext pointer. */ + +#define LINUX_SIGFRAME_ARG2_OFF 0x10 + +#define LINUX_SC_FLAGS_OFF 0x000 +#define LINUX_SC_NAT_OFF 0x008 +#define LINUX_SC_STACK_OFF 0x010 +#define LINUX_SC_IP_OFF 0x028 +#define LINUX_SC_CFM_OFF 0x030 +#define LINUX_SC_UM_OFF 0x038 +#define LINUX_SC_AR_RSC_OFF 0x040 +#define LINUX_SC_AR_BSP_OFF 0x048 +#define LINUX_SC_AR_RNAT_OFF 0x050 +#define LINUX_SC_AR_CCV 0x058 +#define LINUX_SC_AR_UNAT_OFF 0x060 +#define LINUX_SC_AR_FPSR_OFF 0x068 +#define LINUX_SC_AR_PFS_OFF 0x070 +#define LINUX_SC_AR_LC_OFF 0x078 +#define LINUX_SC_PR_OFF 0x080 +#define LINUX_SC_BR_OFF 0x088 +#define LINUX_SC_GR_OFF 0x0c8 +#define LINUX_SC_FR_OFF 0x1d0 +#define LINUX_SC_RBS_BASE_OFF 0x9d0 +#define LINUX_SC_LOADRS_OFF 0x9d8 +#define LINUX_SC_AR_CSD_OFF 0x9e0 +#define LINUX_SC_AR_SSD_OFF 0x9e8 +#define LINUX_SC_MASK 0xa50 + +/* Layout of old Linux kernel interrupt frame (struct pt_regs). */ + +#define LINUX_OLD_PT_IPSR_OFF 0x000 +#define LINUX_OLD_PT_IIP_OFF 0x008 +#define LINUX_OLD_PT_IFS_OFF 0x010 +#define LINUX_OLD_PT_UNAT_OFF 0x018 +#define LINUX_OLD_PT_PFS_OFF 0x020 +#define LINUX_OLD_PT_RSC_OFF 0x028 +#define LINUX_OLD_PT_RNAT_OFF 0x030 +#define LINUX_OLD_PT_BSPSTORE_OFF 0x038 +#define LINUX_OLD_PT_PR_OFF 0x040 +#define LINUX_OLD_PT_B6_OFF 0x048 +#define LINUX_OLD_PT_LOADRS_OFF 0x050 +#define LINUX_OLD_PT_R1_OFF 0x058 +#define LINUX_OLD_PT_R2_OFF 0x060 +#define LINUX_OLD_PT_R3_OFF 0x068 +#define LINUX_OLD_PT_R12_OFF 0x070 +#define LINUX_OLD_PT_R13_OFF 0x078 +#define LINUX_OLD_PT_R14_OFF 0x080 +#define LINUX_OLD_PT_R15_OFF 0x088 +#define LINUX_OLD_PT_R8_OFF 0x090 +#define LINUX_OLD_PT_R9_OFF 0x098 +#define LINUX_OLD_PT_R10_OFF 0x0a0 +#define LINUX_OLD_PT_R11_OFF 0x0a8 +#define LINUX_OLD_PT_R16_OFF 0x0b0 +#define LINUX_OLD_PT_R17_OFF 0x0b8 +#define LINUX_OLD_PT_R18_OFF 0x0c0 +#define LINUX_OLD_PT_R19_OFF 0x0c8 +#define LINUX_OLD_PT_R20_OFF 0x0d0 +#define LINUX_OLD_PT_R21_OFF 0x0d8 +#define LINUX_OLD_PT_R22_OFF 0x0e0 +#define LINUX_OLD_PT_R23_OFF 0x0e8 +#define LINUX_OLD_PT_R24_OFF 0x0f0 +#define LINUX_OLD_PT_R25_OFF 0x0f8 +#define LINUX_OLD_PT_R26_OFF 0x100 +#define LINUX_OLD_PT_R27_OFF 0x108 +#define LINUX_OLD_PT_R28_OFF 0x110 +#define LINUX_OLD_PT_R29_OFF 0x118 +#define LINUX_OLD_PT_R30_OFF 0x120 +#define LINUX_OLD_PT_R31_OFF 0x128 +#define LINUX_OLD_PT_CCV_OFF 0x130 +#define LINUX_OLD_PT_FPSR_OFF 0x138 +#define LINUX_OLD_PT_B0_OFF 0x140 +#define LINUX_OLD_PT_B7_OFF 0x148 +#define LINUX_OLD_PT_F6_OFF 0x150 +#define LINUX_OLD_PT_F7_OFF 0x160 +#define LINUX_OLD_PT_F8_OFF 0x170 +#define LINUX_OLD_PT_F9_OFF 0x180 + +/* Layout of new Linux kernel interrupt frame (struct pt_regs). */ + +#define LINUX_PT_B6_OFF 0 +#define LINUX_PT_B7_OFF 8 +#define LINUX_PT_CSD_OFF 16 +#define LINUX_PT_SSD_OFF 24 +#define LINUX_PT_R8_OFF 32 +#define LINUX_PT_R9_OFF 40 +#define LINUX_PT_R10_OFF 48 +#define LINUX_PT_R11_OFF 56 +#define LINUX_PT_IPSR_OFF 64 +#define LINUX_PT_IIP_OFF 72 +#define LINUX_PT_IFS_OFF 80 +#define LINUX_PT_UNAT_OFF 88 +#define LINUX_PT_PFS_OFF 96 +#define LINUX_PT_RSC_OFF 104 +#define LINUX_PT_RNAT_OFF 112 +#define LINUX_PT_BSPSTORE_OFF 120 +#define LINUX_PT_PR_OFF 128 +#define LINUX_PT_B0_OFF 136 +#define LINUX_PT_LOADRS_OFF 144 +#define LINUX_PT_R1_OFF 152 +#define LINUX_PT_R12_OFF 160 +#define LINUX_PT_R13_OFF 168 +#define LINUX_PT_FPSR_OFF 176 +#define LINUX_PT_R15_OFF 184 +#define LINUX_PT_R14_OFF 192 +#define LINUX_PT_R2_OFF 200 +#define LINUX_PT_R3_OFF 208 +#define LINUX_PT_R16_OFF 216 +#define LINUX_PT_R17_OFF 224 +#define LINUX_PT_R18_OFF 232 +#define LINUX_PT_R19_OFF 240 +#define LINUX_PT_R20_OFF 248 +#define LINUX_PT_R21_OFF 256 +#define LINUX_PT_R22_OFF 264 +#define LINUX_PT_R23_OFF 272 +#define LINUX_PT_R24_OFF 280 +#define LINUX_PT_R25_OFF 288 +#define LINUX_PT_R26_OFF 296 +#define LINUX_PT_R27_OFF 304 +#define LINUX_PT_R28_OFF 312 +#define LINUX_PT_R29_OFF 320 +#define LINUX_PT_R30_OFF 328 +#define LINUX_PT_R31_OFF 336 +#define LINUX_PT_CCV_OFF 344 +#define LINUX_PT_F6_OFF 352 +#define LINUX_PT_F7_OFF 368 +#define LINUX_PT_F8_OFF 384 +#define LINUX_PT_F9_OFF 400 +#define LINUX_PT_F10_OFF 416 +#define LINUX_PT_F11_OFF 432 + +#define LINUX_PT_P_NONSYS 5 /* must match pNonSys in entry.h */ diff --git a/src/libs/libunwind/ia64/regname.c b/src/libs/libunwind/ia64/regname.c new file mode 100644 index 0000000000..8753e5208e --- /dev/null +++ b/src/libs/libunwind/ia64/regname.c @@ -0,0 +1,189 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Logically, we like to think of the stack as a contiguous region of +memory. Unfortunately, this logical view doesn't work for the +register backing store, because the RSE is an asynchronous engine and +because UNIX/Linux allow for stack-switching via sigaltstack(2). +Specifically, this means that any given stacked register may or may +not be backed up by memory in the current stack. If not, then the +backing memory may be found in any of the "more inner" (younger) +stacks. The routines in this file help manage the discontiguous +nature of the register backing store. The routines are completely +independent of UNIX/Linux, but each stack frame that switches the +backing store is expected to reserve 4 words for use by libunwind. For +example, in the Linux sigcontext, sc_fr[0] and sc_fr[1] serve this +purpose. */ + +#include "libunwind_i.h" + +/* Maintain the register names as a single string to keep the number + of dynamic relocations in the shared object to a minimum. */ + +#define regname_len 9 +#define regname_str \ + "r0\0\0\0\0\0\0\0r1\0\0\0\0\0\0\0r2\0\0\0\0\0\0\0r3\0\0\0\0\0\0\0" \ + "r4\0\0\0\0\0\0\0r5\0\0\0\0\0\0\0r6\0\0\0\0\0\0\0r7\0\0\0\0\0\0\0" \ + "r8\0\0\0\0\0\0\0r9\0\0\0\0\0\0\0r10\0\0\0\0\0\0r11\0\0\0\0\0\0" \ + "r12\0\0\0\0\0\0r13\0\0\0\0\0\0r14\0\0\0\0\0\0r15\0\0\0\0\0\0" \ + "r16\0\0\0\0\0\0r17\0\0\0\0\0\0r18\0\0\0\0\0\0r19\0\0\0\0\0\0" \ + "r20\0\0\0\0\0\0r21\0\0\0\0\0\0r22\0\0\0\0\0\0r23\0\0\0\0\0\0" \ + "r24\0\0\0\0\0\0r25\0\0\0\0\0\0r26\0\0\0\0\0\0r27\0\0\0\0\0\0" \ + "r28\0\0\0\0\0\0r29\0\0\0\0\0\0r30\0\0\0\0\0\0r31\0\0\0\0\0\0" \ + "r32\0\0\0\0\0\0r33\0\0\0\0\0\0r34\0\0\0\0\0\0r35\0\0\0\0\0\0" \ + "r36\0\0\0\0\0\0r37\0\0\0\0\0\0r38\0\0\0\0\0\0r39\0\0\0\0\0\0" \ + "r40\0\0\0\0\0\0r41\0\0\0\0\0\0r42\0\0\0\0\0\0r43\0\0\0\0\0\0" \ + "r44\0\0\0\0\0\0r45\0\0\0\0\0\0r46\0\0\0\0\0\0r47\0\0\0\0\0\0" \ + "r48\0\0\0\0\0\0r49\0\0\0\0\0\0r50\0\0\0\0\0\0r51\0\0\0\0\0\0" \ + "r52\0\0\0\0\0\0r53\0\0\0\0\0\0r54\0\0\0\0\0\0r55\0\0\0\0\0\0" \ + "r56\0\0\0\0\0\0r57\0\0\0\0\0\0r58\0\0\0\0\0\0r59\0\0\0\0\0\0" \ + "r60\0\0\0\0\0\0r61\0\0\0\0\0\0r62\0\0\0\0\0\0r63\0\0\0\0\0\0" \ + "r64\0\0\0\0\0\0r65\0\0\0\0\0\0r66\0\0\0\0\0\0r67\0\0\0\0\0\0" \ + "r68\0\0\0\0\0\0r69\0\0\0\0\0\0r70\0\0\0\0\0\0r71\0\0\0\0\0\0" \ + "r72\0\0\0\0\0\0r73\0\0\0\0\0\0r74\0\0\0\0\0\0r75\0\0\0\0\0\0" \ + "r76\0\0\0\0\0\0r77\0\0\0\0\0\0r78\0\0\0\0\0\0r79\0\0\0\0\0\0" \ + "r80\0\0\0\0\0\0r81\0\0\0\0\0\0r82\0\0\0\0\0\0r83\0\0\0\0\0\0" \ + "r84\0\0\0\0\0\0r85\0\0\0\0\0\0r86\0\0\0\0\0\0r87\0\0\0\0\0\0" \ + "r88\0\0\0\0\0\0r89\0\0\0\0\0\0r90\0\0\0\0\0\0r91\0\0\0\0\0\0" \ + "r92\0\0\0\0\0\0r93\0\0\0\0\0\0r94\0\0\0\0\0\0r95\0\0\0\0\0\0" \ + "r96\0\0\0\0\0\0r97\0\0\0\0\0\0r98\0\0\0\0\0\0r99\0\0\0\0\0\0" \ + "r100\0\0\0\0\0r101\0\0\0\0\0r102\0\0\0\0\0r103\0\0\0\0\0" \ + "r104\0\0\0\0\0r105\0\0\0\0\0r106\0\0\0\0\0r107\0\0\0\0\0" \ + "r108\0\0\0\0\0r109\0\0\0\0\0r110\0\0\0\0\0r111\0\0\0\0\0" \ + "r112\0\0\0\0\0r113\0\0\0\0\0r114\0\0\0\0\0r115\0\0\0\0\0" \ + "r116\0\0\0\0\0r117\0\0\0\0\0r118\0\0\0\0\0r119\0\0\0\0\0" \ + "r120\0\0\0\0\0r121\0\0\0\0\0r122\0\0\0\0\0r123\0\0\0\0\0" \ + "r124\0\0\0\0\0r125\0\0\0\0\0r126\0\0\0\0\0r127\0\0\0\0\0" \ + "nat0\0\0\0\0\0nat1\0\0\0\0\0nat2\0\0\0\0\0nat3\0\0\0\0\0" \ + "nat4\0\0\0\0\0nat5\0\0\0\0\0nat6\0\0\0\0\0nat7\0\0\0\0\0" \ + "nat8\0\0\0\0\0nat9\0\0\0\0\0nat10\0\0\0\0nat11\0\0\0\0" \ + "nat12\0\0\0\0nat13\0\0\0\0nat14\0\0\0\0nat15\0\0\0\0" \ + "nat16\0\0\0\0nat17\0\0\0\0nat18\0\0\0\0nat19\0\0\0\0" \ + "nat20\0\0\0\0nat21\0\0\0\0nat22\0\0\0\0nat23\0\0\0\0" \ + "nat24\0\0\0\0nat25\0\0\0\0nat26\0\0\0\0nat27\0\0\0\0" \ + "nat28\0\0\0\0nat29\0\0\0\0nat30\0\0\0\0nat31\0\0\0\0" \ + "nat32\0\0\0\0nat33\0\0\0\0nat34\0\0\0\0nat35\0\0\0\0" \ + "nat36\0\0\0\0nat37\0\0\0\0nat38\0\0\0\0nat39\0\0\0\0" \ + "nat40\0\0\0\0nat41\0\0\0\0nat42\0\0\0\0nat43\0\0\0\0" \ + "nat44\0\0\0\0nat45\0\0\0\0nat46\0\0\0\0nat47\0\0\0\0" \ + "nat48\0\0\0\0nat49\0\0\0\0nat50\0\0\0\0nat51\0\0\0\0" \ + "nat52\0\0\0\0nat53\0\0\0\0nat54\0\0\0\0nat55\0\0\0\0" \ + "nat56\0\0\0\0nat57\0\0\0\0nat58\0\0\0\0nat59\0\0\0\0" \ + "nat60\0\0\0\0nat61\0\0\0\0nat62\0\0\0\0nat63\0\0\0\0" \ + "nat64\0\0\0\0nat65\0\0\0\0nat66\0\0\0\0nat67\0\0\0\0" \ + "nat68\0\0\0\0nat69\0\0\0\0nat70\0\0\0\0nat71\0\0\0\0" \ + "nat72\0\0\0\0nat73\0\0\0\0nat74\0\0\0\0nat75\0\0\0\0" \ + "nat76\0\0\0\0nat77\0\0\0\0nat78\0\0\0\0nat79\0\0\0\0" \ + "nat80\0\0\0\0nat81\0\0\0\0nat82\0\0\0\0nat83\0\0\0\0" \ + "nat84\0\0\0\0nat85\0\0\0\0nat86\0\0\0\0nat87\0\0\0\0" \ + "nat88\0\0\0\0nat89\0\0\0\0nat90\0\0\0\0nat91\0\0\0\0" \ + "nat92\0\0\0\0nat93\0\0\0\0nat94\0\0\0\0nat95\0\0\0\0" \ + "nat96\0\0\0\0nat97\0\0\0\0nat98\0\0\0\0nat99\0\0\0\0" \ + "nat100\0\0\0nat101\0\0\0nat102\0\0\0nat103\0\0\0" \ + "nat104\0\0\0nat105\0\0\0nat106\0\0\0nat107\0\0\0" \ + "nat108\0\0\0nat109\0\0\0nat110\0\0\0nat111\0\0\0" \ + "nat112\0\0\0nat113\0\0\0nat114\0\0\0nat115\0\0\0" \ + "nat116\0\0\0nat117\0\0\0nat118\0\0\0nat119\0\0\0" \ + "nat120\0\0\0nat121\0\0\0nat122\0\0\0nat123\0\0\0" \ + "nat124\0\0\0nat125\0\0\0nat126\0\0\0nat127\0\0\0" \ + "f0\0\0\0\0\0\0\0f1\0\0\0\0\0\0\0f2\0\0\0\0\0\0\0f3\0\0\0\0\0\0\0" \ + "f4\0\0\0\0\0\0\0f5\0\0\0\0\0\0\0f6\0\0\0\0\0\0\0f7\0\0\0\0\0\0\0" \ + "f8\0\0\0\0\0\0\0f9\0\0\0\0\0\0\0f10\0\0\0\0\0\0f11\0\0\0\0\0\0" \ + "f12\0\0\0\0\0\0f13\0\0\0\0\0\0f14\0\0\0\0\0\0f15\0\0\0\0\0\0" \ + "f16\0\0\0\0\0\0f17\0\0\0\0\0\0f18\0\0\0\0\0\0f19\0\0\0\0\0\0" \ + "f20\0\0\0\0\0\0f21\0\0\0\0\0\0f22\0\0\0\0\0\0f23\0\0\0\0\0\0" \ + "f24\0\0\0\0\0\0f25\0\0\0\0\0\0f26\0\0\0\0\0\0f27\0\0\0\0\0\0" \ + "f28\0\0\0\0\0\0f29\0\0\0\0\0\0f30\0\0\0\0\0\0f31\0\0\0\0\0\0" \ + "f32\0\0\0\0\0\0f33\0\0\0\0\0\0f34\0\0\0\0\0\0f35\0\0\0\0\0\0" \ + "f36\0\0\0\0\0\0f37\0\0\0\0\0\0f38\0\0\0\0\0\0f39\0\0\0\0\0\0" \ + "f40\0\0\0\0\0\0f41\0\0\0\0\0\0f42\0\0\0\0\0\0f43\0\0\0\0\0\0" \ + "f44\0\0\0\0\0\0f45\0\0\0\0\0\0f46\0\0\0\0\0\0f47\0\0\0\0\0\0" \ + "f48\0\0\0\0\0\0f49\0\0\0\0\0\0f50\0\0\0\0\0\0f51\0\0\0\0\0\0" \ + "f52\0\0\0\0\0\0f53\0\0\0\0\0\0f54\0\0\0\0\0\0f55\0\0\0\0\0\0" \ + "f56\0\0\0\0\0\0f57\0\0\0\0\0\0f58\0\0\0\0\0\0f59\0\0\0\0\0\0" \ + "f60\0\0\0\0\0\0f61\0\0\0\0\0\0f62\0\0\0\0\0\0f63\0\0\0\0\0\0" \ + "f64\0\0\0\0\0\0f65\0\0\0\0\0\0f66\0\0\0\0\0\0f67\0\0\0\0\0\0" \ + "f68\0\0\0\0\0\0f69\0\0\0\0\0\0f70\0\0\0\0\0\0f71\0\0\0\0\0\0" \ + "f72\0\0\0\0\0\0f73\0\0\0\0\0\0f74\0\0\0\0\0\0f75\0\0\0\0\0\0" \ + "f76\0\0\0\0\0\0f77\0\0\0\0\0\0f78\0\0\0\0\0\0f79\0\0\0\0\0\0" \ + "f80\0\0\0\0\0\0f81\0\0\0\0\0\0f82\0\0\0\0\0\0f83\0\0\0\0\0\0" \ + "f84\0\0\0\0\0\0f85\0\0\0\0\0\0f86\0\0\0\0\0\0f87\0\0\0\0\0\0" \ + "f88\0\0\0\0\0\0f89\0\0\0\0\0\0f90\0\0\0\0\0\0f91\0\0\0\0\0\0" \ + "f92\0\0\0\0\0\0f93\0\0\0\0\0\0f94\0\0\0\0\0\0f95\0\0\0\0\0\0" \ + "f96\0\0\0\0\0\0f97\0\0\0\0\0\0f98\0\0\0\0\0\0f99\0\0\0\0\0\0" \ + "f100\0\0\0\0\0f101\0\0\0\0\0f102\0\0\0\0\0f103\0\0\0\0\0" \ + "f104\0\0\0\0\0f105\0\0\0\0\0f106\0\0\0\0\0f107\0\0\0\0\0" \ + "f108\0\0\0\0\0f109\0\0\0\0\0f110\0\0\0\0\0f111\0\0\0\0\0" \ + "f112\0\0\0\0\0f113\0\0\0\0\0f114\0\0\0\0\0f115\0\0\0\0\0" \ + "f116\0\0\0\0\0f117\0\0\0\0\0f118\0\0\0\0\0f119\0\0\0\0\0" \ + "f120\0\0\0\0\0f121\0\0\0\0\0f122\0\0\0\0\0f123\0\0\0\0\0" \ + "f124\0\0\0\0\0f125\0\0\0\0\0f126\0\0\0\0\0f127\0\0\0\0\0" \ + "ar0\0\0\0\0\0\0ar1\0\0\0\0\0\0ar2\0\0\0\0\0\0ar3\0\0\0\0\0\0" \ + "ar4\0\0\0\0\0\0ar5\0\0\0\0\0\0ar6\0\0\0\0\0\0ar7\0\0\0\0\0\0" \ + "ar8\0\0\0\0\0\0ar9\0\0\0\0\0\0ar10\0\0\0\0\0ar11\0\0\0\0\0" \ + "ar12\0\0\0\0\0ar13\0\0\0\0\0ar14\0\0\0\0\0ar15\0\0\0\0\0" \ + "rsc\0\0\0\0\0\0bsp\0\0\0\0\0\0bspstore\0rnat\0\0\0\0\0" \ + "ar20\0\0\0\0\0ar21\0\0\0\0\0ar22\0\0\0\0\0ar23\0\0\0\0\0" \ + "ar24\0\0\0\0\0ar25\0\0\0\0\0ar26\0\0\0\0\0ar27\0\0\0\0\0" \ + "ar28\0\0\0\0\0ar29\0\0\0\0\0ar30\0\0\0\0\0ar31\0\0\0\0\0" \ + "ccv\0\0\0\0\0\0ar33\0\0\0\0\0ar34\0\0\0\0\0ar35\0\0\0\0\0" \ + "unat\0\0\0\0\0ar37\0\0\0\0\0ar38\0\0\0\0\0ar39\0\0\0\0\0" \ + "fpsr\0\0\0\0\0ar41\0\0\0\0\0ar42\0\0\0\0\0ar43\0\0\0\0\0" \ + "ar44\0\0\0\0\0ar45\0\0\0\0\0ar46\0\0\0\0\0ar47\0\0\0\0\0" \ + "ar48\0\0\0\0\0ar49\0\0\0\0\0ar50\0\0\0\0\0ar51\0\0\0\0\0" \ + "ar52\0\0\0\0\0ar53\0\0\0\0\0ar54\0\0\0\0\0ar55\0\0\0\0\0" \ + "ar56\0\0\0\0\0ar57\0\0\0\0\0ar58\0\0\0\0\0ar59\0\0\0\0\0" \ + "ar60\0\0\0\0\0ar61\0\0\0\0\0ar62\0\0\0\0\0ar63\0\0\0\0\0" \ + "pfs\0\0\0\0\0\0lc\0\0\0\0\0\0\0ec\0\0\0\0\0\0\0ar67\0\0\0\0\0" \ + "ar68\0\0\0\0\0ar69\0\0\0\0\0ar70\0\0\0\0\0ar71\0\0\0\0\0" \ + "ar72\0\0\0\0\0ar73\0\0\0\0\0ar74\0\0\0\0\0ar75\0\0\0\0\0" \ + "ar76\0\0\0\0\0ar77\0\0\0\0\0ar78\0\0\0\0\0ar79\0\0\0\0\0" \ + "ar80\0\0\0\0\0ar81\0\0\0\0\0ar82\0\0\0\0\0ar83\0\0\0\0\0" \ + "ar84\0\0\0\0\0ar85\0\0\0\0\0ar86\0\0\0\0\0ar87\0\0\0\0\0" \ + "ar88\0\0\0\0\0ar89\0\0\0\0\0ar90\0\0\0\0\0ar91\0\0\0\0\0" \ + "ar92\0\0\0\0\0ar93\0\0\0\0\0ar94\0\0\0\0\0ar95\0\0\0\0\0" \ + "ar96\0\0\0\0\0ar97\0\0\0\0\0ar98\0\0\0\0\0ar99\0\0\0\0\0" \ + "ar100\0\0\0\0ar101\0\0\0\0ar102\0\0\0\0ar103\0\0\0\0" \ + "ar104\0\0\0\0ar105\0\0\0\0ar106\0\0\0\0ar107\0\0\0\0" \ + "ar108\0\0\0\0ar109\0\0\0\0ar110\0\0\0\0ar111\0\0\0\0" \ + "ar112\0\0\0\0ar113\0\0\0\0ar114\0\0\0\0ar115\0\0\0\0" \ + "ar116\0\0\0\0ar117\0\0\0\0ar118\0\0\0\0ar119\0\0\0\0" \ + "ar120\0\0\0\0ar121\0\0\0\0ar122\0\0\0\0ar123\0\0\0\0" \ + "ar124\0\0\0\0ar125\0\0\0\0ar126\0\0\0\0ar127\0\0\0\0" \ + "rp\0\0\0\0\0\0\0b1\0\0\0\0\0\0\0b2\0\0\0\0\0\0\0b3\0\0\0\0\0\0\0" \ + "b4\0\0\0\0\0\0\0b5\0\0\0\0\0\0\0b6\0\0\0\0\0\0\0b7\0\0\0\0\0\0\0" \ + "pr\0\0\0\0\0\0\0cfm\0\0\0\0\0\0bsp\0\0\0\0\0\0ip\0\0\0\0\0\0\0" \ + "sp\0\0\0\0\0\0\0" + +#define NREGS ((int) (sizeof (regname_str) - 1) / regname_len) + +PROTECTED const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < NREGS) + return regname_str + reg * regname_len; + else + return "???"; +} diff --git a/src/libs/libunwind/ia64/regs.h b/src/libs/libunwind/ia64/regs.h new file mode 100644 index 0000000000..a22a818776 --- /dev/null +++ b/src/libs/libunwind/ia64/regs.h @@ -0,0 +1,73 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* Apply rotation to a general register. REG must be in the range 0-127. */ + +static inline int +rotate_gr (struct cursor *c, int reg) +{ + unsigned int rrb_gr, sor; + int preg; + + sor = 8 * ((c->cfm >> 14) & 0xf); + rrb_gr = (c->cfm >> 18) & 0x7f; + + if ((unsigned) (reg - 32) >= sor) + preg = reg; + else + { + preg = reg + rrb_gr; /* apply rotation */ + if ((unsigned) (preg - 32) >= sor) + preg -= sor; /* wrap around */ + } + if (sor) + Debug (15, "sor=%u rrb.gr=%u, r%d -> r%d\n", sor, rrb_gr, reg, preg); + return preg; +} + +/* Apply rotation to a floating-point register. The number REG must + be in the range of 0-127. */ + +static inline int +rotate_fr (struct cursor *c, int reg) +{ + unsigned int rrb_fr; + int preg; + + rrb_fr = (c->cfm >> 25) & 0x7f; + if (reg < 32) + preg = reg; /* register not part of the rotating partition */ + else + { + preg = reg + rrb_fr; /* apply rotation */ + if (preg > 127) + preg -= 96; /* wrap around */ + } + if (rrb_fr) + Debug (15, "rrb.fr=%u, f%d -> f%d\n", rrb_fr, reg, preg); + return preg; +} diff --git a/src/libs/libunwind/ia64/setjmp.S b/src/libs/libunwind/ia64/setjmp.S new file mode 100644 index 0000000000..384615b840 --- /dev/null +++ b/src/libs/libunwind/ia64/setjmp.S @@ -0,0 +1,51 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "jmpbuf.h" + + .align 32 + + .global _setjmp + + .proc _setjmp + +_setjmp: + mov r2 = ar.bsp + st8 [r32] = r12 // jmp_buf[JB_SP] = sp + mov r3 = rp + + adds r16 = JB_RP*8, r32 + adds r17 = JB_BSP*8, r32 + mov r8 = 0 + ;; + st8 [r16] = r3 // jmp_buf[JB_RP] = rp + st8 [r17] = r2 // jmp_buf[JB_BSP] = bsp + br.ret.sptk.many rp + + .endp _setjmp +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/ia64/siglongjmp.S b/src/libs/libunwind/ia64/siglongjmp.S new file mode 100644 index 0000000000..d77b43753b --- /dev/null +++ b/src/libs/libunwind/ia64/siglongjmp.S @@ -0,0 +1,69 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#define SIG_SETMASK 2 + + .global _UI_siglongjmp_cont + .global sigprocmask + + .align 32 + .proc siglongjmp_continuation +siglongjmp_continuation: +_UI_siglongjmp_cont: // non-function label for siglongjmp.c + .prologue + .save rp, r15 + .body + nop 0 + nop 0 + br.call.sptk.many b6 = .next + ;; + .prologue + .save ar.pfs, r33 +.next: alloc loc1 = ar.pfs, 0, 3, 3, 0 + /* + * Note: we can use the scratch stack are because the caller + * of sigsetjmp() by definition is not a leaf-procedure. + */ + st8 [sp] = r17 // store signal mask + .save rp, loc0 + mov loc0 = r15 // final continuation point + ;; + .body + mov loc2 = r16 // value to return in r8 + + mov out0 = SIG_SETMASK + mov out1 = sp + mov out2 = r0 + br.call.sptk.many rp = sigprocmask + ;; + mov rp = loc0 + mov ar.pfs = loc1 + mov r8 = loc2 + br.ret.sptk.many rp + .endp siglongjmp_continuation +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/ia64/sigsetjmp.S b/src/libs/libunwind/ia64/sigsetjmp.S new file mode 100644 index 0000000000..02f7af4b37 --- /dev/null +++ b/src/libs/libunwind/ia64/sigsetjmp.S @@ -0,0 +1,69 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "jmpbuf.h" + +#define SIG_BLOCK 0 + + .align 32 + + .global __sigsetjmp + .global sigprocmask + + .proc __sigsetjmp + +__sigsetjmp: + .prologue + .save ar.pfs, r35 + alloc loc1 = ar.pfs, 2, 3, 3, 0 + add out2 = JB_MASK*8, in0 + .save rp, loc0 + mov loc0 = rp + mov out0 = SIG_BLOCK + .body + ;; + cmp.ne p6, p0 = in1, r0 + mov out1 = r0 + mov loc2 = ar.bsp +(p6) br.call.sptk.many rp = sigprocmask // sigjmp_buf[JB_MASK] = sigmask + ;; + + add r16 = JB_MASK_SAVED*8, in0 + st8 [in0] = sp, (JB_RP-JB_SP)*8 // sigjmp_buf[JB_SP] = sp + mov r8 = 0 + ;; + st8 [in0] = loc0, (JB_BSP-JB_RP)*8 // sigjmp_buf[JB_RP] = rp + st8 [r16] = in1 // sigjmp_buf[JB_MASK_SAVED] = savemask + mov rp = loc0 + ;; + st8 [in0] = loc2 // sigjmp_buf[JB_BSP] = bsp + mov.i ar.pfs = loc1 + br.ret.sptk.many rp + + .endp __sigsetjmp +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/ia64/ucontext_i.h b/src/libs/libunwind/ia64/ucontext_i.h new file mode 100644 index 0000000000..ea32c8aaa0 --- /dev/null +++ b/src/libs/libunwind/ia64/ucontext_i.h @@ -0,0 +1,68 @@ +/* Copyright (C) 2002 Hewlett-Packard Co. + Contributed by David Mosberger-Tang . + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Constants shared between setcontext() and getcontext(). Don't + install this header file. */ + +#define SIG_BLOCK 0 +#define SIG_UNBLOCK 1 +#define SIG_SETMASK 2 + +#define IA64_SC_FLAG_SYNCHRONOUS_BIT 63 + +#define SC_FLAGS 0x000 +#define SC_NAT 0x008 +#define SC_BSP 0x048 +#define SC_RNAT 0x050 +#define SC_UNAT 0x060 +#define SC_FPSR 0x068 +#define SC_PFS 0x070 +#define SC_LC 0x078 +#define SC_PR 0x080 +#define SC_BR 0x088 +#define SC_GR 0x0c8 +#define SC_FR 0x1d0 +#define SC_MASK 0x9d0 + + +#define rTMP r10 +#define rPOS r11 +#define rCPOS r14 +#define rNAT r15 +#define rFLAGS r16 + +#define rB5 r18 +#define rB4 r19 +#define rB3 r20 +#define rB2 r21 +#define rB1 r22 +#define rB0 r23 +#define rRSC r24 +#define rBSP r25 +#define rRNAT r26 +#define rUNAT r27 +#define rFPSR r28 +#define rPFS r29 +#define rLC r30 +#define rPR r31 diff --git a/src/libs/libunwind/ia64/unwind_decoder.h b/src/libs/libunwind/ia64/unwind_decoder.h new file mode 100644 index 0000000000..7fd41740de --- /dev/null +++ b/src/libs/libunwind/ia64/unwind_decoder.h @@ -0,0 +1,477 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* + * Generic IA-64 unwind info decoder. + * + * This file is used both by the Linux kernel and objdump. Please keep + * the two copies of this file in sync. + * + * You need to customize the decoder by defining the following + * macros/constants before including this file: + * + * Types: + * unw_word Unsigned integer type with at least 64 bits + * + * Register names: + * UNW_REG_BSP + * UNW_REG_BSPSTORE + * UNW_REG_FPSR + * UNW_REG_LC + * UNW_REG_PFS + * UNW_REG_PR + * UNW_REG_RNAT + * UNW_REG_PSP + * UNW_REG_RP + * UNW_REG_UNAT + * + * Decoder action macros: + * UNW_DEC_BAD_CODE(code) + * UNW_DEC_ABI(fmt,abi,context,arg) + * UNW_DEC_BR_GR(fmt,brmask,gr,arg) + * UNW_DEC_BR_MEM(fmt,brmask,arg) + * UNW_DEC_COPY_STATE(fmt,label,arg) + * UNW_DEC_EPILOGUE(fmt,t,ecount,arg) + * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg) + * UNW_DEC_FR_MEM(fmt,frmask,arg) + * UNW_DEC_GR_GR(fmt,grmask,gr,arg) + * UNW_DEC_GR_MEM(fmt,grmask,arg) + * UNW_DEC_LABEL_STATE(fmt,label,arg) + * UNW_DEC_MEM_STACK_F(fmt,t,size,arg) + * UNW_DEC_MEM_STACK_V(fmt,t,arg) + * UNW_DEC_PRIUNAT_GR(fmt,r,arg) + * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) + * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) + * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg) + * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg) + * UNW_DEC_PROLOGUE(fmt,body,rlen,arg) + * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg) + * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg) + * UNW_DEC_REG_REG(fmt,src,dst,arg) + * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg) + * UNW_DEC_REG_WHEN(fmt,reg,t,arg) + * UNW_DEC_RESTORE(fmt,t,abreg,arg) + * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg) + * UNW_DEC_SPILL_BASE(fmt,pspoff,arg) + * UNW_DEC_SPILL_MASK(fmt,imaskp,arg) + * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg) + * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg) + * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg) + * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg) + * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg) + * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg) + */ + +static unw_word +unw_decode_uleb128 (unsigned char **dpp) +{ + unsigned shift = 0; + unw_word byte, result = 0; + unsigned char *bp = *dpp; + + while (1) + { + byte = *bp++; + result |= (byte & 0x7f) << shift; + if ((byte & 0x80) == 0) + break; + shift += 7; + } + *dpp = bp; + return result; +} + +static unsigned char * +unw_decode_x1 (unsigned char *dp, unsigned char code, void *arg) +{ + unsigned char byte1, abreg; + unw_word t, off; + + byte1 = *dp++; + t = unw_decode_uleb128 (&dp); + off = unw_decode_uleb128 (&dp); + abreg = (byte1 & 0x7f); + if (byte1 & 0x80) + UNW_DEC_SPILL_SPREL(X1, t, abreg, off, arg); + else + UNW_DEC_SPILL_PSPREL(X1, t, abreg, off, arg); + return dp; +} + +static unsigned char * +unw_decode_x2 (unsigned char *dp, unsigned char code, void *arg) +{ + unsigned char byte1, byte2, abreg, x, ytreg; + unw_word t; + + byte1 = *dp++; byte2 = *dp++; + t = unw_decode_uleb128 (&dp); + abreg = (byte1 & 0x7f); + ytreg = byte2; + x = (byte1 >> 7) & 1; + if ((byte1 & 0x80) == 0 && ytreg == 0) + UNW_DEC_RESTORE(X2, t, abreg, arg); + else + UNW_DEC_SPILL_REG(X2, t, abreg, x, ytreg, arg); + return dp; +} + +static unsigned char * +unw_decode_x3 (unsigned char *dp, unsigned char code, void *arg) +{ + unsigned char byte1, byte2, abreg, qp; + unw_word t, off; + + byte1 = *dp++; byte2 = *dp++; + t = unw_decode_uleb128 (&dp); + off = unw_decode_uleb128 (&dp); + + qp = (byte1 & 0x3f); + abreg = (byte2 & 0x7f); + + if (byte1 & 0x80) + UNW_DEC_SPILL_SPREL_P(X3, qp, t, abreg, off, arg); + else + UNW_DEC_SPILL_PSPREL_P(X3, qp, t, abreg, off, arg); + return dp; +} + +static unsigned char * +unw_decode_x4 (unsigned char *dp, unsigned char code, void *arg) +{ + unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg; + unw_word t; + + byte1 = *dp++; byte2 = *dp++; byte3 = *dp++; + t = unw_decode_uleb128 (&dp); + + qp = (byte1 & 0x3f); + abreg = (byte2 & 0x7f); + x = (byte2 >> 7) & 1; + ytreg = byte3; + + if ((byte2 & 0x80) == 0 && byte3 == 0) + UNW_DEC_RESTORE_P(X4, qp, t, abreg, arg); + else + UNW_DEC_SPILL_REG_P(X4, qp, t, abreg, x, ytreg, arg); + return dp; +} + +static inline unsigned char * +unw_decode_r1 (unsigned char *dp, unsigned char code, void *arg) +{ + int body = (code & 0x20) != 0; + unw_word rlen; + + rlen = (code & 0x1f); + UNW_DEC_PROLOGUE(R1, body, rlen, arg); + return dp; +} + +static inline unsigned char * +unw_decode_r2 (unsigned char *dp, unsigned char code, void *arg) +{ + unsigned char byte1, mask, grsave; + unw_word rlen; + + byte1 = *dp++; + + mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); + grsave = (byte1 & 0x7f); + rlen = unw_decode_uleb128 (&dp); + UNW_DEC_PROLOGUE_GR(R2, rlen, mask, grsave, arg); + return dp; +} + +static inline unsigned char * +unw_decode_r3 (unsigned char *dp, unsigned char code, void *arg) +{ + unw_word rlen; + + rlen = unw_decode_uleb128 (&dp); + UNW_DEC_PROLOGUE(R3, ((code & 0x3) == 1), rlen, arg); + return dp; +} + +static inline unsigned char * +unw_decode_p1 (unsigned char *dp, unsigned char code, void *arg) +{ + unsigned char brmask = (code & 0x1f); + + UNW_DEC_BR_MEM(P1, brmask, arg); + return dp; +} + +static inline unsigned char * +unw_decode_p2_p5 (unsigned char *dp, unsigned char code, void *arg) +{ + if ((code & 0x10) == 0) + { + unsigned char byte1 = *dp++; + + UNW_DEC_BR_GR(P2, ((code & 0xf) << 1) | ((byte1 >> 7) & 1), + (byte1 & 0x7f), arg); + } + else if ((code & 0x08) == 0) + { + unsigned char byte1 = *dp++, r, dst; + + r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); + dst = (byte1 & 0x7f); + switch (r) + { + case 0: UNW_DEC_REG_GR(P3, UNW_REG_PSP, dst, arg); break; + case 1: UNW_DEC_REG_GR(P3, UNW_REG_RP, dst, arg); break; + case 2: UNW_DEC_REG_GR(P3, UNW_REG_PFS, dst, arg); break; + case 3: UNW_DEC_REG_GR(P3, UNW_REG_PR, dst, arg); break; + case 4: UNW_DEC_REG_GR(P3, UNW_REG_UNAT, dst, arg); break; + case 5: UNW_DEC_REG_GR(P3, UNW_REG_LC, dst, arg); break; + case 6: UNW_DEC_RP_BR(P3, dst, arg); break; + case 7: UNW_DEC_REG_GR(P3, UNW_REG_RNAT, dst, arg); break; + case 8: UNW_DEC_REG_GR(P3, UNW_REG_BSP, dst, arg); break; + case 9: UNW_DEC_REG_GR(P3, UNW_REG_BSPSTORE, dst, arg); break; + case 10: UNW_DEC_REG_GR(P3, UNW_REG_FPSR, dst, arg); break; + case 11: UNW_DEC_PRIUNAT_GR(P3, dst, arg); break; + default: UNW_DEC_BAD_CODE(r); break; + } + } + else if ((code & 0x7) == 0) + UNW_DEC_SPILL_MASK(P4, dp, arg); + else if ((code & 0x7) == 1) + { + unw_word grmask, frmask, byte1, byte2, byte3; + + byte1 = *dp++; byte2 = *dp++; byte3 = *dp++; + grmask = ((byte1 >> 4) & 0xf); + frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3; + UNW_DEC_FRGR_MEM(P5, grmask, frmask, arg); + } + else + UNW_DEC_BAD_CODE(code); + return dp; +} + +static inline unsigned char * +unw_decode_p6 (unsigned char *dp, unsigned char code, void *arg) +{ + int gregs = (code & 0x10) != 0; + unsigned char mask = (code & 0x0f); + + if (gregs) + UNW_DEC_GR_MEM(P6, mask, arg); + else + UNW_DEC_FR_MEM(P6, mask, arg); + return dp; +} + +static inline unsigned char * +unw_decode_p7_p10 (unsigned char *dp, unsigned char code, void *arg) +{ + unsigned char r, byte1, byte2; + unw_word t, size; + + if ((code & 0x10) == 0) + { + r = (code & 0xf); + t = unw_decode_uleb128 (&dp); + switch (r) + { + case 0: + size = unw_decode_uleb128 (&dp); + UNW_DEC_MEM_STACK_F(P7, t, size, arg); + break; + + case 1: UNW_DEC_MEM_STACK_V(P7, t, arg); break; + case 2: UNW_DEC_SPILL_BASE(P7, t, arg); break; + case 3: UNW_DEC_REG_SPREL(P7, UNW_REG_PSP, t, arg); break; + case 4: UNW_DEC_REG_WHEN(P7, UNW_REG_RP, t, arg); break; + case 5: UNW_DEC_REG_PSPREL(P7, UNW_REG_RP, t, arg); break; + case 6: UNW_DEC_REG_WHEN(P7, UNW_REG_PFS, t, arg); break; + case 7: UNW_DEC_REG_PSPREL(P7, UNW_REG_PFS, t, arg); break; + case 8: UNW_DEC_REG_WHEN(P7, UNW_REG_PR, t, arg); break; + case 9: UNW_DEC_REG_PSPREL(P7, UNW_REG_PR, t, arg); break; + case 10: UNW_DEC_REG_WHEN(P7, UNW_REG_LC, t, arg); break; + case 11: UNW_DEC_REG_PSPREL(P7, UNW_REG_LC, t, arg); break; + case 12: UNW_DEC_REG_WHEN(P7, UNW_REG_UNAT, t, arg); break; + case 13: UNW_DEC_REG_PSPREL(P7, UNW_REG_UNAT, t, arg); break; + case 14: UNW_DEC_REG_WHEN(P7, UNW_REG_FPSR, t, arg); break; + case 15: UNW_DEC_REG_PSPREL(P7, UNW_REG_FPSR, t, arg); break; + default: UNW_DEC_BAD_CODE(r); break; + } + } + else + { + switch (code & 0xf) + { + case 0x0: /* p8 */ + { + r = *dp++; + t = unw_decode_uleb128 (&dp); + switch (r) + { + case 1: UNW_DEC_REG_SPREL(P8, UNW_REG_RP, t, arg); break; + case 2: UNW_DEC_REG_SPREL(P8, UNW_REG_PFS, t, arg); break; + case 3: UNW_DEC_REG_SPREL(P8, UNW_REG_PR, t, arg); break; + case 4: UNW_DEC_REG_SPREL(P8, UNW_REG_LC, t, arg); break; + case 5: UNW_DEC_REG_SPREL(P8, UNW_REG_UNAT, t, arg); break; + case 6: UNW_DEC_REG_SPREL(P8, UNW_REG_FPSR, t, arg); break; + case 7: UNW_DEC_REG_WHEN(P8, UNW_REG_BSP, t, arg); break; + case 8: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSP, t, arg); break; + case 9: UNW_DEC_REG_SPREL(P8, UNW_REG_BSP, t, arg); break; + case 10: UNW_DEC_REG_WHEN(P8, UNW_REG_BSPSTORE, t, arg); break; + case 11: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSPSTORE, t, arg); break; + case 12: UNW_DEC_REG_SPREL(P8, UNW_REG_BSPSTORE, t, arg); break; + case 13: UNW_DEC_REG_WHEN(P8, UNW_REG_RNAT, t, arg); break; + case 14: UNW_DEC_REG_PSPREL(P8, UNW_REG_RNAT, t, arg); break; + case 15: UNW_DEC_REG_SPREL(P8, UNW_REG_RNAT, t, arg); break; + case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8, t, arg); break; + case 17: UNW_DEC_PRIUNAT_PSPREL(P8, t, arg); break; + case 18: UNW_DEC_PRIUNAT_SPREL(P8, t, arg); break; + case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8, t, arg); break; + default: UNW_DEC_BAD_CODE(r); break; + } + } + break; + + case 0x1: + byte1 = *dp++; byte2 = *dp++; + UNW_DEC_GR_GR(P9, (byte1 & 0xf), (byte2 & 0x7f), arg); + break; + + case 0xf: /* p10 */ + byte1 = *dp++; byte2 = *dp++; + UNW_DEC_ABI(P10, byte1, byte2, arg); + break; + + case 0x9: + return unw_decode_x1 (dp, code, arg); + + case 0xa: + return unw_decode_x2 (dp, code, arg); + + case 0xb: + return unw_decode_x3 (dp, code, arg); + + case 0xc: + return unw_decode_x4 (dp, code, arg); + + default: + UNW_DEC_BAD_CODE(code); + break; + } + } + return dp; +} + +static inline unsigned char * +unw_decode_b1 (unsigned char *dp, unsigned char code, void *arg) +{ + unw_word label = (code & 0x1f); + + if ((code & 0x20) != 0) + UNW_DEC_COPY_STATE(B1, label, arg); + else + UNW_DEC_LABEL_STATE(B1, label, arg); + return dp; +} + +static inline unsigned char * +unw_decode_b2 (unsigned char *dp, unsigned char code, void *arg) +{ + unw_word t; + + t = unw_decode_uleb128 (&dp); + UNW_DEC_EPILOGUE(B2, t, (code & 0x1f), arg); + return dp; +} + +static inline unsigned char * +unw_decode_b3_x4 (unsigned char *dp, unsigned char code, void *arg) +{ + unw_word t, ecount, label; + + if ((code & 0x10) == 0) + { + t = unw_decode_uleb128 (&dp); + ecount = unw_decode_uleb128 (&dp); + UNW_DEC_EPILOGUE(B3, t, ecount, arg); + } + else if ((code & 0x07) == 0) + { + label = unw_decode_uleb128 (&dp); + if ((code & 0x08) != 0) + UNW_DEC_COPY_STATE(B4, label, arg); + else + UNW_DEC_LABEL_STATE(B4, label, arg); + } + else + switch (code & 0x7) + { + case 1: return unw_decode_x1 (dp, code, arg); + case 2: return unw_decode_x2 (dp, code, arg); + case 3: return unw_decode_x3 (dp, code, arg); + case 4: return unw_decode_x4 (dp, code, arg); + default: UNW_DEC_BAD_CODE(code); break; + } + return dp; +} + +typedef unsigned char *(*unw_decoder) (unsigned char *, unsigned char, void *); + +/* + * Decode one descriptor and return address of next descriptor. + */ +static inline unsigned char * +unw_decode (unsigned char *dp, int inside_body, void *arg) +{ + unsigned char code, primary; + + code = *dp++; + primary = code >> 5; + + if (primary < 2) + dp = unw_decode_r1 (dp, code, arg); + else if (primary == 2) + dp = unw_decode_r2 (dp, code, arg); + else if (primary == 3) + dp = unw_decode_r3 (dp, code, arg); + else if (inside_body) + switch (primary) + { + case 4: + case 5: dp = unw_decode_b1 (dp, code, arg); break; + case 6: dp = unw_decode_b2 (dp, code, arg); break; + case 7: dp = unw_decode_b3_x4 (dp, code, arg); break; + } + else + switch (primary) + { + case 4: dp = unw_decode_p1 (dp, code, arg); break; + case 5: dp = unw_decode_p2_p5 (dp, code, arg); break; + case 6: dp = unw_decode_p6 (dp, code, arg); break; + case 7: dp = unw_decode_p7_p10 (dp, code, arg); break; + } + return dp; +} diff --git a/src/libs/libunwind/ia64/unwind_i.h b/src/libs/libunwind/ia64/unwind_i.h new file mode 100644 index 0000000000..8ccbb46c93 --- /dev/null +++ b/src/libs/libunwind/ia64/unwind_i.h @@ -0,0 +1,633 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include +#include + +#include + +#include "rse.h" + +#include "libunwind_i.h" + +#define IA64_UNW_VER(x) ((x) >> 48) +#define IA64_UNW_FLAG_MASK ((unw_word_t) 0x0000ffff00000000ULL) +#define IA64_UNW_FLAG_OSMASK ((unw_word_t) 0x0000f00000000000ULL) +#define IA64_UNW_FLAG_EHANDLER(x) ((x) & (unw_word_t) 0x0000000100000000ULL) +#define IA64_UNW_FLAG_UHANDLER(x) ((x) & (unw_word_t) 0x0000000200000000ULL) +#define IA64_UNW_LENGTH(x) ((x) & (unw_word_t) 0x00000000ffffffffULL) + +#ifdef MIN +# undef MIN +#endif +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + +#if !defined(HAVE_SYS_UC_ACCESS_H) && !defined(UNW_REMOTE_ONLY) + +static ALWAYS_INLINE void * +inlined_uc_addr (ucontext_t *uc, int reg, uint8_t *nat_bitnr) +{ + unw_word_t reg_addr; + void *addr; + + switch (reg) + { + case UNW_IA64_GR + 0: addr = &unw.read_only.r0; break; + case UNW_IA64_NAT + 0: addr = &unw.read_only.r0; break; + case UNW_IA64_FR + 0: addr = &unw.read_only.f0; break; + case UNW_IA64_FR + 1: + if (__BYTE_ORDER == __BIG_ENDIAN) + addr = &unw.read_only.f1_be; + else + addr = &unw.read_only.f1_le; + break; + case UNW_IA64_IP: addr = &uc->uc_mcontext.sc_br[0]; break; + case UNW_IA64_CFM: addr = &uc->uc_mcontext.sc_ar_pfs; break; + case UNW_IA64_AR_RNAT: addr = &uc->uc_mcontext.sc_ar_rnat; break; + case UNW_IA64_AR_UNAT: addr = &uc->uc_mcontext.sc_ar_unat; break; + case UNW_IA64_AR_LC: addr = &uc->uc_mcontext.sc_ar_lc; break; + case UNW_IA64_AR_FPSR: addr = &uc->uc_mcontext.sc_ar_fpsr; break; + case UNW_IA64_PR: addr = &uc->uc_mcontext.sc_pr; break; + case UNW_IA64_AR_BSPSTORE: addr = &uc->uc_mcontext.sc_ar_bsp; break; + + case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: + case UNW_IA64_GR + 12: + addr = &uc->uc_mcontext.sc_gr[reg - UNW_IA64_GR]; + break; + + case UNW_IA64_NAT + 4 ... UNW_IA64_NAT + 7: + case UNW_IA64_NAT + 12: + addr = &uc->uc_mcontext.sc_nat; + reg_addr = (unw_word_t) &uc->uc_mcontext.sc_gr[reg - UNW_IA64_NAT]; + *nat_bitnr = reg - UNW_IA64_NAT; + break; + + case UNW_IA64_BR + 1 ... UNW_IA64_BR + 5: + addr = &uc->uc_mcontext.sc_br[reg - UNW_IA64_BR]; + break; + + case UNW_IA64_FR+ 2 ... UNW_IA64_FR+ 5: + case UNW_IA64_FR+16 ... UNW_IA64_FR+31: + addr = &uc->uc_mcontext.sc_fr[reg - UNW_IA64_FR]; + break; + + default: + addr = NULL; + } + return addr; +} + +static inline void * +uc_addr (ucontext_t *uc, int reg, uint8_t *nat_bitnr) +{ + if (__builtin_constant_p (reg)) + return inlined_uc_addr (uc, reg, nat_bitnr); + else + return tdep_uc_addr (uc, reg, nat_bitnr); +} + +/* Return TRUE if ADDR points inside unw.read_only_reg. */ + +static inline long +ia64_read_only_reg (void *addr) +{ + return ((unsigned long) ((char *) addr - (char *) &unw.read_only) + < sizeof (unw.read_only)); +} + +#endif /* !defined(HAVE_SYS_UC_ACCESS_H) && !defined(UNW_REMOTE_ONLY) */ + +/* Bits 0 and 1 of a location are used to encode its type: + bit 0: set if location uses floating-point format. + bit 1: set if location is a NaT bit on memory stack. */ + +#define IA64_LOC_TYPE_FP (1 << 0) +#define IA64_LOC_TYPE_MEMSTK_NAT (1 << 1) + +#ifdef UNW_LOCAL_ONLY +#define IA64_LOC_REG(r,t) (((r) << 2) | (t)) +#define IA64_LOC_ADDR(a,t) (((a) & ~0x3) | (t)) +#define IA64_LOC_UC_ADDR(a,t) IA64_LOC_ADDR(a, t) +#define IA64_NULL_LOC (0) + +#define IA64_GET_REG(l) ((l) >> 2) +#define IA64_GET_ADDR(l) ((l) & ~0x3) +#define IA64_IS_NULL_LOC(l) ((l) == 0) +#define IA64_IS_FP_LOC(l) (((l) & IA64_LOC_TYPE_FP) != 0) +#define IA64_IS_MEMSTK_NAT(l) (((l) & IA64_LOC_TYPE_MEMSTK_NAT) != 0) +#define IA64_IS_REG_LOC(l) 0 +#define IA64_IS_UC_LOC(l) 0 + +#define IA64_REG_LOC(c,r) ((unw_word_t) uc_addr((c)->as_arg, r, NULL)) +#define IA64_REG_NAT_LOC(c,r,n) ((unw_word_t) uc_addr((c)->as_arg, r, n)) +#define IA64_FPREG_LOC(c,r) \ + ((unw_word_t) uc_addr((c)->as_arg, (r), NULL) | IA64_LOC_TYPE_FP) + +# define ia64_find_proc_info(c,ip,n) \ + tdep_find_proc_info(unw_local_addr_space, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define ia64_put_unwind_info(c, pi) do { ; } while (0) + +/* Note: the register accessors (ia64_{get,set}{,fp}()) must check for + NULL locations because uc_addr() returns NULL for unsaved + registers. */ + +static inline int +ia64_getfp (struct cursor *c, unw_word_t loc, unw_fpreg_t *val) +{ + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + *val = *(unw_fpreg_t *) IA64_GET_ADDR (loc); + return 0; +} + +static inline int +ia64_putfp (struct cursor *c, unw_word_t loc, unw_fpreg_t val) +{ + unw_fpreg_t *addr = (unw_fpreg_t *) IA64_GET_ADDR (loc); + + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + else if (ia64_read_only_reg (addr)) + { + Debug (16, "attempt to read-only register\n"); + return -UNW_EREADONLYREG; + } + *addr = val; + return 0; +} + +static inline int +ia64_get (struct cursor *c, unw_word_t loc, unw_word_t *val) +{ + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + *val = *(unw_word_t *) IA64_GET_ADDR (loc); + return 0; +} + +static inline int +ia64_put (struct cursor *c, unw_word_t loc, unw_word_t val) +{ + unw_word_t *addr = (unw_word_t *) IA64_GET_ADDR (loc); + + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + else if (ia64_read_only_reg (addr)) + { + Debug (16, "attempt to read-only register\n"); + return -UNW_EREADONLYREG; + } + *addr = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ + +/* Bits 0 and 1 of the second word (w1) of a location are used + to further distinguish what location we're dealing with: + + bit 0: set if the location is a register + bit 1: set of the location is accessed via uc_access(3) */ +#define IA64_LOC_TYPE_REG (1 << 0) +#define IA64_LOC_TYPE_UC (1 << 1) + +#define IA64_LOC_REG(r,t) ((ia64_loc_t) { ((r) << 2) | (t), \ + IA64_LOC_TYPE_REG }) +#define IA64_LOC_ADDR(a,t) ((ia64_loc_t) { ((a) & ~0x3) | (t), 0 }) +#define IA64_LOC_UC_ADDR(a,t) ((ia64_loc_t) { ((a) & ~0x3) | (t), \ + IA64_LOC_TYPE_UC }) +#define IA64_LOC_UC_REG(r,a) ((ia64_loc_t) { ((r) << 2), \ + ((a) | IA64_LOC_TYPE_REG \ + | IA64_LOC_TYPE_UC) }) +#define IA64_NULL_LOC ((ia64_loc_t) { 0, 0 }) + +#define IA64_GET_REG(l) ((l).w0 >> 2) +#define IA64_GET_ADDR(l) ((l).w0 & ~0x3) +#define IA64_GET_AUX_ADDR(l) ((l).w1 & ~0x3) +#define IA64_IS_NULL_LOC(l) (((l).w0 | (l).w1) == 0) +#define IA64_IS_FP_LOC(l) (((l).w0 & IA64_LOC_TYPE_FP) != 0) +#define IA64_IS_MEMSTK_NAT(l) (((l).w0 & IA64_LOC_TYPE_MEMSTK_NAT) != 0) +#define IA64_IS_REG_LOC(l) (((l).w1 & IA64_LOC_TYPE_REG) != 0) +#define IA64_IS_UC_LOC(l) (((l).w1 & IA64_LOC_TYPE_UC) != 0) + +#define IA64_REG_LOC(c,r) IA64_LOC_REG ((r), 0) +#define IA64_REG_NAT_LOC(c,r,n) IA64_LOC_REG ((r), 0) +#define IA64_FPREG_LOC(c,r) IA64_LOC_REG ((r), IA64_LOC_TYPE_FP) + +# define ia64_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define ia64_put_unwind_info(c,pi) \ + (*(c)->as->acc.put_unwind_info)((c)->as, (pi), (c)->as_arg) + +#define ia64_uc_access_reg UNW_OBJ(uc_access_reg) +#define ia64_uc_access_fpreg UNW_OBJ(uc_access_fpreg) + +extern int ia64_uc_access_reg (struct cursor *c, ia64_loc_t loc, + unw_word_t *valp, int write); +extern int ia64_uc_access_fpreg (struct cursor *c, ia64_loc_t loc, + unw_fpreg_t *valp, int write); + +static inline int +ia64_getfp (struct cursor *c, ia64_loc_t loc, unw_fpreg_t *val) +{ + unw_word_t addr; + int ret; + + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + + if (IA64_IS_UC_LOC (loc)) + return ia64_uc_access_fpreg (c, loc, val, 0); + + if (IA64_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, IA64_GET_REG (loc), + val, 0, c->as_arg); + + addr = IA64_GET_ADDR (loc); + ret = (*c->as->acc.access_mem) (c->as, addr + 0, &val->raw.bits[0], 0, + c->as_arg); + if (ret < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 8, &val->raw.bits[1], 0, + c->as_arg); +} + +static inline int +ia64_putfp (struct cursor *c, ia64_loc_t loc, unw_fpreg_t val) +{ + unw_word_t addr; + int ret; + + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + + if (IA64_IS_UC_LOC (loc)) + return ia64_uc_access_fpreg (c, loc, &val, 1); + + if (IA64_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, IA64_GET_REG (loc), &val, 1, + c->as_arg); + + addr = IA64_GET_ADDR (loc); + ret = (*c->as->acc.access_mem) (c->as, addr + 0, &val.raw.bits[0], 1, + c->as_arg); + if (ret < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 8, &val.raw.bits[1], 1, + c->as_arg); +} + +/* Get the 64 data bits from location LOC. If bit 0 is cleared, LOC + is a memory address, otherwise it is a register number. If the + register is a floating-point register, the 64 bits are read from + the significand bits. */ + +static inline int +ia64_get (struct cursor *c, ia64_loc_t loc, unw_word_t *val) +{ + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + + if (IA64_IS_FP_LOC (loc)) + { + unw_fpreg_t tmp; + int ret; + + ret = ia64_getfp (c, loc, &tmp); + if (ret < 0) + return ret; + + if (c->as->big_endian) + *val = tmp.raw.bits[1]; + else + *val = tmp.raw.bits[0]; + return 0; + } + + if (IA64_IS_UC_LOC (loc)) + return ia64_uc_access_reg (c, loc, val, 0); + + if (IA64_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg)(c->as, IA64_GET_REG (loc), val, 0, + c->as_arg); + else + return (*c->as->acc.access_mem)(c->as, IA64_GET_ADDR (loc), val, 0, + c->as_arg); +} + +static inline int +ia64_put (struct cursor *c, ia64_loc_t loc, unw_word_t val) +{ + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + + if (IA64_IS_FP_LOC (loc)) + { + unw_fpreg_t tmp; + + memset (&tmp, 0, sizeof (tmp)); + if (c->as->big_endian) + tmp.raw.bits[1] = val; + else + tmp.raw.bits[0] = val; + return ia64_putfp (c, loc, tmp); + } + + if (IA64_IS_UC_LOC (loc)) + return ia64_uc_access_reg (c, loc, &val, 1); + + if (IA64_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg)(c->as, IA64_GET_REG (loc), &val, 1, + c->as_arg); + else + return (*c->as->acc.access_mem)(c->as, IA64_GET_ADDR (loc), &val, 1, + c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +struct ia64_unwind_block + { + unw_word_t header; + unw_word_t desc[0]; /* unwind descriptors */ + + /* Personality routine and language-specific data follow behind + descriptors. */ + }; + +enum ia64_where + { + IA64_WHERE_NONE, /* register isn't saved at all */ + IA64_WHERE_GR, /* register is saved in a general register */ + IA64_WHERE_FR, /* register is saved in a floating-point register */ + IA64_WHERE_BR, /* register is saved in a branch register */ + IA64_WHERE_SPREL, /* register is saved on memstack (sp-relative) */ + IA64_WHERE_PSPREL, /* register is saved on memstack (psp-relative) */ + + /* At the end of each prologue these locations get resolved to + IA64_WHERE_PSPREL and IA64_WHERE_GR, respectively: */ + + IA64_WHERE_SPILL_HOME, /* register is saved in its spill home */ + IA64_WHERE_GR_SAVE /* register is saved in next general register */ + }; + +#define IA64_WHEN_NEVER 0x7fffffff + +struct ia64_reg_info + { + unw_word_t val; /* save location: register number or offset */ + enum ia64_where where; /* where the register gets saved */ + int when; /* when the register gets saved */ + }; + +struct ia64_labeled_state; /* opaque structure */ + +struct ia64_reg_state + { + struct ia64_reg_state *next; /* next (outer) element on state stack */ + struct ia64_reg_info reg[IA64_NUM_PREGS]; /* register save locations */ + }; + +struct ia64_state_record + { + unsigned int first_region : 1; /* is this the first region? */ + unsigned int done : 1; /* are we done scanning descriptors? */ + unsigned int any_spills : 1; /* got any register spills? */ + unsigned int in_body : 1; /* are we inside prologue or body? */ + uint8_t *imask; /* imask of spill_mask record or NULL */ + uint16_t abi_marker; + + unw_word_t pr_val; /* predicate values */ + unw_word_t pr_mask; /* predicate mask */ + + long spill_offset; /* psp-relative offset for spill base */ + int region_start; + int region_len; + int when_sp_restored; + int epilogue_count; + int when_target; + + uint8_t gr_save_loc; /* next save register */ + uint8_t return_link_reg; /* branch register used as return pointer */ + + struct ia64_labeled_state *labeled_states; + struct ia64_reg_state curr; + }; + +struct ia64_labeled_state + { + struct ia64_labeled_state *next; /* next label (or NULL) */ + unsigned long label; /* label for this state */ + struct ia64_reg_state saved_state; + }; + +/* Convenience macros: */ +#define ia64_make_proc_info UNW_OBJ(make_proc_info) +#define ia64_fetch_proc_info UNW_OBJ(fetch_proc_info) +#define ia64_create_state_record UNW_OBJ(create_state_record) +#define ia64_free_state_record UNW_OBJ(free_state_record) +#define ia64_find_save_locs UNW_OBJ(find_save_locs) +#define ia64_validate_cache UNW_OBJ(ia64_validate_cache) +#define ia64_local_validate_cache UNW_OBJ(ia64_local_validate_cache) +#define ia64_per_thread_cache UNW_OBJ(per_thread_cache) +#define ia64_scratch_loc UNW_OBJ(scratch_loc) +#define ia64_local_resume UNW_OBJ(local_resume) +#define ia64_local_addr_space_init UNW_OBJ(local_addr_space_init) +#define ia64_strloc UNW_OBJ(strloc) +#define ia64_install_cursor UNW_OBJ(install_cursor) +#define rbs_switch UNW_OBJ(rbs_switch) +#define rbs_find_stacked UNW_OBJ(rbs_find_stacked) + +extern int ia64_make_proc_info (struct cursor *c); +extern int ia64_fetch_proc_info (struct cursor *c, unw_word_t ip, + int need_unwind_info); +/* The proc-info must be valid for IP before this routine can be + called: */ +extern int ia64_create_state_record (struct cursor *c, + struct ia64_state_record *sr); +extern int ia64_free_state_record (struct ia64_state_record *sr); +extern int ia64_find_save_locs (struct cursor *c); +extern void ia64_validate_cache (unw_addr_space_t as, void *arg); +extern int ia64_local_validate_cache (unw_addr_space_t as, void *arg); +extern void ia64_local_addr_space_init (void); +extern ia64_loc_t ia64_scratch_loc (struct cursor *c, unw_regnum_t reg, + uint8_t *nat_bitnr); + +extern NORETURN void ia64_install_cursor (struct cursor *c, + unw_word_t pri_unat, + unw_word_t *extra, + unw_word_t bspstore, + unw_word_t dirty_size, + unw_word_t *dirty_partition, + unw_word_t dirty_rnat); +extern int ia64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); +extern int rbs_switch (struct cursor *c, + unw_word_t saved_bsp, unw_word_t saved_bspstore, + ia64_loc_t saved_rnat_loc); +extern int rbs_find_stacked (struct cursor *c, unw_word_t regs_to_skip, + ia64_loc_t *locp, ia64_loc_t *rnat_locp); + +#ifndef UNW_REMOTE_ONLY +# define NEED_RBS_COVER_AND_FLUSH +# define rbs_cover_and_flush UNW_OBJ(rbs_cover_and_flush) + extern int rbs_cover_and_flush (struct cursor *c, unw_word_t nregs, + unw_word_t *dirty_partition, + unw_word_t *dirty_rnat, + unw_word_t *bspstore); +#endif + +/* Warning: ia64_strloc() is for debugging only and it is NOT re-entrant! */ +extern const char *ia64_strloc (ia64_loc_t loc); + +/* Return true if the register-backing store is inside a ucontext_t + that needs to be accessed via uc_access(3). */ + +static inline int +rbs_on_uc (struct rbs_area *rbs) +{ + return IA64_IS_UC_LOC (rbs->rnat_loc) && !IA64_IS_REG_LOC (rbs->rnat_loc); +} + +/* Return true if BSP points to a word that's stored on register + backing-store RBS. */ +static inline int +rbs_contains (struct rbs_area *rbs, unw_word_t bsp) +{ + int result; + + /* Caveat: this takes advantage of unsigned arithmetic. The full + test is (bsp >= rbs->end - rbs->size) && (bsp < rbs->end). We + take advantage of the fact that -n == ~n + 1. */ + result = bsp - rbs->end > ~rbs->size; + Debug (16, "0x%lx in [0x%lx-0x%lx) => %d\n", + (long) bsp, (long) (rbs->end - rbs->size), (long) rbs->end, result); + return result; +} + +static inline ia64_loc_t +rbs_get_rnat_loc (struct rbs_area *rbs, unw_word_t bsp) +{ + unw_word_t rnat_addr = rse_rnat_addr (bsp); + ia64_loc_t rnat_loc; + + if (rbs_contains (rbs, rnat_addr)) + { + if (rbs_on_uc (rbs)) + rnat_loc = IA64_LOC_UC_ADDR (rnat_addr, 0); + else + rnat_loc = IA64_LOC_ADDR (rnat_addr, 0); + } + else + rnat_loc = rbs->rnat_loc; + return rnat_loc; +} + +static inline ia64_loc_t +rbs_loc (struct rbs_area *rbs, unw_word_t bsp) +{ + if (rbs_on_uc (rbs)) + return IA64_LOC_UC_ADDR (bsp, 0); + else + return IA64_LOC_ADDR (bsp, 0); +} + +static inline int +ia64_get_stacked (struct cursor *c, unw_word_t reg, + ia64_loc_t *locp, ia64_loc_t *rnat_locp) +{ + struct rbs_area *rbs = c->rbs_area + c->rbs_curr; + unw_word_t addr, regs_to_skip = reg - 32; + int ret = 0; + + assert (reg >= 32 && reg < 128); + + addr = rse_skip_regs (c->bsp, regs_to_skip); + if (locp) + *locp = rbs_loc (rbs, addr); + if (rnat_locp) + *rnat_locp = rbs_get_rnat_loc (rbs, addr); + + if (!rbs_contains (rbs, addr)) + ret = rbs_find_stacked (c, regs_to_skip, locp, rnat_locp); + return ret; +} + +/* The UNaT slot # calculation is identical to the one for RNaT slots, + but for readability/clarity, we don't want to use + ia64_rnat_slot_num() directly. */ +#define ia64_unat_slot_num(addr) rse_slot_num(addr) + +/* The following are helper macros which makes it easier for libunwind + to be used in the kernel. They allow the kernel to optimize away + any unused code without littering everything with #ifdefs. */ +#define ia64_is_big_endian(c) ((c)->as->big_endian) +#define ia64_get_abi(c) ((c)->as->abi) +#define ia64_set_abi(c, v) ((c)->as->abi = (v)) +#define ia64_get_abi_marker(c) ((c)->last_abi_marker) + +/* XXX should be in glibc: */ +#ifndef IA64_SC_FLAG_ONSTACK +# define IA64_SC_FLAG_ONSTACK_BIT 0 /* running on signal stack? */ +# define IA64_SC_FLAG_IN_SYSCALL_BIT 1 /* did signal interrupt a syscall? */ +# define IA64_SC_FLAG_FPH_VALID_BIT 2 /* is state in f[32]-f[127] valid? */ + +# define IA64_SC_FLAG_ONSTACK (1 << IA64_SC_FLAG_ONSTACK_BIT) +# define IA64_SC_FLAG_IN_SYSCALL (1 << IA64_SC_FLAG_IN_SYSCALL_BIT) +# define IA64_SC_FLAG_FPH_VALID (1 << IA64_SC_FLAG_FPH_VALID_BIT) +#endif + +#endif /* unwind_i_h */ diff --git a/src/libs/libunwind/mi/Gdestroy_addr_space.c b/src/libs/libunwind/mi/Gdestroy_addr_space.c new file mode 100644 index 0000000000..719c051e38 --- /dev/null +++ b/src/libs/libunwind/mi/Gdestroy_addr_space.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED void +unw_destroy_addr_space (unw_addr_space_t as) +{ +#ifndef UNW_LOCAL_ONLY +# if UNW_DEBUG + memset (as, 0, sizeof (*as)); +# endif + free (as); +#endif +} diff --git a/src/libs/libunwind/mi/Gdyn-extract.c b/src/libs/libunwind/mi/Gdyn-extract.c new file mode 100644 index 0000000000..a083350910 --- /dev/null +++ b/src/libs/libunwind/mi/Gdyn-extract.c @@ -0,0 +1,62 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +HIDDEN int +unwi_extract_dynamic_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, unw_dyn_info_t *di, + int need_unwind_info, void *arg) +{ + pi->start_ip = di->start_ip; + pi->end_ip = di->end_ip; + pi->gp = di->gp; + pi->format = di->format; + switch (di->format) + { + case UNW_INFO_FORMAT_DYNAMIC: + pi->handler = di->u.pi.handler; + pi->lsda = 0; + pi->flags = di->u.pi.flags; + pi->unwind_info_size = 0; + if (need_unwind_info) + pi->unwind_info = di; + else + pi->unwind_info = NULL; + return 0; + + case UNW_INFO_FORMAT_TABLE: + case UNW_INFO_FORMAT_REMOTE_TABLE: +#ifdef tdep_search_unwind_table + /* call platform-specific search routine: */ + return tdep_search_unwind_table (as, ip, di, pi, need_unwind_info, arg); +#else + /* fall through */ +#endif + default: + break; + } + return -UNW_EINVAL; +} diff --git a/src/libs/libunwind/mi/Gdyn-remote.c b/src/libs/libunwind/mi/Gdyn-remote.c new file mode 100644 index 0000000000..1f029b4deb --- /dev/null +++ b/src/libs/libunwind/mi/Gdyn-remote.c @@ -0,0 +1,326 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "libunwind_i.h" +#include "remote.h" + +static void +free_regions (unw_dyn_region_info_t *region) +{ + if (region->next) + free_regions (region->next); + free (region); +} + +static int +intern_op (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + unw_dyn_op_t *op, void *arg) +{ + int ret; + + if ((ret = fetch8 (as, a, addr, &op->tag, arg)) < 0 + || (ret = fetch8 (as, a, addr, &op->qp, arg)) < 0 + || (ret = fetch16 (as, a, addr, &op->reg, arg)) < 0 + || (ret = fetch32 (as, a, addr, &op->when, arg)) < 0 + || (ret = fetchw (as, a, addr, &op->val, arg)) < 0) + return ret; + return 0; +} + +static int +intern_regions (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, unw_dyn_region_info_t **regionp, void *arg) +{ + uint32_t insn_count, op_count, i; + unw_dyn_region_info_t *region; + unw_word_t next_addr; + int ret; + + *regionp = NULL; + + if (!*addr) + return 0; /* NULL region-list */ + + if ((ret = fetchw (as, a, addr, &next_addr, arg)) < 0 + || (ret = fetch32 (as, a, addr, (int32_t *) &insn_count, arg)) < 0 + || (ret = fetch32 (as, a, addr, (int32_t *) &op_count, arg)) < 0) + return ret; + + region = calloc (1, _U_dyn_region_info_size (op_count)); + if (!region) + { + ret = -UNW_ENOMEM; + goto out; + } + + region->insn_count = insn_count; + region->op_count = op_count; + for (i = 0; i < op_count; ++i) + if ((ret = intern_op (as, a, addr, region->op + i, arg)) < 0) + goto out; + + if (next_addr) + if ((ret = intern_regions (as, a, &next_addr, ®ion->next, arg)) < 0) + goto out; + + *regionp = region; + return 0; + + out: + if (region) + free_regions (region); + return ret; +} + +static int +intern_array (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, unw_word_t table_len, unw_word_t **table_data, + void *arg) +{ + unw_word_t i, *data = calloc (table_len, WSIZE); + int ret = 0; + + if (!data) + { + ret = -UNW_ENOMEM; + goto out; + } + + for (i = 0; i < table_len; ++i) + if (fetchw (as, a, addr, data + i, arg) < 0) + goto out; + + *table_data = data; + return 0; + + out: + if (data) + free (data); + return ret; +} + +static void +free_dyn_info (unw_dyn_info_t *di) +{ + switch (di->format) + { + case UNW_INFO_FORMAT_DYNAMIC: + if (di->u.pi.regions) + { + free_regions (di->u.pi.regions); + di->u.pi.regions = NULL; + } + break; + + case UNW_INFO_FORMAT_TABLE: + if (di->u.ti.table_data) + { + free (di->u.ti.table_data); + di->u.ti.table_data = NULL; + } + break; + + case UNW_INFO_FORMAT_REMOTE_TABLE: + default: + break; + } +} + +static int +intern_dyn_info (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, unw_dyn_info_t *di, void *arg) +{ + unw_word_t first_region; + int ret; + + switch (di->format) + { + case UNW_INFO_FORMAT_DYNAMIC: + if ((ret = fetchw (as, a, addr, &di->u.pi.name_ptr, arg)) < 0 + || (ret = fetchw (as, a, addr, &di->u.pi.handler, arg)) < 0 + || (ret = fetch32 (as, a, addr, + (int32_t *) &di->u.pi.flags, arg)) < 0) + goto out; + *addr += 4; /* skip over pad0 */ + if ((ret = fetchw (as, a, addr, &first_region, arg)) < 0 + || (ret = intern_regions (as, a, &first_region, &di->u.pi.regions, + arg)) < 0) + goto out; + break; + + case UNW_INFO_FORMAT_TABLE: + if ((ret = fetchw (as, a, addr, &di->u.ti.name_ptr, arg)) < 0 + || (ret = fetchw (as, a, addr, &di->u.ti.segbase, arg)) < 0 + || (ret = fetchw (as, a, addr, &di->u.ti.table_len, arg)) < 0 + || (ret = intern_array (as, a, addr, di->u.ti.table_len, + &di->u.ti.table_data, arg)) < 0) + goto out; + break; + + case UNW_INFO_FORMAT_REMOTE_TABLE: + if ((ret = fetchw (as, a, addr, &di->u.rti.name_ptr, arg)) < 0 + || (ret = fetchw (as, a, addr, &di->u.rti.segbase, arg)) < 0 + || (ret = fetchw (as, a, addr, &di->u.rti.table_len, arg)) < 0 + || (ret = fetchw (as, a, addr, &di->u.rti.table_data, arg)) < 0) + goto out; + break; + + default: + ret = -UNW_ENOINFO; + goto out; + } + return 0; + + out: + free_dyn_info (di); + return ret; +} + +HIDDEN int +unwi_dyn_remote_find_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + unw_accessors_t *a = unw_get_accessors (as); + unw_word_t dyn_list_addr, addr, next_addr, gen1, gen2, start_ip, end_ip; + unw_dyn_info_t *di = NULL; + int ret; + + if (as->dyn_info_list_addr) + dyn_list_addr = as->dyn_info_list_addr; + else + { + if ((*a->get_dyn_info_list_addr) (as, &dyn_list_addr, arg) < 0) + return -UNW_ENOINFO; + if (as->caching_policy != UNW_CACHE_NONE) + as->dyn_info_list_addr = dyn_list_addr; + } + + do + { + addr = dyn_list_addr; + + ret = -UNW_ENOINFO; + + if (fetchw (as, a, &addr, &gen1, arg) < 0 + || fetchw (as, a, &addr, &next_addr, arg) < 0) + return ret; + + for (addr = next_addr; addr != 0; addr = next_addr) + { + if (fetchw (as, a, &addr, &next_addr, arg) < 0) + goto recheck; /* only fail if generation # didn't change */ + + addr += WSIZE; /* skip over prev_addr */ + + if (fetchw (as, a, &addr, &start_ip, arg) < 0 + || fetchw (as, a, &addr, &end_ip, arg) < 0) + goto recheck; /* only fail if generation # didn't change */ + + if (ip >= start_ip && ip < end_ip) + { + if (!di) + di = calloc (1, sizeof (*di)); + + di->start_ip = start_ip; + di->end_ip = end_ip; + + if (fetchw (as, a, &addr, &di->gp, arg) < 0 + || fetch32 (as, a, &addr, &di->format, arg) < 0) + goto recheck; /* only fail if generation # didn't change */ + + addr += 4; /* skip over padding */ + + if (need_unwind_info + && intern_dyn_info (as, a, &addr, di, arg) < 0) + goto recheck; /* only fail if generation # didn't change */ + + if (unwi_extract_dynamic_proc_info (as, ip, pi, di, + need_unwind_info, arg) < 0) + { + free_dyn_info (di); + goto recheck; /* only fail if generation # didn't change */ + } + ret = 0; /* OK, found it */ + break; + } + } + + /* Re-check generation number to ensure the data we have is + consistent. */ + recheck: + addr = dyn_list_addr; + if (fetchw (as, a, &addr, &gen2, arg) < 0) + return ret; + } + while (gen1 != gen2); + + if (ret < 0 && di) + free (di); + + return ret; +} + +HIDDEN void +unwi_dyn_remote_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, + void *arg) +{ + if (!pi->unwind_info) + return; + + free_dyn_info (pi->unwind_info); + free (pi->unwind_info); + pi->unwind_info = NULL; +} + +/* Returns 1 if the cache is up-to-date or -1 if the cache contained + stale data and had to be flushed. */ + +HIDDEN int +unwi_dyn_validate_cache (unw_addr_space_t as, void *arg) +{ + unw_word_t addr, gen; + unw_accessors_t *a; + + if (!as->dyn_info_list_addr) + /* If we don't have the dyn_info_list_addr, we don't have anything + in the cache. */ + return 0; + + a = unw_get_accessors (as); + addr = as->dyn_info_list_addr; + + if (fetchw (as, a, &addr, &gen, arg) < 0) + return 1; + + if (gen == as->dyn_generation) + return 1; + + unw_flush_cache (as, 0, 0); + as->dyn_generation = gen; + return -1; +} diff --git a/src/libs/libunwind/mi/Gfind_dynamic_proc_info.c b/src/libs/libunwind/mi/Gfind_dynamic_proc_info.c new file mode 100644 index 0000000000..98d3501286 --- /dev/null +++ b/src/libs/libunwind/mi/Gfind_dynamic_proc_info.c @@ -0,0 +1,91 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +static inline int +local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + return -UNW_ENOINFO; +} + +#else /* !UNW_REMOTE_ONLY */ + +static inline int +local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + unw_dyn_info_list_t *list; + unw_dyn_info_t *di; + +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + + list = (unw_dyn_info_list_t *) (uintptr_t) _U_dyn_info_list_addr (); + for (di = list->first; di; di = di->next) + if (ip >= di->start_ip && ip < di->end_ip) + return unwi_extract_dynamic_proc_info (as, ip, pi, di, need_unwind_info, + arg); + return -UNW_ENOINFO; +} + +#endif /* !UNW_REMOTE_ONLY */ + +#ifdef UNW_LOCAL_ONLY + +static inline int +remote_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + return -UNW_ENOINFO; +} + +#else /* !UNW_LOCAL_ONLY */ + +static inline int +remote_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + return unwi_dyn_remote_find_proc_info (as, ip, pi, need_unwind_info, arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +HIDDEN int +unwi_find_dynamic_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, int need_unwind_info, + void *arg) +{ + if (as == unw_local_addr_space) + return local_find_proc_info (as, ip, pi, need_unwind_info, arg); + else + return remote_find_proc_info (as, ip, pi, need_unwind_info, arg); +} diff --git a/src/libs/libunwind/mi/Gget_accessors.c b/src/libs/libunwind/mi/Gget_accessors.c new file mode 100644 index 0000000000..548c7636d2 --- /dev/null +++ b/src/libs/libunwind/mi/Gget_accessors.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2004-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED unw_accessors_t * +unw_get_accessors (unw_addr_space_t as) +{ + if (!tdep_init_done) + tdep_init (); + return &as->acc; +} diff --git a/src/libs/libunwind/mi/Gget_fpreg.c b/src/libs/libunwind/mi/Gget_fpreg.c new file mode 100644 index 0000000000..f2f7405ec5 --- /dev/null +++ b/src/libs/libunwind/mi/Gget_fpreg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED int +unw_get_fpreg (unw_cursor_t *cursor, int regnum, unw_fpreg_t *valp) +{ + struct cursor *c = (struct cursor *) cursor; + + return tdep_access_fpreg (c, regnum, valp, 0); +} diff --git a/src/libs/libunwind/mi/Gget_proc_info_by_ip.c b/src/libs/libunwind/mi/Gget_proc_info_by_ip.c new file mode 100644 index 0000000000..c39312d564 --- /dev/null +++ b/src/libs/libunwind/mi/Gget_proc_info_by_ip.c @@ -0,0 +1,39 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED int +unw_get_proc_info_by_ip (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, void *as_arg) +{ + unw_accessors_t *a = unw_get_accessors (as); + int ret; + + ret = unwi_find_dynamic_proc_info (as, ip, pi, 0, as_arg); + if (ret == -UNW_ENOINFO) + ret = (*a->find_proc_info) (as, ip, pi, 0, as_arg); + return ret; +} diff --git a/src/libs/libunwind/mi/Gget_proc_name.c b/src/libs/libunwind/mi/Gget_proc_name.c new file mode 100644 index 0000000000..5376f82cc7 --- /dev/null +++ b/src/libs/libunwind/mi/Gget_proc_name.c @@ -0,0 +1,114 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" +#include "remote.h" + +static inline int +intern_string (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t addr, char *buf, size_t buf_len, void *arg) +{ + size_t i; + int ret; + + for (i = 0; i < buf_len; ++i) + { + if ((ret = fetch8 (as, a, &addr, (int8_t *) buf + i, arg)) < 0) + return ret; + + if (buf[i] == '\0') + return 0; /* copied full string; return success */ + } + buf[buf_len - 1] = '\0'; /* ensure string is NUL terminated */ + return -UNW_ENOMEM; +} + +static inline int +get_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, void *arg) +{ + unw_accessors_t *a = unw_get_accessors (as); + unw_proc_info_t pi; + int ret; + + buf[0] = '\0'; /* always return a valid string, even if it's empty */ + + ret = unwi_find_dynamic_proc_info (as, ip, &pi, 1, arg); + if (ret == 0) + { + unw_dyn_info_t *di = pi.unwind_info; + + if (offp) + *offp = ip - pi.start_ip; + + switch (di->format) + { + case UNW_INFO_FORMAT_DYNAMIC: + ret = intern_string (as, a, di->u.pi.name_ptr, buf, buf_len, arg); + break; + + case UNW_INFO_FORMAT_TABLE: + case UNW_INFO_FORMAT_REMOTE_TABLE: + /* XXX should we create a fake name, e.g.: "tablenameN", + where N is the index of the function in the table??? */ + ret = -UNW_ENOINFO; + break; + + default: + ret = -UNW_EINVAL; + break; + } + unwi_put_dynamic_unwind_info (as, &pi, arg); + return ret; + } + + if (ret != -UNW_ENOINFO) + return ret; + + /* not a dynamic procedure, try to lookup static procedure name: */ + + if (a->get_proc_name) + return (*a->get_proc_name) (as, ip, buf, buf_len, offp, arg); + + return -UNW_ENOINFO; +} + +PROTECTED int +unw_get_proc_name (unw_cursor_t *cursor, char *buf, size_t buf_len, + unw_word_t *offp) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t ip; + int error; + + ip = tdep_get_ip (c); + if (c->dwarf.use_prev_instr) + --ip; + error = get_proc_name (tdep_get_as (c), ip, buf, buf_len, offp, + tdep_get_as_arg (c)); + if (c->dwarf.use_prev_instr && offp != NULL && error == 0) + *offp += 1; + return error; +} diff --git a/src/libs/libunwind/mi/Gget_reg.c b/src/libs/libunwind/mi/Gget_reg.c new file mode 100644 index 0000000000..7c0a5a9c06 --- /dev/null +++ b/src/libs/libunwind/mi/Gget_reg.c @@ -0,0 +1,41 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED int +unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp) +{ + struct cursor *c = (struct cursor *) cursor; + + // We can get the IP value directly without needing a lookup. + if (regnum == UNW_REG_IP) + { + *valp = tdep_get_ip (c); + return 0; + } + + return tdep_access_reg (c, regnum, valp, 0); +} diff --git a/src/libs/libunwind/mi/Gput_dynamic_unwind_info.c b/src/libs/libunwind/mi/Gput_dynamic_unwind_info.c new file mode 100644 index 0000000000..ca377c98a8 --- /dev/null +++ b/src/libs/libunwind/mi/Gput_dynamic_unwind_info.c @@ -0,0 +1,55 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +HIDDEN void +unwi_put_dynamic_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, + void *arg) +{ + switch (pi->format) + { + case UNW_INFO_FORMAT_DYNAMIC: +#ifndef UNW_LOCAL_ONLY +# ifdef UNW_REMOTE_ONLY + unwi_dyn_remote_put_unwind_info (as, pi, arg); +# else + if (as != unw_local_addr_space) + unwi_dyn_remote_put_unwind_info (as, pi, arg); +# endif +#endif + break; + + case UNW_INFO_FORMAT_TABLE: + case UNW_INFO_FORMAT_REMOTE_TABLE: +#ifdef tdep_put_unwind_info + tdep_put_unwind_info (as, pi, arg); + break; +#endif + /* fall through */ + default: + break; + } +} diff --git a/src/libs/libunwind/mi/Gset_caching_policy.c b/src/libs/libunwind/mi/Gset_caching_policy.c new file mode 100644 index 0000000000..45ba100132 --- /dev/null +++ b/src/libs/libunwind/mi/Gset_caching_policy.c @@ -0,0 +1,46 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED int +unw_set_caching_policy (unw_addr_space_t as, unw_caching_policy_t policy) +{ + if (!tdep_init_done) + tdep_init (); + +#ifndef HAVE___THREAD + if (policy == UNW_CACHE_PER_THREAD) + policy = UNW_CACHE_GLOBAL; +#endif + + if (policy == as->caching_policy) + return 0; /* no change */ + + as->caching_policy = policy; + /* Ensure caches are empty (and initialized). */ + unw_flush_cache (as, 0, 0); + return 0; +} diff --git a/src/libs/libunwind/mi/Gset_fpreg.c b/src/libs/libunwind/mi/Gset_fpreg.c new file mode 100644 index 0000000000..4f2fa7be6b --- /dev/null +++ b/src/libs/libunwind/mi/Gset_fpreg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED int +unw_set_fpreg (unw_cursor_t *cursor, int regnum, unw_fpreg_t val) +{ + struct cursor *c = (struct cursor *) cursor; + + return tdep_access_fpreg (c, regnum, &val, 1); +} diff --git a/src/libs/libunwind/mi/Gset_reg.c b/src/libs/libunwind/mi/Gset_reg.c new file mode 100644 index 0000000000..c9b6e6aa64 --- /dev/null +++ b/src/libs/libunwind/mi/Gset_reg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED int +unw_set_reg (unw_cursor_t *cursor, int regnum, unw_word_t valp) +{ + struct cursor *c = (struct cursor *) cursor; + + return tdep_access_reg (c, regnum, &valp, 1); +} diff --git a/src/libs/libunwind/mi/Ldestroy_addr_space.c b/src/libs/libunwind/mi/Ldestroy_addr_space.c new file mode 100644 index 0000000000..5bf9364bc7 --- /dev/null +++ b/src/libs/libunwind/mi/Ldestroy_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gdestroy_addr_space.c" +#endif diff --git a/src/libs/libunwind/mi/Ldyn-extract.c b/src/libs/libunwind/mi/Ldyn-extract.c new file mode 100644 index 0000000000..1802f865f7 --- /dev/null +++ b/src/libs/libunwind/mi/Ldyn-extract.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gdyn-extract.c" +#endif diff --git a/src/libs/libunwind/mi/Ldyn-remote.c b/src/libs/libunwind/mi/Ldyn-remote.c new file mode 100644 index 0000000000..260722a04b --- /dev/null +++ b/src/libs/libunwind/mi/Ldyn-remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gdyn-remote.c" +#endif diff --git a/src/libs/libunwind/mi/Lfind_dynamic_proc_info.c b/src/libs/libunwind/mi/Lfind_dynamic_proc_info.c new file mode 100644 index 0000000000..bc88e1c53f --- /dev/null +++ b/src/libs/libunwind/mi/Lfind_dynamic_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gfind_dynamic_proc_info.c" +#endif diff --git a/src/libs/libunwind/mi/Lget_accessors.c b/src/libs/libunwind/mi/Lget_accessors.c new file mode 100644 index 0000000000..555e37f30d --- /dev/null +++ b/src/libs/libunwind/mi/Lget_accessors.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_accessors.c" +#endif diff --git a/src/libs/libunwind/mi/Lget_fpreg.c b/src/libs/libunwind/mi/Lget_fpreg.c new file mode 100644 index 0000000000..e3be441437 --- /dev/null +++ b/src/libs/libunwind/mi/Lget_fpreg.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_fpreg.c" +#endif diff --git a/src/libs/libunwind/mi/Lget_proc_info_by_ip.c b/src/libs/libunwind/mi/Lget_proc_info_by_ip.c new file mode 100644 index 0000000000..96910d83e4 --- /dev/null +++ b/src/libs/libunwind/mi/Lget_proc_info_by_ip.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info_by_ip.c" +#endif diff --git a/src/libs/libunwind/mi/Lget_proc_name.c b/src/libs/libunwind/mi/Lget_proc_name.c new file mode 100644 index 0000000000..378097b57a --- /dev/null +++ b/src/libs/libunwind/mi/Lget_proc_name.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_name.c" +#endif diff --git a/src/libs/libunwind/mi/Lget_reg.c b/src/libs/libunwind/mi/Lget_reg.c new file mode 100644 index 0000000000..effe8a8063 --- /dev/null +++ b/src/libs/libunwind/mi/Lget_reg.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_reg.c" +#endif diff --git a/src/libs/libunwind/mi/Lput_dynamic_unwind_info.c b/src/libs/libunwind/mi/Lput_dynamic_unwind_info.c new file mode 100644 index 0000000000..99597cd5fa --- /dev/null +++ b/src/libs/libunwind/mi/Lput_dynamic_unwind_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gput_dynamic_unwind_info.c" +#endif diff --git a/src/libs/libunwind/mi/Lset_caching_policy.c b/src/libs/libunwind/mi/Lset_caching_policy.c new file mode 100644 index 0000000000..cc18816b37 --- /dev/null +++ b/src/libs/libunwind/mi/Lset_caching_policy.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gset_caching_policy.c" +#endif diff --git a/src/libs/libunwind/mi/Lset_fpreg.c b/src/libs/libunwind/mi/Lset_fpreg.c new file mode 100644 index 0000000000..2497d404f4 --- /dev/null +++ b/src/libs/libunwind/mi/Lset_fpreg.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gset_fpreg.c" +#endif diff --git a/src/libs/libunwind/mi/Lset_reg.c b/src/libs/libunwind/mi/Lset_reg.c new file mode 100644 index 0000000000..c7a872b016 --- /dev/null +++ b/src/libs/libunwind/mi/Lset_reg.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gset_reg.c" +#endif diff --git a/src/libs/libunwind/mi/_ReadSLEB.c b/src/libs/libunwind/mi/_ReadSLEB.c new file mode 100644 index 0000000000..c041e37a05 --- /dev/null +++ b/src/libs/libunwind/mi/_ReadSLEB.c @@ -0,0 +1,25 @@ +#include + +unw_word_t +_ReadSLEB (unsigned char **dpp) +{ + unsigned shift = 0; + unw_word_t byte, result = 0; + unsigned char *bp = *dpp; + + while (1) + { + byte = *bp++; + result |= (byte & 0x7f) << shift; + shift += 7; + if ((byte & 0x80) == 0) + break; + } + + if (shift < 8 * sizeof (unw_word_t) && (byte & 0x40) != 0) + /* sign-extend negative value */ + result |= ((unw_word_t) -1) << shift; + + *dpp = bp; + return result; +} diff --git a/src/libs/libunwind/mi/_ReadULEB.c b/src/libs/libunwind/mi/_ReadULEB.c new file mode 100644 index 0000000000..116f3e19bc --- /dev/null +++ b/src/libs/libunwind/mi/_ReadULEB.c @@ -0,0 +1,20 @@ +#include + +unw_word_t +_ReadULEB (unsigned char **dpp) +{ + unsigned shift = 0; + unw_word_t byte, result = 0; + unsigned char *bp = *dpp; + + while (1) + { + byte = *bp++; + result |= (byte & 0x7f) << shift; + if ((byte & 0x80) == 0) + break; + shift += 7; + } + *dpp = bp; + return result; +} diff --git a/src/libs/libunwind/mi/backtrace.c b/src/libs/libunwind/mi/backtrace.c new file mode 100644 index 0000000000..c7aa2bdcdc --- /dev/null +++ b/src/libs/libunwind/mi/backtrace.c @@ -0,0 +1,81 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef UNW_REMOTE_ONLY + +#define UNW_LOCAL_ONLY +#include +#include +#include + +/* See glibc manual for a description of this function. */ + +static ALWAYS_INLINE int +slow_backtrace (void **buffer, int size, unw_context_t *uc) +{ + unw_cursor_t cursor; + unw_word_t ip; + int n = 0; + + if (unlikely (unw_init_local (&cursor, uc) < 0)) + return 0; + + while (unw_step (&cursor) > 0) + { + if (n >= size) + return n; + + if (unw_get_reg (&cursor, UNW_REG_IP, &ip) < 0) + return n; + buffer[n++] = (void *) (uintptr_t) ip; + } + return n; +} + +int +unw_backtrace (void **buffer, int size) +{ + unw_cursor_t cursor; + unw_context_t uc; + int n = size; + + tdep_getcontext_trace (&uc); + + if (unlikely (unw_init_local (&cursor, &uc) < 0)) + return 0; + + if (unlikely (tdep_trace (&cursor, buffer, &n) < 0)) + { + unw_getcontext (&uc); + return slow_backtrace (buffer, size, &uc); + } + + return n; +} + +extern int backtrace (void **buffer, int size) + WEAK ALIAS(unw_backtrace); + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/mi/dyn-cancel.c b/src/libs/libunwind/mi/dyn-cancel.c new file mode 100644 index 0000000000..9d7472d5fd --- /dev/null +++ b/src/libs/libunwind/mi/dyn-cancel.c @@ -0,0 +1,46 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +void +_U_dyn_cancel (unw_dyn_info_t *di) +{ + mutex_lock (&_U_dyn_info_list_lock); + { + ++_U_dyn_info_list.generation; + + if (di->prev) + di->prev->next = di->next; + else + _U_dyn_info_list.first = di->next; + + if (di->next) + di->next->prev = di->prev; + } + mutex_unlock (&_U_dyn_info_list_lock); + + di->next = di->prev = NULL; +} diff --git a/src/libs/libunwind/mi/dyn-info-list.c b/src/libs/libunwind/mi/dyn-info-list.c new file mode 100644 index 0000000000..1a0790d368 --- /dev/null +++ b/src/libs/libunwind/mi/dyn-info-list.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +PROTECTED unw_word_t +_U_dyn_info_list_addr (void) +{ + return (unw_word_t) (uintptr_t) &_U_dyn_info_list; +} diff --git a/src/libs/libunwind/mi/dyn-register.c b/src/libs/libunwind/mi/dyn-register.c new file mode 100644 index 0000000000..efdad3de07 --- /dev/null +++ b/src/libs/libunwind/mi/dyn-register.c @@ -0,0 +1,44 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +HIDDEN define_lock (_U_dyn_info_list_lock); + +void +_U_dyn_register (unw_dyn_info_t *di) +{ + mutex_lock (&_U_dyn_info_list_lock); + { + ++_U_dyn_info_list.generation; + + di->next = _U_dyn_info_list.first; + di->prev = NULL; + if (di->next) + di->next->prev = di; + _U_dyn_info_list.first = di; + } + mutex_unlock (&_U_dyn_info_list_lock); +} diff --git a/src/libs/libunwind/mi/flush_cache.c b/src/libs/libunwind/mi/flush_cache.c new file mode 100644 index 0000000000..513d13564f --- /dev/null +++ b/src/libs/libunwind/mi/flush_cache.c @@ -0,0 +1,59 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED void +unw_flush_cache (unw_addr_space_t as, unw_word_t lo, unw_word_t hi) +{ +#if !UNW_TARGET_IA64 + struct unw_debug_frame_list *w = as->debug_frames; +#endif + + /* clear dyn_info_list_addr cache: */ + as->dyn_info_list_addr = 0; + +#if !UNW_TARGET_IA64 + for (; w; w = w->next) + { + if (w->index) + free (w->index); + free (w->debug_frame); + } + as->debug_frames = NULL; +#endif + + /* This lets us flush caches lazily. The implementation currently + ignores the flush range arguments (lo-hi). This is OK because + unw_flush_cache() is allowed to flush more than the requested + range. */ + +#ifdef HAVE_FETCH_AND_ADD + fetch_and_add1 (&as->cache_generation); +#else +# warning unw_flush_cache(): need a way to atomically increment an integer. + ++as->cache_generation; +#endif +} diff --git a/src/libs/libunwind/mi/init.c b/src/libs/libunwind/mi/init.c new file mode 100644 index 0000000000..057027e0ec --- /dev/null +++ b/src/libs/libunwind/mi/init.c @@ -0,0 +1,60 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +HIDDEN intrmask_t unwi_full_mask; + +static const char rcsid[] UNUSED = + "$Id: " PACKAGE_STRING " --- report bugs to " PACKAGE_BUGREPORT " $"; + +#if UNW_DEBUG + +/* Must not be declared HIDDEN/PROTECTED because libunwind.so and + libunwind-PLATFORM.so will both define their own copies of this + variable and we want to use only one or the other when both + libraries are loaded. */ +long unwi_debug_level; + +#endif /* UNW_DEBUG */ + +HIDDEN void +mi_init (void) +{ +#if UNW_DEBUG + const char *str = getenv ("UNW_DEBUG_LEVEL"); + + if (str) + unwi_debug_level = atoi (str); + + if (unwi_debug_level > 0) + { + setbuf (stdout, NULL); + setbuf (stderr, NULL); + } +#endif + + assert (sizeof (struct cursor) <= sizeof (unw_cursor_t)); +} diff --git a/src/libs/libunwind/mi/mempool.c b/src/libs/libunwind/mi/mempool.c new file mode 100644 index 0000000000..536b64e815 --- /dev/null +++ b/src/libs/libunwind/mi/mempool.c @@ -0,0 +1,184 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2003, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +/* From GCC docs: ``Gcc also provides a target specific macro + * __BIGGEST_ALIGNMENT__, which is the largest alignment ever used for any data + * type on the target machine you are compiling for.'' */ +#ifdef __BIGGEST_ALIGNMENT__ +# define MAX_ALIGN __BIGGEST_ALIGNMENT__ +#else +/* Crude hack to check that MAX_ALIGN is power-of-two. + * sizeof(long double) = 12 on i386. */ +# define MAX_ALIGN_(n) (n < 8 ? 8 : \ + n < 16 ? 16 : n) +# define MAX_ALIGN MAX_ALIGN_(sizeof (long double)) +#endif + +static char sos_memory[SOS_MEMORY_SIZE] ALIGNED(MAX_ALIGN); +static size_t sos_memory_freepos; +static size_t pg_size; + +HIDDEN void * +sos_alloc (size_t size) +{ + size_t pos; + + size = UNW_ALIGN(size, MAX_ALIGN); + +#if defined(__GNUC__) && defined(HAVE_FETCH_AND_ADD) + /* Assume `sos_memory' is suitably aligned. */ + assert(((uintptr_t) &sos_memory[0] & (MAX_ALIGN-1)) == 0); + + pos = fetch_and_add (&sos_memory_freepos, size); +#else + static define_lock (sos_lock); + intrmask_t saved_mask; + + lock_acquire (&sos_lock, saved_mask); + { + /* No assumptions about `sos_memory' alignment. */ + if (sos_memory_freepos == 0) + { + unsigned align = UNW_ALIGN((uintptr_t) &sos_memory[0], MAX_ALIGN) + - (uintptr_t) &sos_memory[0]; + sos_memory_freepos = align; + } + pos = sos_memory_freepos; + sos_memory_freepos += size; + } + lock_release (&sos_lock, saved_mask); +#endif + + assert (((uintptr_t) &sos_memory[pos] & (MAX_ALIGN-1)) == 0); + assert ((pos+size) <= SOS_MEMORY_SIZE); + + return &sos_memory[pos]; +} + +/* Must be called while holding the mempool lock. */ + +static void +free_object (struct mempool *pool, void *object) +{ + struct object *obj = object; + + obj->next = pool->free_list; + pool->free_list = obj; + ++pool->num_free; +} + +static void +add_memory (struct mempool *pool, char *mem, size_t size, size_t obj_size) +{ + char *obj; + + for (obj = mem; obj <= mem + size - obj_size; obj += obj_size) + free_object (pool, obj); +} + +static void +expand (struct mempool *pool) +{ + size_t size; + char *mem; + + size = pool->chunk_size; + GET_MEMORY (mem, size); + if (!mem) + { + size = UNW_ALIGN(pool->obj_size, pg_size); + GET_MEMORY (mem, size); + if (!mem) + { + /* last chance: try to allocate one object from the SOS memory */ + size = pool->obj_size; + mem = sos_alloc (size); + } + } + add_memory (pool, mem, size, pool->obj_size); +} + +HIDDEN void +mempool_init (struct mempool *pool, size_t obj_size, size_t reserve) +{ + if (pg_size == 0) + pg_size = getpagesize (); + + memset (pool, 0, sizeof (*pool)); + + lock_init (&pool->lock); + + /* round object-size up to integer multiple of MAX_ALIGN */ + obj_size = UNW_ALIGN(obj_size, MAX_ALIGN); + + if (!reserve) + { + reserve = pg_size / obj_size / 4; + if (!reserve) + reserve = 16; + } + + pool->obj_size = obj_size; + pool->reserve = reserve; + pool->chunk_size = UNW_ALIGN(2*reserve*obj_size, pg_size); + + expand (pool); +} + +HIDDEN void * +mempool_alloc (struct mempool *pool) +{ + intrmask_t saved_mask; + struct object *obj; + + lock_acquire (&pool->lock, saved_mask); + { + if (pool->num_free <= pool->reserve) + expand (pool); + + assert (pool->num_free > 0); + + --pool->num_free; + obj = pool->free_list; + pool->free_list = obj->next; + } + lock_release (&pool->lock, saved_mask); + return obj; +} + +HIDDEN void +mempool_free (struct mempool *pool, void *object) +{ + intrmask_t saved_mask; + + lock_acquire (&pool->lock, saved_mask); + { + free_object (pool, object); + } + lock_release (&pool->lock, saved_mask); +} diff --git a/src/libs/libunwind/mi/strerror.c b/src/libs/libunwind/mi/strerror.c new file mode 100644 index 0000000000..2cec73d1db --- /dev/null +++ b/src/libs/libunwind/mi/strerror.c @@ -0,0 +1,51 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 BEA Systems + Contributed by Thomas Hallgren + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +/* Returns the text corresponding to the given err_code or the + text "invalid error code" if the err_code is invalid. */ +const char * +unw_strerror (int err_code) +{ + const char *cp; + unw_error_t error = (unw_error_t)-err_code; + switch (error) + { + case UNW_ESUCCESS: cp = "no error"; break; + case UNW_EUNSPEC: cp = "unspecified (general) error"; break; + case UNW_ENOMEM: cp = "out of memory"; break; + case UNW_EBADREG: cp = "bad register number"; break; + case UNW_EREADONLYREG: cp = "attempt to write read-only register"; break; + case UNW_ESTOPUNWIND: cp = "stop unwinding"; break; + case UNW_EINVALIDIP: cp = "invalid IP"; break; + case UNW_EBADFRAME: cp = "bad frame"; break; + case UNW_EINVAL: cp = "unsupported operation or bad value"; break; + case UNW_EBADVERSION: cp = "unwind info has unsupported version"; break; + case UNW_ENOINFO: cp = "no unwind info found"; break; + default: cp = "invalid error code"; + } + return cp; +} diff --git a/src/libs/libunwind/mips/Gcreate_addr_space.c b/src/libs/libunwind/mips/Gcreate_addr_space.c new file mode 100644 index 0000000000..371841d900 --- /dev/null +++ b/src/libs/libunwind/mips/Gcreate_addr_space.c @@ -0,0 +1,66 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +PROTECTED unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * MIPS supports only big or little-endian, not weird stuff like + * PDP_ENDIAN. + */ + if (byte_order != 0 + && byte_order != __LITTLE_ENDIAN + && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + if (byte_order == 0) + /* use host default: */ + as->big_endian = (__BYTE_ORDER == __BIG_ENDIAN); + else + as->big_endian = (byte_order == __BIG_ENDIAN); + + /* FIXME! There is no way to specify the ABI. */ + as->abi = UNW_MIPS_ABI_O32; + as->addr_size = 4; + + return as; +#endif +} diff --git a/src/libs/libunwind/mips/Gget_proc_info.c b/src/libs/libunwind/mips/Gget_proc_info.c new file mode 100644 index 0000000000..973ddd979b --- /dev/null +++ b/src/libs/libunwind/mips/Gget_proc_info.c @@ -0,0 +1,41 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + /* We can only unwind using Dwarf into on MIPS: return failure code + if it's not present. */ + ret = dwarf_make_proc_info (&c->dwarf); + if (ret < 0) + return ret; + + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/libs/libunwind/mips/Gget_save_loc.c b/src/libs/libunwind/mips/Gget_save_loc.c new file mode 100644 index 0000000000..d6075b76cb --- /dev/null +++ b/src/libs/libunwind/mips/Gget_save_loc.c @@ -0,0 +1,100 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* FIXME for MIPS. */ + +PROTECTED int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + + switch (reg) + { + case UNW_MIPS_R0: + case UNW_MIPS_R1: + case UNW_MIPS_R2: + case UNW_MIPS_R3: + case UNW_MIPS_R4: + case UNW_MIPS_R5: + case UNW_MIPS_R6: + case UNW_MIPS_R7: + case UNW_MIPS_R8: + case UNW_MIPS_R9: + case UNW_MIPS_R10: + case UNW_MIPS_R11: + case UNW_MIPS_R12: + case UNW_MIPS_R13: + case UNW_MIPS_R14: + case UNW_MIPS_R15: + case UNW_MIPS_R16: + case UNW_MIPS_R17: + case UNW_MIPS_R18: + case UNW_MIPS_R19: + case UNW_MIPS_R20: + case UNW_MIPS_R21: + case UNW_MIPS_R22: + case UNW_MIPS_R23: + case UNW_MIPS_R24: + case UNW_MIPS_R25: + case UNW_MIPS_R26: + case UNW_MIPS_R27: + case UNW_MIPS_R28: + case UNW_MIPS_R29: + case UNW_MIPS_R30: + case UNW_MIPS_R31: + case UNW_MIPS_PC: + loc = c->dwarf.loc[reg - UNW_MIPS_R0]; + break; + + default: + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/libs/libunwind/mips/Gglobal.c b/src/libs/libunwind/mips/Gglobal.c new file mode 100644 index 0000000000..fa9478eebe --- /dev/null +++ b/src/libs/libunwind/mips/Gglobal.c @@ -0,0 +1,55 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (mips_lock); +HIDDEN int tdep_init_done; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&mips_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + mips_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&mips_lock, saved_mask); +} diff --git a/src/libs/libunwind/mips/Ginit.c b/src/libs/libunwind/mips/Ginit.c new file mode 100644 index 0000000000..8290c40819 --- /dev/null +++ b/src/libs/libunwind/mips/Ginit.c @@ -0,0 +1,210 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +PROTECTED unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space; + +/* Return the address of the 64-bit slot in UC for REG (even for o32, + where registers are 32-bit, the slots are still 64-bit). */ + +static inline void * +uc_addr (ucontext_t *uc, int reg) +{ + if (reg >= UNW_MIPS_R0 && reg < UNW_MIPS_R0 + 32) + return &uc->uc_mcontext.gregs[reg - UNW_MIPS_R0]; + else if (reg == UNW_MIPS_PC) + return &uc->uc_mcontext.pc; + else + return NULL; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + char *addr = uc_addr (uc, reg); + + if (reg >= UNW_MIPS_R0 && reg <= UNW_MIPS_R31 + && tdep_big_endian (unw_local_addr_space) + && unw_local_addr_space->abi == UNW_MIPS_ABI_O32) + addr += 4; + + return addr; +} + +# endif /* UNW_LOCAL_ONLY */ + +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ + *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list; + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (16, "mem[%llx] <- %llx\n", (long long) addr, (long long) *val); + *(unw_word_t *) (intptr_t) addr = *val; + } + else + { + *val = *(unw_word_t *) (intptr_t) addr; + Debug (16, "mem[%llx] -> %llx\n", (long long) addr, (long long) *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = arg; + + if (unw_is_fpreg (reg)) + goto badreg; + + Debug (16, "reg = %s\n", unw_regname (reg)); + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) (intptr_t) addr = (mips_reg_t) *val; + Debug (12, "%s <- %llx\n", unw_regname (reg), (long long) *val); + } + else + { + *val = (mips_reg_t) *(unw_word_t *) (intptr_t) addr; + Debug (12, "%s -> %llx\n", unw_regname (reg), (long long) *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + unw_fpreg_t *addr; + + if (!unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + *(unw_fpreg_t *) (intptr_t) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) (intptr_t) addr; + Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + + return elf_w (get_proc_name) (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +mips_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); +#if _MIPS_SIM == _ABIO32 + local_addr_space.abi = UNW_MIPS_ABI_O32; +#elif _MIPS_SIM == _ABIN32 + local_addr_space.abi = UNW_MIPS_ABI_N32; +#elif _MIPS_SIM == _ABI64 + local_addr_space.abi = UNW_MIPS_ABI_N64; +#else +# error Unsupported ABI +#endif + local_addr_space.addr_size = sizeof (void *); + local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = NULL; /* mips_local_resume? FIXME! */ + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/mips/Ginit_local.c b/src/libs/libunwind/mips/Ginit_local.c new file mode 100644 index 0000000000..e5e1c5a3a2 --- /dev/null +++ b/src/libs/libunwind/mips/Ginit_local.c @@ -0,0 +1,53 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = uc; + return common_init (c, 1); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/mips/Ginit_remote.c b/src/libs/libunwind/mips/Ginit_remote.c new file mode 100644 index 0000000000..f284e994f4 --- /dev/null +++ b/src/libs/libunwind/mips/Ginit_remote.c @@ -0,0 +1,45 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +PROTECTED int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/libs/libunwind/mips/Gis_signal_frame.c b/src/libs/libunwind/mips/Gis_signal_frame.c new file mode 100644 index 0000000000..2c9627f446 --- /dev/null +++ b/src/libs/libunwind/mips/Gis_signal_frame.c @@ -0,0 +1,78 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2015 Imagination Technologies Limited + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include + +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors (as); + arg = c->dwarf.as_arg; + + ip = c->dwarf.ip; + + /* syscall */ + if ((ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0) + return 0; + if ((w1 & 0xffffffff) != 0x0c) + return 0; + + /* li v0, 0x1061 (rt) or li v0, 0x1017 */ + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) + return 0; + + switch (c->dwarf.as->abi) + { + case UNW_MIPS_ABI_O32: + switch (w0 & 0xffffffff) + { + case 0x24021061: + return 1; + case 0x24021017: + return 2; + default: + return 0; + } + case UNW_MIPS_ABI_N64: + switch (w0 & 0xffffffff) + { + case 0x2402145b: + return 1; + default: + return 0; + } + default: + return 0; + } +} diff --git a/src/libs/libunwind/mips/Gregs.c b/src/libs/libunwind/mips/Gregs.c new file mode 100644 index 0000000000..269777673f --- /dev/null +++ b/src/libs/libunwind/mips/Gregs.c @@ -0,0 +1,103 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* FIXME: The following is probably unfinished and/or at least partly bogus. */ + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + + switch (reg) + { + case UNW_MIPS_R0: + case UNW_MIPS_R1: + case UNW_MIPS_R2: + case UNW_MIPS_R3: + case UNW_MIPS_R4: + case UNW_MIPS_R5: + case UNW_MIPS_R6: + case UNW_MIPS_R7: + case UNW_MIPS_R8: + case UNW_MIPS_R9: + case UNW_MIPS_R10: + case UNW_MIPS_R11: + case UNW_MIPS_R12: + case UNW_MIPS_R13: + case UNW_MIPS_R14: + case UNW_MIPS_R15: + case UNW_MIPS_R16: + case UNW_MIPS_R17: + case UNW_MIPS_R18: + case UNW_MIPS_R19: + case UNW_MIPS_R20: + case UNW_MIPS_R21: + case UNW_MIPS_R22: + case UNW_MIPS_R23: + case UNW_MIPS_R24: + case UNW_MIPS_R25: + case UNW_MIPS_R26: + case UNW_MIPS_R27: + case UNW_MIPS_R28: + case UNW_MIPS_R29: + case UNW_MIPS_R30: + case UNW_MIPS_R31: + loc = c->dwarf.loc[reg - UNW_MIPS_R0]; + break; + + case UNW_MIPS_PC: + loc = c->dwarf.loc[reg]; + break; + + case UNW_MIPS_CFA: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + /* FIXME: IP? Copro & shadow registers? */ + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +/* FIXME for MIPS. */ + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} diff --git a/src/libs/libunwind/mips/Gresume.c b/src/libs/libunwind/mips/Gresume.c new file mode 100644 index 0000000000..b822e24b0c --- /dev/null +++ b/src/libs/libunwind/mips/Gresume.c @@ -0,0 +1,45 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* FIXME for MIPS. */ + +#include + +#include "unwind_i.h" + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +mips_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +PROTECTED int +unw_resume (unw_cursor_t *cursor) +{ + return -UNW_EINVAL; +} diff --git a/src/libs/libunwind/mips/Gstep.c b/src/libs/libunwind/mips/Gstep.c new file mode 100644 index 0000000000..0a0b9c20df --- /dev/null +++ b/src/libs/libunwind/mips/Gstep.c @@ -0,0 +1,132 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2015 Imagination Technologies Limited + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +PROTECTED int +unw_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; + unw_word_t ra, fp; + int ret; + + switch (unw_is_signal_frame (cursor)) { + case 1: + sc_addr = sp_addr + LINUX_SF_TRAMP_SIZE + sizeof (siginfo_t) + + LINUX_UC_MCONTEXT_OFF; + break; + case 2: + sc_addr = sp_addr + LINUX_UC_MCONTEXT_OFF; + break; + default: + return -UNW_EUNSPEC; + } + + if (tdep_big_endian(c->dwarf.as)) + sc_addr += 4; + + c->sigcontext_addr = sc_addr; + + /* Update the dwarf cursor. */ + c->dwarf.loc[UNW_MIPS_R0] = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0); + c->dwarf.loc[UNW_MIPS_R1] = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0); + c->dwarf.loc[UNW_MIPS_R2] = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0); + c->dwarf.loc[UNW_MIPS_R3] = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0); + c->dwarf.loc[UNW_MIPS_R4] = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0); + c->dwarf.loc[UNW_MIPS_R5] = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0); + c->dwarf.loc[UNW_MIPS_R6] = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0); + c->dwarf.loc[UNW_MIPS_R7] = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0); + c->dwarf.loc[UNW_MIPS_R8] = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0); + c->dwarf.loc[UNW_MIPS_R9] = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0); + c->dwarf.loc[UNW_MIPS_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0); + c->dwarf.loc[UNW_MIPS_R11] = DWARF_LOC (sc_addr + LINUX_SC_R11_OFF, 0); + c->dwarf.loc[UNW_MIPS_R12] = DWARF_LOC (sc_addr + LINUX_SC_R12_OFF, 0); + c->dwarf.loc[UNW_MIPS_R13] = DWARF_LOC (sc_addr + LINUX_SC_R13_OFF, 0); + c->dwarf.loc[UNW_MIPS_R14] = DWARF_LOC (sc_addr + LINUX_SC_R14_OFF, 0); + c->dwarf.loc[UNW_MIPS_R15] = DWARF_LOC (sc_addr + LINUX_SC_R15_OFF, 0); + c->dwarf.loc[UNW_MIPS_R16] = DWARF_LOC (sc_addr + LINUX_SC_R16_OFF, 0); + c->dwarf.loc[UNW_MIPS_R17] = DWARF_LOC (sc_addr + LINUX_SC_R17_OFF, 0); + c->dwarf.loc[UNW_MIPS_R18] = DWARF_LOC (sc_addr + LINUX_SC_R18_OFF, 0); + c->dwarf.loc[UNW_MIPS_R19] = DWARF_LOC (sc_addr + LINUX_SC_R19_OFF, 0); + c->dwarf.loc[UNW_MIPS_R20] = DWARF_LOC (sc_addr + LINUX_SC_R20_OFF, 0); + c->dwarf.loc[UNW_MIPS_R21] = DWARF_LOC (sc_addr + LINUX_SC_R21_OFF, 0); + c->dwarf.loc[UNW_MIPS_R22] = DWARF_LOC (sc_addr + LINUX_SC_R22_OFF, 0); + c->dwarf.loc[UNW_MIPS_R23] = DWARF_LOC (sc_addr + LINUX_SC_R23_OFF, 0); + c->dwarf.loc[UNW_MIPS_R24] = DWARF_LOC (sc_addr + LINUX_SC_R24_OFF, 0); + c->dwarf.loc[UNW_MIPS_R25] = DWARF_LOC (sc_addr + LINUX_SC_R25_OFF, 0); + c->dwarf.loc[UNW_MIPS_R26] = DWARF_LOC (sc_addr + LINUX_SC_R26_OFF, 0); + c->dwarf.loc[UNW_MIPS_R27] = DWARF_LOC (sc_addr + LINUX_SC_R27_OFF, 0); + c->dwarf.loc[UNW_MIPS_R28] = DWARF_LOC (sc_addr + LINUX_SC_R28_OFF, 0); + c->dwarf.loc[UNW_MIPS_R29] = DWARF_LOC (sc_addr + LINUX_SC_R29_OFF, 0); + c->dwarf.loc[UNW_MIPS_R30] = DWARF_LOC (sc_addr + LINUX_SC_R30_OFF, 0); + c->dwarf.loc[UNW_MIPS_R31] = DWARF_LOC (sc_addr + LINUX_SC_R31_OFF, 0); + c->dwarf.loc[UNW_MIPS_PC] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0); + + /* Set SP/CFA and PC/IP. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_MIPS_R29], &c->dwarf.cfa); + + if ((ret = dwarf_get(&c->dwarf, DWARF_LOC(sc_addr + LINUX_SC_PC_OFF, 0), + &c->dwarf.ip)) < 0) + return ret; + + if ((ret = dwarf_get(&c->dwarf, DWARF_LOC(sc_addr + LINUX_SC_R31_OFF, 0), + &ra)) < 0) + return ret; + if ((ret = dwarf_get(&c->dwarf, DWARF_LOC(sc_addr + LINUX_SC_R30_OFF, 0), + &fp)) < 0) + return ret; + + Debug (2, "SH (ip=0x%016llx, ra=0x%016llx, sp=0x%016llx, fp=0x%016llx)\n", + (unsigned long long)c->dwarf.ip, (unsigned long long)ra, + (unsigned long long)c->dwarf.cfa, (unsigned long long)fp); + + c->dwarf.pi_valid = 0; + c->dwarf.use_prev_instr = 0; + + return 1; +} + +PROTECTED int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + ret = unw_handle_signal_frame (cursor); + if (ret < 0) + /* Not a signal frame, try DWARF-based unwinding. */ + ret = dwarf_step (&c->dwarf); + + if (unlikely (ret == -UNW_ESTOPUNWIND)) + return ret; + + /* Dwarf unwinding didn't work, stop. */ + if (unlikely (ret < 0)) + return 0; + + return (c->dwarf.ip == 0) ? 0 : 1; +} diff --git a/src/libs/libunwind/mips/Lcreate_addr_space.c b/src/libs/libunwind/mips/Lcreate_addr_space.c new file mode 100644 index 0000000000..0f2dc6be90 --- /dev/null +++ b/src/libs/libunwind/mips/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/libs/libunwind/mips/Lget_proc_info.c b/src/libs/libunwind/mips/Lget_proc_info.c new file mode 100644 index 0000000000..69028b019f --- /dev/null +++ b/src/libs/libunwind/mips/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/libs/libunwind/mips/Lget_save_loc.c b/src/libs/libunwind/mips/Lget_save_loc.c new file mode 100644 index 0000000000..9ea048a907 --- /dev/null +++ b/src/libs/libunwind/mips/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/libs/libunwind/mips/Lglobal.c b/src/libs/libunwind/mips/Lglobal.c new file mode 100644 index 0000000000..6d7b489e14 --- /dev/null +++ b/src/libs/libunwind/mips/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/libs/libunwind/mips/Linit.c b/src/libs/libunwind/mips/Linit.c new file mode 100644 index 0000000000..e9abfdd46a --- /dev/null +++ b/src/libs/libunwind/mips/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/libs/libunwind/mips/Linit_local.c b/src/libs/libunwind/mips/Linit_local.c new file mode 100644 index 0000000000..68a1687e85 --- /dev/null +++ b/src/libs/libunwind/mips/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/libs/libunwind/mips/Linit_remote.c b/src/libs/libunwind/mips/Linit_remote.c new file mode 100644 index 0000000000..58cb04ab7c --- /dev/null +++ b/src/libs/libunwind/mips/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/libs/libunwind/mips/Lis_signal_frame.c b/src/libs/libunwind/mips/Lis_signal_frame.c new file mode 100644 index 0000000000..b9a7c4f51a --- /dev/null +++ b/src/libs/libunwind/mips/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/libs/libunwind/mips/Lregs.c b/src/libs/libunwind/mips/Lregs.c new file mode 100644 index 0000000000..2c9c75cd7d --- /dev/null +++ b/src/libs/libunwind/mips/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/libs/libunwind/mips/Lresume.c b/src/libs/libunwind/mips/Lresume.c new file mode 100644 index 0000000000..41a8cf003d --- /dev/null +++ b/src/libs/libunwind/mips/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/libs/libunwind/mips/Lstep.c b/src/libs/libunwind/mips/Lstep.c new file mode 100644 index 0000000000..c1ac3c7547 --- /dev/null +++ b/src/libs/libunwind/mips/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/libs/libunwind/mips/elfxx.c b/src/libs/libunwind/mips/elfxx.c new file mode 100644 index 0000000000..07d3d12b94 --- /dev/null +++ b/src/libs/libunwind/mips/elfxx.c @@ -0,0 +1,27 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +#include "../src/elfxx.c" diff --git a/src/libs/libunwind/mips/gen-offsets.c b/src/libs/libunwind/mips/gen-offsets.c new file mode 100644 index 0000000000..448f694532 --- /dev/null +++ b/src/libs/libunwind/mips/gen-offsets.c @@ -0,0 +1,30 @@ +#include +#include +#include + +#define UC(N,X) \ + printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) + +#define SC(N,X) \ + printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) + +int +main (void) +{ + printf ( +"/* Linux-specific definitions: */\n\n" + +"/* Define various structure offsets to simplify cross-compilation. */\n\n" + +"/* Offsets for MIPS Linux \"ucontext_t\": */\n\n"); + + UC ("FLAGS", uc_flags); + UC ("LINK", uc_link); + UC ("STACK", uc_stack); + UC ("MCONTEXT", uc_mcontext); + UC ("SIGMASK", uc_sigmask); + + UC ("MCONTEXT_GREGS", uc_mcontext.gregs); + + return 0; +} diff --git a/src/libs/libunwind/mips/getcontext.S b/src/libs/libunwind/mips/getcontext.S new file mode 100644 index 0000000000..d1dbd57932 --- /dev/null +++ b/src/libs/libunwind/mips/getcontext.S @@ -0,0 +1,93 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" +#include + + .text + +#if _MIPS_SIM == _ABIO32 +# if __BYTE_ORDER == __BIG_ENDIAN +# define OFFSET 4 +# else +# define OFFSET 0 +# endif +# define SREG(X) \ + sw $X, (LINUX_UC_MCONTEXT_GREGS + 8 * X + OFFSET) ($4); \ + sra $1, $X, 31; \ + sw $1, (LINUX_UC_MCONTEXT_GREGS + 8 * X + 4 - OFFSET) ($4) +/* Yes, we save the return address to PC. */ +# define SPC \ + sw $31, (LINUX_UC_MCONTEXT_PC + OFFSET) ($4); \ + sra $1, $31, 31; \ + sw $1, (LINUX_UC_MCONTEXT_PC + 4 - OFFSET) ($4) +#else +# define SREG(X) sd $X, (LINUX_UC_MCONTEXT_GREGS + 8 * X) ($4) +# define SPC sd $31, (LINUX_UC_MCONTEXT_PC) ($4) +#endif + + .global _Umips_getcontext + .type _Umips_getcontext, %function + # This is a stub version of getcontext() for MIPS which only stores core + # registers. +_Umips_getcontext: + .set noat + SREG (1) + SREG (0) + SREG (2) + SREG (3) + SREG (4) + SREG (5) + SREG (6) + SREG (7) + SREG (8) + SREG (9) + SREG (10) + SREG (11) + SREG (12) + SREG (13) + SREG (14) + SREG (15) + SREG (16) + SREG (17) + SREG (18) + SREG (19) + SREG (20) + SREG (21) + SREG (22) + SREG (23) + SREG (24) + SREG (25) + SREG (26) + SREG (27) + SREG (28) + SREG (29) + SREG (30) + SREG (31) + SPC + li $2, 0 + j $31 + + .size _Umips_getcontext, .-_Umips_getcontext diff --git a/src/libs/libunwind/mips/init.h b/src/libs/libunwind/mips/init.h new file mode 100644 index 0000000000..74c3ab952f --- /dev/null +++ b/src/libs/libunwind/mips/init.h @@ -0,0 +1,60 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret, i; + + for (i = 0; i < 32; i++) + c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, UNW_MIPS_R0 + i); + for (i = 32; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + c->dwarf.loc[UNW_MIPS_PC] = DWARF_REG_LOC (&c->dwarf, UNW_MIPS_PC); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_MIPS_PC], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_MIPS_R29), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + /* FIXME: Initialisation for other registers. */ + + c->dwarf.args_size = 0; + c->dwarf.ret_addr_column = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/libs/libunwind/mips/is_fpreg.c b/src/libs/libunwind/mips/is_fpreg.c new file mode 100644 index 0000000000..3acc6967a2 --- /dev/null +++ b/src/libs/libunwind/mips/is_fpreg.c @@ -0,0 +1,35 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +/* FIXME: I'm not sure if libunwind's GP/FP register distinction is very useful + on MIPS. */ + +PROTECTED int +unw_is_fpreg (int regnum) +{ + /* FIXME: Support FP. */ + return 0; +} diff --git a/src/libs/libunwind/mips/offsets.h b/src/libs/libunwind/mips/offsets.h new file mode 100644 index 0000000000..b506051367 --- /dev/null +++ b/src/libs/libunwind/mips/offsets.h @@ -0,0 +1,86 @@ +/* Linux-specific definitions: */ + +/* Define various structure offsets to simplify cross-compilation. */ + +/* FIXME: Currently these are only used in getcontext.S, which is only used + for a local unwinder, so we can use the compile-time ABI. At a later date + we will want all three here, to use for signal handlers. Also, because + of the three ABIs, gen-offsets.c can not quite generate this file. */ + +/* Offsets for MIPS Linux "ucontext_t": */ + +/* First 24 bytes in sigframe are argument save space and padding for +what used to be signal trampolines. Ref: arch/mips/kernel/signal.c */ +#define LINUX_SF_TRAMP_SIZE 0x18 + +#if _MIPS_SIM == _ABIO32 + +# define LINUX_UC_FLAGS_OFF 0x0 +# define LINUX_UC_LINK_OFF 0x4 +# define LINUX_UC_STACK_OFF 0x8 +# define LINUX_UC_MCONTEXT_OFF 0x18 +# define LINUX_UC_SIGMASK_OFF 0x268 +# define LINUX_UC_MCONTEXT_PC 0x20 +# define LINUX_UC_MCONTEXT_GREGS 0x28 + +#elif _MIPS_SIM == _ABIN32 + +# define LINUX_UC_FLAGS_OFF 0x0 +# define LINUX_UC_LINK_OFF 0x4 +# define LINUX_UC_STACK_OFF 0x8 +# define LINUX_UC_MCONTEXT_OFF 0x18 +# define LINUX_UC_SIGMASK_OFF 0x270 +# define LINUX_UC_MCONTEXT_PC 0x258 +# define LINUX_UC_MCONTEXT_GREGS 0x18 + +#elif _MIPS_SIM == _ABI64 + +# define LINUX_UC_FLAGS_OFF 0x0 +# define LINUX_UC_LINK_OFF 0x8 +# define LINUX_UC_STACK_OFF 0x10 +# define LINUX_UC_MCONTEXT_OFF 0x28 +# define LINUX_UC_SIGMASK_OFF 0x280 +# define LINUX_UC_MCONTEXT_PC 0x268 +# define LINUX_UC_MCONTEXT_GREGS 0x28 + +#else + +#error Unsupported ABI + +#endif + +#define LINUX_SC_R0_OFF (LINUX_UC_MCONTEXT_GREGS - LINUX_UC_MCONTEXT_OFF) +#define LINUX_SC_R1_OFF (LINUX_SC_R0_OFF + 1*8) +#define LINUX_SC_R2_OFF (LINUX_SC_R0_OFF + 2*8) +#define LINUX_SC_R3_OFF (LINUX_SC_R0_OFF + 3*8) +#define LINUX_SC_R4_OFF (LINUX_SC_R0_OFF + 4*8) +#define LINUX_SC_R5_OFF (LINUX_SC_R0_OFF + 5*8) +#define LINUX_SC_R6_OFF (LINUX_SC_R0_OFF + 6*8) +#define LINUX_SC_R7_OFF (LINUX_SC_R0_OFF + 7*8) +#define LINUX_SC_R8_OFF (LINUX_SC_R0_OFF + 8*8) +#define LINUX_SC_R9_OFF (LINUX_SC_R0_OFF + 9*8) +#define LINUX_SC_R10_OFF (LINUX_SC_R0_OFF + 10*8) +#define LINUX_SC_R11_OFF (LINUX_SC_R0_OFF + 11*8) +#define LINUX_SC_R12_OFF (LINUX_SC_R0_OFF + 12*8) +#define LINUX_SC_R13_OFF (LINUX_SC_R0_OFF + 13*8) +#define LINUX_SC_R14_OFF (LINUX_SC_R0_OFF + 14*8) +#define LINUX_SC_R15_OFF (LINUX_SC_R0_OFF + 15*8) +#define LINUX_SC_R16_OFF (LINUX_SC_R0_OFF + 16*8) +#define LINUX_SC_R17_OFF (LINUX_SC_R0_OFF + 17*8) +#define LINUX_SC_R18_OFF (LINUX_SC_R0_OFF + 18*8) +#define LINUX_SC_R19_OFF (LINUX_SC_R0_OFF + 19*8) +#define LINUX_SC_R20_OFF (LINUX_SC_R0_OFF + 20*8) +#define LINUX_SC_R21_OFF (LINUX_SC_R0_OFF + 21*8) +#define LINUX_SC_R22_OFF (LINUX_SC_R0_OFF + 22*8) +#define LINUX_SC_R23_OFF (LINUX_SC_R0_OFF + 23*8) +#define LINUX_SC_R24_OFF (LINUX_SC_R0_OFF + 24*8) +#define LINUX_SC_R25_OFF (LINUX_SC_R0_OFF + 25*8) +#define LINUX_SC_R26_OFF (LINUX_SC_R0_OFF + 26*8) +#define LINUX_SC_R27_OFF (LINUX_SC_R0_OFF + 27*8) +#define LINUX_SC_R28_OFF (LINUX_SC_R0_OFF + 28*8) +#define LINUX_SC_R29_OFF (LINUX_SC_R0_OFF + 29*8) +#define LINUX_SC_R30_OFF (LINUX_SC_R0_OFF + 30*8) +#define LINUX_SC_R31_OFF (LINUX_SC_R0_OFF + 31*8) + +#define LINUX_SC_SP_OFF LINUX_SC_R29_OFF +#define LINUX_SC_PC_OFF (LINUX_UC_MCONTEXT_PC - LINUX_UC_MCONTEXT_OFF) diff --git a/src/libs/libunwind/mips/regname.c b/src/libs/libunwind/mips/regname.c new file mode 100644 index 0000000000..a4a63340d9 --- /dev/null +++ b/src/libs/libunwind/mips/regname.c @@ -0,0 +1,48 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + /* 0. */ + "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", + /* 8. */ + "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", + /* 16. */ + "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", + /* 24. */ + "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", + }; + +PROTECTED const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else if (reg == UNW_MIPS_PC) + return "pc"; + else + return "???"; +} diff --git a/src/libs/libunwind/mips/siglongjmp.S b/src/libs/libunwind/mips/siglongjmp.S new file mode 100644 index 0000000000..9cbcf3dc01 --- /dev/null +++ b/src/libs/libunwind/mips/siglongjmp.S @@ -0,0 +1,8 @@ + /* Dummy implementation for now. */ + + .globl _UI_siglongjmp_cont + .globl _UI_longjmp_cont + +_UI_siglongjmp_cont: +_UI_longjmp_cont: + j $31 diff --git a/src/libs/libunwind/mips/unwind_i.h b/src/libs/libunwind/mips/unwind_i.h new file mode 100644 index 0000000000..3382dcfe58 --- /dev/null +++ b/src/libs/libunwind/mips/unwind_i.h @@ -0,0 +1,43 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include + +#include + +#include "libunwind_i.h" + +#define mips_lock UNW_OBJ(lock) +#define mips_local_resume UNW_OBJ(local_resume) +#define mips_local_addr_space_init UNW_OBJ(local_addr_space_init) + +extern int mips_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); + +extern void mips_local_addr_space_init (void); + +#endif /* unwind_i_h */ diff --git a/src/libs/libunwind/os-freebsd.c b/src/libs/libunwind/os-freebsd.c new file mode 100644 index 0000000000..1aa1e078f8 --- /dev/null +++ b/src/libs/libunwind/os-freebsd.c @@ -0,0 +1,145 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include +#include +#include +#include +#include + +#include "libunwind_i.h" + +static void * +get_mem(size_t sz) +{ + void *res; + + res = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + if (res == MAP_FAILED) + return (NULL); + return (res); +} + +static void +free_mem(void *ptr, size_t sz) +{ + munmap(ptr, sz); +} + +static int +get_pid_by_tid(int tid) +{ + int mib[3], error; + size_t len, len1; + char *buf; + struct kinfo_proc *kv; + int i, pid; + + len = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_ALL; + + error = sysctl(mib, 3, NULL, &len, NULL, 0); + if (error == -1) + return (-1); + len1 = len * 4 / 3; + buf = get_mem(len1); + if (buf == NULL) + return (-1); + len = len1; + error = sysctl(mib, 3, buf, &len, NULL, 0); + if (error == -1) { + free_mem(buf, len1); + return (-1); + } + pid = -1; + for (i = 0, kv = (struct kinfo_proc *)buf; i < len / sizeof(*kv); + i++, kv++) { + if (kv->ki_tid == tid) { + pid = kv->ki_pid; + break; + } + } + free_mem(buf, len1); + return (pid); +} + +PROTECTED int +tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, char *path, size_t pathlen) +{ + int mib[4], error, ret; + size_t len, len1; + char *buf, *bp, *eb; + struct kinfo_vmentry *kv; + + len = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_VMMAP; + mib[3] = pid; + + error = sysctl(mib, 4, NULL, &len, NULL, 0); + if (error == -1) { + if (errno == ESRCH) { + mib[3] = get_pid_by_tid(pid); + if (mib[3] != -1) + error = sysctl(mib, 4, NULL, &len, NULL, 0); + if (error == -1) + return (-UNW_EUNSPEC); + } else + return (-UNW_EUNSPEC); + } + len1 = len * 4 / 3; + buf = get_mem(len1); + if (buf == NULL) + return (-UNW_EUNSPEC); + len = len1; + error = sysctl(mib, 4, buf, &len, NULL, 0); + if (error == -1) { + free_mem(buf, len1); + return (-UNW_EUNSPEC); + } + ret = -UNW_EUNSPEC; + for (bp = buf, eb = buf + len; bp < eb; bp += kv->kve_structsize) { + kv = (struct kinfo_vmentry *)(uintptr_t)bp; + if (ip < kv->kve_start || ip >= kv->kve_end) + continue; + if (kv->kve_type != KVME_TYPE_VNODE) + continue; + *segbase = kv->kve_start; + *mapoff = kv->kve_offset; + if (path) + { + strncpy(path, kv->kve_path, pathlen); + } + ret = elf_map_image (ei, kv->kve_path); + break; + } + free_mem(buf, len1); + return (ret); +} diff --git a/src/libs/libunwind/os-hpux.c b/src/libs/libunwind/os-hpux.c new file mode 100644 index 0000000000..2ee6fa7426 --- /dev/null +++ b/src/libs/libunwind/os-hpux.c @@ -0,0 +1,67 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include + +#include "libunwind_i.h" + +#include "elf64.h" + +HIDDEN int +tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen) +{ + struct load_module_desc lmd; + const char *path2; + + if (pid != getpid ()) + { + printf ("%s: remote case not implemented yet\n", __FUNCTION__); + return -UNW_ENOINFO; + } + + if (!dlmodinfo (ip, &lmd, sizeof (lmd), NULL, 0, 0)) + return -UNW_ENOINFO; + + *segbase = lmd.text_base; + *mapoff = 0; /* XXX fix me? */ + + path2 = dlgetname (&lmd, sizeof (lmd), NULL, 0, 0); + if (!path2) + return -UNW_ENOINFO; + if (path) + { + strncpy(path, path2, pathlen); + path[pathlen - 1] = '\0'; + if (strcmp(path, path2) != 0) + Debug(1, "buffer size (%d) not big enough to hold path\n", pathlen); + } + Debug(1, "segbase=%lx, mapoff=%lx, path=%s\n", *segbase, *mapoff, path); + + return elf_map_image (ei, path); +} diff --git a/src/libs/libunwind/os-linux.c b/src/libs/libunwind/os-linux.c new file mode 100644 index 0000000000..1cc9ba52ae --- /dev/null +++ b/src/libs/libunwind/os-linux.c @@ -0,0 +1,63 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "libunwind_i.h" +#include "os-linux.h" + +PROTECTED int +tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen) +{ + struct map_iterator mi; + int found = 0, rc; + unsigned long hi; + + if (maps_init (&mi, pid) < 0) + return -1; + + while (maps_next (&mi, segbase, &hi, mapoff)) + if (ip >= *segbase && ip < hi) + { + found = 1; + break; + } + + if (!found) + { + maps_close (&mi); + return -1; + } + if (path) + { + strncpy(path, mi.path, pathlen); + } + rc = elf_map_image (ei, mi.path); + maps_close (&mi); + return rc; +} diff --git a/src/libs/libunwind/os-linux.h b/src/libs/libunwind/os-linux.h new file mode 100644 index 0000000000..3976b38cc2 --- /dev/null +++ b/src/libs/libunwind/os-linux.h @@ -0,0 +1,297 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef os_linux_h +#define os_linux_h + +struct map_iterator + { + off_t offset; + int fd; + size_t buf_size; + char *buf; + char *buf_end; + char *path; + }; + +static inline char * +ltoa (char *buf, long val) +{ + char *cp = buf, tmp; + ssize_t i, len; + + do + { + *cp++ = '0' + (val % 10); + val /= 10; + } + while (val); + + /* reverse the order of the digits: */ + len = cp - buf; + --cp; + for (i = 0; i < len / 2; ++i) + { + tmp = buf[i]; + buf[i] = cp[-i]; + cp[-i] = tmp; + } + return buf + len; +} + +static inline int +maps_init (struct map_iterator *mi, pid_t pid) +{ + char path[sizeof ("/proc/0123456789/maps")], *cp; + + memcpy (path, "/proc/", 6); + cp = ltoa (path + 6, pid); + assert (cp + 6 < path + sizeof (path)); + memcpy (cp, "/maps", 6); + + mi->fd = open (path, O_RDONLY); + if (mi->fd >= 0) + { + /* Try to allocate a page-sized buffer. */ + mi->buf_size = getpagesize (); + cp = mmap (NULL, mi->buf_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (cp == MAP_FAILED) + { + close(mi->fd); + mi->fd = -1; + return -1; + } + else + { + mi->offset = 0; + mi->buf = mi->buf_end = cp + mi->buf_size; + return 0; + } + } + return -1; +} + +static inline char * +skip_whitespace (char *cp) +{ + if (!cp) + return NULL; + + while (*cp == ' ' || *cp == '\t') + ++cp; + return cp; +} + +static inline char * +scan_hex (char *cp, unsigned long *valp) +{ + unsigned long num_digits = 0, digit, val = 0; + + cp = skip_whitespace (cp); + if (!cp) + return NULL; + + while (1) + { + digit = *cp; + if ((digit - '0') <= 9) + digit -= '0'; + else if ((digit - 'a') < 6) + digit -= 'a' - 10; + else if ((digit - 'A') < 6) + digit -= 'A' - 10; + else + break; + val = (val << 4) | digit; + ++num_digits; + ++cp; + } + if (!num_digits) + return NULL; + *valp = val; + return cp; +} + +static inline char * +scan_dec (char *cp, unsigned long *valp) +{ + unsigned long num_digits = 0, digit, val = 0; + + if (!(cp = skip_whitespace (cp))) + return NULL; + + while (1) + { + digit = *cp; + if ((digit - '0') <= 9) + { + digit -= '0'; + ++cp; + } + else + break; + val = (10 * val) + digit; + ++num_digits; + } + if (!num_digits) + return NULL; + *valp = val; + return cp; +} + +static inline char * +scan_char (char *cp, char *valp) +{ + if (!cp) + return NULL; + + *valp = *cp; + + /* don't step over NUL terminator */ + if (*cp) + ++cp; + return cp; +} + +/* Scan a string delimited by white-space. Fails on empty string or + if string is doesn't fit in the specified buffer. */ +static inline char * +scan_string (char *cp, char *valp, size_t buf_size) +{ + size_t i = 0; + + if (!(cp = skip_whitespace (cp))) + return NULL; + + while (*cp != ' ' && *cp != '\t' && *cp != '\0') + { + if ((valp != NULL) && (i < buf_size - 1)) + valp[i++] = *cp; + ++cp; + } + if (i == 0 || i >= buf_size) + return NULL; + valp[i] = '\0'; + return cp; +} + +static inline int +maps_next (struct map_iterator *mi, + unsigned long *low, unsigned long *high, unsigned long *offset) +{ + char perm[16], dash = 0, colon = 0, *cp; + unsigned long major, minor, inum; + ssize_t i, nread; + + if (mi->fd < 0) + return 0; + + while (1) + { + ssize_t bytes_left = mi->buf_end - mi->buf; + char *eol = NULL; + + for (i = 0; i < bytes_left; ++i) + { + if (mi->buf[i] == '\n') + { + eol = mi->buf + i; + break; + } + else if (mi->buf[i] == '\0') + break; + } + if (!eol) + { + /* copy down the remaining bytes, if any */ + if (bytes_left > 0) + memmove (mi->buf_end - mi->buf_size, mi->buf, bytes_left); + + mi->buf = mi->buf_end - mi->buf_size; + nread = read (mi->fd, mi->buf + bytes_left, + mi->buf_size - bytes_left); + if (nread <= 0) + return 0; + else if ((size_t) (nread + bytes_left) < mi->buf_size) + { + /* Move contents to the end of the buffer so we + maintain the invariant that all bytes between + mi->buf and mi->buf_end are valid. */ + memmove (mi->buf_end - nread - bytes_left, mi->buf, + nread + bytes_left); + mi->buf = mi->buf_end - nread - bytes_left; + } + + eol = mi->buf + bytes_left + nread - 1; + + for (i = bytes_left; i < bytes_left + nread; ++i) + if (mi->buf[i] == '\n') + { + eol = mi->buf + i; + break; + } + } + cp = mi->buf; + mi->buf = eol + 1; + *eol = '\0'; + + /* scan: "LOW-HIGH PERM OFFSET MAJOR:MINOR INUM PATH" */ + cp = scan_hex (cp, low); + cp = scan_char (cp, &dash); + cp = scan_hex (cp, high); + cp = scan_string (cp, perm, sizeof (perm)); + cp = scan_hex (cp, offset); + cp = scan_hex (cp, &major); + cp = scan_char (cp, &colon); + cp = scan_hex (cp, &minor); + cp = scan_dec (cp, &inum); + cp = mi->path = skip_whitespace (cp); + if (!cp) + continue; + cp = scan_string (cp, NULL, 0); + if (dash != '-' || colon != ':') + continue; /* skip line with unknown or bad format */ + return 1; + } + return 0; +} + +static inline void +maps_close (struct map_iterator *mi) +{ + if (mi->fd < 0) + return; + close (mi->fd); + mi->fd = -1; + if (mi->buf) + { + munmap (mi->buf_end - mi->buf_size, mi->buf_size); + mi->buf = mi->buf_end = NULL; + } +} + +#endif /* os_linux_h */ diff --git a/src/libs/libunwind/os-qnx.c b/src/libs/libunwind/os-qnx.c new file mode 100644 index 0000000000..97bc76634e --- /dev/null +++ b/src/libs/libunwind/os-qnx.c @@ -0,0 +1,107 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2013 Garmin International + Contributed by Matt Fischer + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "libunwind_i.h" + +struct cb_info +{ + unw_word_t ip; + unsigned long segbase; + unsigned long offset; + const char *path; +}; + +static int callback(const struct dl_phdr_info *info, size_t size, void *data) +{ + int i; + struct cb_info *cbi = (struct cb_info*)data; + for(i=0; idlpi_phnum; i++) { + int segbase = info->dlpi_addr + info->dlpi_phdr[i].p_vaddr; + if(cbi->ip >= segbase && cbi->ip < segbase + info->dlpi_phdr[i].p_memsz) + { + cbi->path = info->dlpi_name; + cbi->offset = info->dlpi_phdr[i].p_offset; + cbi->segbase = segbase; + return 1; + } + } + + return 0; +} + +PROTECTED int +tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen) +{ + struct cb_info cbi; + int ret = -1; + cbi.ip = ip; + cbi.segbase = 0; + cbi.offset = 0; + cbi.path = NULL; + + /* QNX's support for accessing symbol maps is severely broken. There is + a devctl() call that can be made on a proc node (DCMD_PROC_MAPDEBUG) + which returns information similar to Linux's /proc//maps + node, however the filename that is returned by this call is not an + absolute path, and there is no foolproof way to map the filename + back to the file that it came from. + + Therefore, the normal approach for implementing this function, + which works equally well for both local and remote unwinding, + will not work here. The only type of image lookup which works + reliably is locally, using dl_iterate_phdr(). However, the only + time that this function is required to look up a remote image is for + ptrace support, which doesn't work on QNX anyway. Local unwinding, + which is the main case that makes use of this function, will work + fine with dl_iterate_phdr(). Therefore, in lieu of any better + platform support for remote image lookup, this function has just + been implemented in terms of dl_iterate_phdr(). + */ + + if (pid != getpid()) + { + /* Return an error if an attempt is made to perform remote image lookup */ + return -1; + } + + if (dl_iterate_phdr (callback, &cbi) != 0) + { + if (path) + { + strncpy (path, cbi.path, pathlen); + } + + *mapoff = cbi.offset; + *segbase = cbi.segbase; + + ret = elf_map_image (ei, cbi.path); + } + + return ret; +} diff --git a/src/libs/libunwind/ppc/Gget_proc_info.c b/src/libs/libunwind/ppc/Gget_proc_info.c new file mode 100644 index 0000000000..29f1db552a --- /dev/null +++ b/src/libs/libunwind/ppc/Gget_proc_info.c @@ -0,0 +1,41 @@ +/* libunwind - a platform-independent unwind library + + Copied from src/x86_64/, modified slightly (or made empty stubs) for + building frysk successfully on ppc64, by Wu Zhou + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +PROTECTED int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + ret = dwarf_make_proc_info (&c->dwarf); + if (ret < 0) + return ret; + + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/libs/libunwind/ppc/Gget_save_loc.c b/src/libs/libunwind/ppc/Gget_save_loc.c new file mode 100644 index 0000000000..c5beb81d7d --- /dev/null +++ b/src/libs/libunwind/ppc/Gget_save_loc.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + + Copied from src/x86_64/, modified slightly (or made empty stubs) for + building frysk successfully on ppc64, by Wu Zhou + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +PROTECTED int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + /* XXX: empty stub. */ + return 0; +} diff --git a/src/libs/libunwind/ppc/Ginit_local.c b/src/libs/libunwind/ppc/Ginit_local.c new file mode 100644 index 0000000000..4ca2b25b5b --- /dev/null +++ b/src/libs/libunwind/ppc/Ginit_local.c @@ -0,0 +1,65 @@ +/* libunwind - a platform-independent unwind library + + Copied from src/x86_64/, modified slightly (or made empty stubs) for + building frysk successfully on ppc64, by Wu Zhou + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#ifdef UNW_TARGET_PPC64 +#include "../ppc64/init.h" +#else +#include "../ppc32/init.h" +#endif + +#ifdef UNW_REMOTE_ONLY + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + /* XXX: empty stub. */ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = uc; + #ifdef UNW_TARGET_PPC64 + return common_init_ppc64 (c, 1); + #else + return common_init_ppc32 (c, 1); + #endif +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/ppc/Ginit_remote.c b/src/libs/libunwind/ppc/Ginit_remote.c new file mode 100644 index 0000000000..4ee54025a9 --- /dev/null +++ b/src/libs/libunwind/ppc/Ginit_remote.c @@ -0,0 +1,60 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#ifdef UNW_TARGET_PPC64 +#include "../ppc64/init.h" +#else +#include "../ppc32/init.h" +#endif + +PROTECTED int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + + #ifdef UNW_TARGET_PPC64 + return common_init_ppc64 (c, 0); + #elif UNW_TARGET_PPC32 + return common_init_ppc32 (c, 0); + #else + #error init_remote :: NO VALID PPC ARCH! + #endif +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/libs/libunwind/ppc/Gis_signal_frame.c b/src/libs/libunwind/ppc/Gis_signal_frame.c new file mode 100644 index 0000000000..e8b691781e --- /dev/null +++ b/src/libs/libunwind/ppc/Gis_signal_frame.c @@ -0,0 +1,78 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +PROTECTED int +unw_is_signal_frame (unw_cursor_t * cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, i0, i1, i2, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + as->validate = 1; /* Don't trust the ip */ + arg = c->dwarf.as_arg; + + /* Check if return address points at sigreturn sequence. + on ppc64 Linux that is (see libc.so): + 0x38210080 addi r1, r1, 128 // pop the stack + 0x380000ac li r0, 172 // invoke system service 172 + 0x44000002 sc + */ + + ip = c->dwarf.ip; + if (ip == 0) + return 0; + + /* Read up two 8-byte words at the IP. We are only looking at 3 + consecutive 32-bit words, so the second 8-byte word needs to be + shifted right by 32 bits (think big-endian) */ + + a = unw_get_accessors (as); + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0) + return 0; + + if (tdep_big_endian (as)) + { + i0 = w0 >> 32; + i1 = w0 & 0xffffffffUL; + i2 = w1 >> 32; + } + else + { + i0 = w0 & 0xffffffffUL; + i1 = w0 >> 32; + i2 = w1 & 0xffffffffUL; + } + + return (i0 == 0x38210080 && i1 == 0x380000ac && i2 == 0x44000002); +} diff --git a/src/libs/libunwind/ppc/Lget_proc_info.c b/src/libs/libunwind/ppc/Lget_proc_info.c new file mode 100644 index 0000000000..69028b019f --- /dev/null +++ b/src/libs/libunwind/ppc/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/libs/libunwind/ppc/Lget_save_loc.c b/src/libs/libunwind/ppc/Lget_save_loc.c new file mode 100644 index 0000000000..9ea048a907 --- /dev/null +++ b/src/libs/libunwind/ppc/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/libs/libunwind/ppc/Linit_local.c b/src/libs/libunwind/ppc/Linit_local.c new file mode 100644 index 0000000000..68a1687e85 --- /dev/null +++ b/src/libs/libunwind/ppc/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/libs/libunwind/ppc/Linit_remote.c b/src/libs/libunwind/ppc/Linit_remote.c new file mode 100644 index 0000000000..58cb04ab7c --- /dev/null +++ b/src/libs/libunwind/ppc/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/libs/libunwind/ppc/Lis_signal_frame.c b/src/libs/libunwind/ppc/Lis_signal_frame.c new file mode 100644 index 0000000000..b9a7c4f51a --- /dev/null +++ b/src/libs/libunwind/ppc/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/libs/libunwind/ppc/longjmp.S b/src/libs/libunwind/ppc/longjmp.S new file mode 100644 index 0000000000..d363aef222 --- /dev/null +++ b/src/libs/libunwind/ppc/longjmp.S @@ -0,0 +1,36 @@ +/* libunwind - a platform-independent unwind library + + Copied from src/x86_64/, modified slightly (or made empty stubs) for + building frysk successfully on ppc64, by Wu Zhou + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + .globl _UI_longjmp_cont + + .type _UI_longjmp_cont, @function +_UI_longjmp_cont: + .size _UI_longjmp_cont, .-_UI_longjmp_cont + +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/ppc/siglongjmp.S b/src/libs/libunwind/ppc/siglongjmp.S new file mode 100644 index 0000000000..64be36ce17 --- /dev/null +++ b/src/libs/libunwind/ppc/siglongjmp.S @@ -0,0 +1,31 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + .globl _UI_siglongjmp_cont + + _UI_siglongjmp_cont: + +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/ppc32/Gcreate_addr_space.c b/src/libs/libunwind/ppc32/Gcreate_addr_space.c new file mode 100644 index 0000000000..f5055ecb98 --- /dev/null +++ b/src/libs/libunwind/ppc32/Gcreate_addr_space.c @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include + +PROTECTED unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * We support only big-endian on Linux ppc32. + */ + if (byte_order != 0 && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + return as; +#endif +} diff --git a/src/libs/libunwind/ppc32/Gglobal.c b/src/libs/libunwind/ppc32/Gglobal.c new file mode 100644 index 0000000000..a0f80beec6 --- /dev/null +++ b/src/libs/libunwind/ppc32/Gglobal.c @@ -0,0 +1,135 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (ppc32_lock); +HIDDEN int tdep_init_done; + +/* The API register numbers are exactly the same as the .eh_frame + registers, for now at least. */ +HIDDEN const uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH] = + { + [UNW_PPC32_R0]=UNW_PPC32_R0, + [UNW_PPC32_R1]=UNW_PPC32_R1, + [UNW_PPC32_R2]=UNW_PPC32_R2, + [UNW_PPC32_R3]=UNW_PPC32_R3, + [UNW_PPC32_R4]=UNW_PPC32_R4, + [UNW_PPC32_R5]=UNW_PPC32_R5, + [UNW_PPC32_R6]=UNW_PPC32_R6, + [UNW_PPC32_R7]=UNW_PPC32_R7, + [UNW_PPC32_R8]=UNW_PPC32_R8, + [UNW_PPC32_R9]=UNW_PPC32_R9, + [UNW_PPC32_R10]=UNW_PPC32_R10, + [UNW_PPC32_R11]=UNW_PPC32_R11, + [UNW_PPC32_R12]=UNW_PPC32_R12, + [UNW_PPC32_R13]=UNW_PPC32_R13, + [UNW_PPC32_R14]=UNW_PPC32_R14, + [UNW_PPC32_R15]=UNW_PPC32_R15, + [UNW_PPC32_R16]=UNW_PPC32_R16, + [UNW_PPC32_R17]=UNW_PPC32_R17, + [UNW_PPC32_R18]=UNW_PPC32_R18, + [UNW_PPC32_R19]=UNW_PPC32_R19, + [UNW_PPC32_R20]=UNW_PPC32_R20, + [UNW_PPC32_R21]=UNW_PPC32_R21, + [UNW_PPC32_R22]=UNW_PPC32_R22, + [UNW_PPC32_R23]=UNW_PPC32_R23, + [UNW_PPC32_R24]=UNW_PPC32_R24, + [UNW_PPC32_R25]=UNW_PPC32_R25, + [UNW_PPC32_R26]=UNW_PPC32_R26, + [UNW_PPC32_R27]=UNW_PPC32_R27, + [UNW_PPC32_R28]=UNW_PPC32_R28, + [UNW_PPC32_R29]=UNW_PPC32_R29, + [UNW_PPC32_R30]=UNW_PPC32_R30, + [UNW_PPC32_R31]=UNW_PPC32_R31, + + [UNW_PPC32_CTR]=UNW_PPC32_CTR, + [UNW_PPC32_XER]=UNW_PPC32_XER, + [UNW_PPC32_CCR]=UNW_PPC32_CCR, + [UNW_PPC32_LR]=UNW_PPC32_LR, + [UNW_PPC32_FPSCR]=UNW_PPC32_FPSCR, + + [UNW_PPC32_F0]=UNW_PPC32_F0, + [UNW_PPC32_F1]=UNW_PPC32_F1, + [UNW_PPC32_F2]=UNW_PPC32_F2, + [UNW_PPC32_F3]=UNW_PPC32_F3, + [UNW_PPC32_F4]=UNW_PPC32_F4, + [UNW_PPC32_F5]=UNW_PPC32_F5, + [UNW_PPC32_F6]=UNW_PPC32_F6, + [UNW_PPC32_F7]=UNW_PPC32_F7, + [UNW_PPC32_F8]=UNW_PPC32_F8, + [UNW_PPC32_F9]=UNW_PPC32_F9, + [UNW_PPC32_F10]=UNW_PPC32_F10, + [UNW_PPC32_F11]=UNW_PPC32_F11, + [UNW_PPC32_F12]=UNW_PPC32_F12, + [UNW_PPC32_F13]=UNW_PPC32_F13, + [UNW_PPC32_F14]=UNW_PPC32_F14, + [UNW_PPC32_F15]=UNW_PPC32_F15, + [UNW_PPC32_F16]=UNW_PPC32_F16, + [UNW_PPC32_F17]=UNW_PPC32_F17, + [UNW_PPC32_F18]=UNW_PPC32_F18, + [UNW_PPC32_F19]=UNW_PPC32_F19, + [UNW_PPC32_F20]=UNW_PPC32_F20, + [UNW_PPC32_F21]=UNW_PPC32_F21, + [UNW_PPC32_F22]=UNW_PPC32_F22, + [UNW_PPC32_F23]=UNW_PPC32_F23, + [UNW_PPC32_F24]=UNW_PPC32_F24, + [UNW_PPC32_F25]=UNW_PPC32_F25, + [UNW_PPC32_F26]=UNW_PPC32_F26, + [UNW_PPC32_F27]=UNW_PPC32_F27, + [UNW_PPC32_F28]=UNW_PPC32_F28, + [UNW_PPC32_F29]=UNW_PPC32_F29, + [UNW_PPC32_F30]=UNW_PPC32_F30, + [UNW_PPC32_F31]=UNW_PPC32_F31, +}; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&ppc32_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + ppc32_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&ppc32_lock, saved_mask); +} diff --git a/src/libs/libunwind/ppc32/Ginit.c b/src/libs/libunwind/ppc32/Ginit.c new file mode 100644 index 0000000000..f2e6e82367 --- /dev/null +++ b/src/libs/libunwind/ppc32/Ginit.c @@ -0,0 +1,216 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "ucontext_i.h" +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +PROTECTED unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static void * +uc_addr (ucontext_t *uc, int reg) +{ + void *addr; + + if ((unsigned) (reg - UNW_PPC32_R0) < 32) + addr = &uc->uc_mcontext.uc_regs->gregs[reg - UNW_PPC32_R0]; + + else + if ( ((unsigned) (reg - UNW_PPC32_F0) < 32) && + ((unsigned) (reg - UNW_PPC32_F0) >= 0) ) + addr = &uc->uc_mcontext.uc_regs->fpregs.fpregs[reg - UNW_PPC32_F0]; + + else + { + unsigned gregs_idx; + + switch (reg) + { + case UNW_PPC32_CTR: + gregs_idx = CTR_IDX; + break; + case UNW_PPC32_LR: + gregs_idx = LINK_IDX; + break; + case UNW_PPC32_XER: + gregs_idx = XER_IDX; + break; + case UNW_PPC32_CCR: + gregs_idx = CCR_IDX; + break; + default: + return NULL; + } + addr = &uc->uc_mcontext.uc_regs->gregs[gregs_idx]; + } + return addr; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (12, "mem[%lx] <- %lx\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "mem[%lx] -> %lx\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, + int write, void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = arg; + + if ( ((unsigned int) (reg - UNW_PPC32_F0) < 32) && + ((unsigned int) (reg - UNW_PPC32_F0) >= 0)) + goto badreg; + + addr = uc_addr (uc, reg); + if (!addr) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %lx\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %lx\n", unw_regname (reg), *val); + } + return 0; + +badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + unw_fpreg_t *addr; + + if ((unsigned) (reg - UNW_PPC32_F0) < 0) + goto badreg; + + addr = uc_addr (uc, reg); + if (!addr) + goto badreg; + + if (write) + { + Debug (12, "%s <- %016Lf\n", unw_regname (reg), *val); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %016Lf\n", unw_regname (reg), *val); + } + return 0; + +badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +ppc32_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = ppc32_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/ppc32/Gregs.c b/src/libs/libunwind/ppc32/Gregs.c new file mode 100644 index 0000000000..9344455e6c --- /dev/null +++ b/src/libs/libunwind/ppc32/Gregs.c @@ -0,0 +1,90 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + struct dwarf_loc loc; + + switch (reg) + { + case UNW_TDEP_IP: + if (write) + { + c->dwarf.ip = *valp; /* update the IP cache */ + if (c->dwarf.pi_valid && (*valp < c->dwarf.pi.start_ip + || *valp >= c->dwarf.pi.end_ip)) + c->dwarf.pi_valid = 0; /* new IP outside of current proc */ + } + else + *valp = c->dwarf.ip; + return 0; + + case UNW_TDEP_SP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + + default: + break; + } + + /* make sure it's not an FP or VR register */ + if ((((unsigned) (reg - UNW_PPC32_F0)) <= 31)) + return -UNW_EBADREG; + + loc = c->dwarf.loc[reg]; + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + struct dwarf_loc loc; + + if ((unsigned) (reg - UNW_PPC32_F0) < 32) + { + loc = c->dwarf.loc[reg]; + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); + } + + return -UNW_EBADREG; +} + diff --git a/src/libs/libunwind/ppc32/Gresume.c b/src/libs/libunwind/ppc32/Gresume.c new file mode 100644 index 0000000000..955d061c6c --- /dev/null +++ b/src/libs/libunwind/ppc32/Gresume.c @@ -0,0 +1,77 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford cjashfor@us.ibm.com + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#ifndef UNW_REMOTE_ONLY + +#include + +/* sigreturn() is a no-op on x86_64 glibc. */ + +static NORETURN inline long +my_rt_sigreturn (void *new_sp) +{ + /* XXX: empty stub. */ + abort (); +} + +HIDDEN inline int +ppc32_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + /* XXX: empty stub. */ + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +/* This routine is responsible for copying the register values in + cursor C and establishing them as the current machine state. */ + +static inline int +establish_machine_state (struct cursor *c) +{ + /* XXX: empty stub. */ + return 0; +} + +PROTECTED int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if ((ret = establish_machine_state (c)) < 0) + return ret; + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/libs/libunwind/ppc32/Gstep.c b/src/libs/libunwind/ppc32/Gstep.c new file mode 100644 index 0000000000..8506a61885 --- /dev/null +++ b/src/libs/libunwind/ppc32/Gstep.c @@ -0,0 +1,309 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "ucontext_i.h" +#include + +/* This definition originates in /usr/include/asm-ppc64/ptrace.h, but is + defined there only when __KERNEL__ is defined. We reproduce it here for + our use at the user level in order to locate the ucontext record, which + appears to be at this offset relative to the stack pointer when in the + context of the signal handler return trampoline code - + __kernel_sigtramp_rt64. */ +#define __SIGNAL_FRAMESIZE 128 + +/* This definition comes from the document "64-bit PowerPC ELF Application + Binary Interface Supplement 1.9", section 3.2.2. + http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK */ + +typedef struct +{ + long unsigned back_chain; + long unsigned lr_save; + /* many more fields here, but they are unused by this code */ +} stack_frame_t; + + +PROTECTED int +unw_step (unw_cursor_t * cursor) +{ + struct cursor *c = (struct cursor *) cursor; + stack_frame_t dummy; + unw_word_t back_chain_offset, lr_save_offset; + struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc; + int ret; + + Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip); + + if (c->dwarf.ip == 0) + { + /* Unless the cursor or stack is corrupt or uninitialized, + we've most likely hit the top of the stack */ + return 0; + } + + /* Try DWARF-based unwinding... */ + + ret = dwarf_step (&c->dwarf); + + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + if (unlikely (ret < 0)) + { + if (likely (!unw_is_signal_frame (cursor))) + { + /* DWARF unwinding failed. As of 09/26/2006, gcc in 64-bit mode + produces the mandatory level of traceback record in the code, but + I get the impression that this is transitory, that eventually gcc + will not produce any traceback records at all. So, for now, we + won't bother to try to find and use these records. + + We can, however, attempt to unwind the frame by using the callback + chain. This is very crude, however, and won't be able to unwind + any registers besides the IP, SP, and LR . */ + + back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy); + lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy); + + back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0); + + if ((ret = + dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0) + { + Debug (2, + "Unable to retrieve CFA from back chain in stack frame - %d\n", + ret); + return ret; + } + if (c->dwarf.cfa == 0) + /* Unless the cursor or stack is corrupt or uninitialized we've most + likely hit the top of the stack */ + return 0; + + lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0); + + if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0) + { + Debug (2, + "Unable to retrieve IP from lr save in stack frame - %d\n", + ret); + return ret; + } + ret = 1; + } + else + { + /* Find the sigcontext record by taking the CFA and adjusting by + the dummy signal frame size. + + Note that there isn't any way to determined if SA_SIGINFO was + set in the sa_flags parameter to sigaction when the signal + handler was established. If it was not set, the ucontext + record is not required to be on the stack, in which case the + following code will likely cause a seg fault or other crash + condition. */ + + unw_word_t ucontext = c->dwarf.cfa + __SIGNAL_FRAMESIZE; + + Debug (1, "signal frame, skip over trampoline\n"); + + c->sigcontext_format = PPC_SCF_LINUX_RT_SIGFRAME; + c->sigcontext_addr = ucontext; + + sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); + ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0); + + ret = dwarf_get (&c->dwarf, sp_loc, &c->dwarf.cfa); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + ret = dwarf_get (&c->dwarf, ip_loc, &c->dwarf.ip); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + /* Instead of just restoring the non-volatile registers, do all + of the registers for now. This will incur a performance hit, + but it's rare enough not to cause too much of a problem, and + might be useful in some cases. */ + c->dwarf.loc[UNW_PPC32_R0] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R0, 0); + c->dwarf.loc[UNW_PPC32_R1] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); + c->dwarf.loc[UNW_PPC32_R2] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R2, 0); + c->dwarf.loc[UNW_PPC32_R3] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R3, 0); + c->dwarf.loc[UNW_PPC32_R4] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R4, 0); + c->dwarf.loc[UNW_PPC32_R5] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R5, 0); + c->dwarf.loc[UNW_PPC32_R6] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R6, 0); + c->dwarf.loc[UNW_PPC32_R7] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R7, 0); + c->dwarf.loc[UNW_PPC32_R8] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); + c->dwarf.loc[UNW_PPC32_R9] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); + c->dwarf.loc[UNW_PPC32_R10] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); + c->dwarf.loc[UNW_PPC32_R11] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); + c->dwarf.loc[UNW_PPC32_R12] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); + c->dwarf.loc[UNW_PPC32_R13] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); + c->dwarf.loc[UNW_PPC32_R14] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); + c->dwarf.loc[UNW_PPC32_R15] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); + c->dwarf.loc[UNW_PPC32_R16] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R16, 0); + c->dwarf.loc[UNW_PPC32_R17] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R17, 0); + c->dwarf.loc[UNW_PPC32_R18] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R18, 0); + c->dwarf.loc[UNW_PPC32_R19] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R19, 0); + c->dwarf.loc[UNW_PPC32_R20] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R20, 0); + c->dwarf.loc[UNW_PPC32_R21] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R21, 0); + c->dwarf.loc[UNW_PPC32_R22] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R22, 0); + c->dwarf.loc[UNW_PPC32_R23] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R23, 0); + c->dwarf.loc[UNW_PPC32_R24] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R24, 0); + c->dwarf.loc[UNW_PPC32_R25] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R25, 0); + c->dwarf.loc[UNW_PPC32_R26] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R26, 0); + c->dwarf.loc[UNW_PPC32_R27] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R27, 0); + c->dwarf.loc[UNW_PPC32_R28] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R28, 0); + c->dwarf.loc[UNW_PPC32_R29] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R29, 0); + c->dwarf.loc[UNW_PPC32_R30] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R30, 0); + c->dwarf.loc[UNW_PPC32_R31] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R31, 0); + + c->dwarf.loc[UNW_PPC32_LR] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0); + c->dwarf.loc[UNW_PPC32_CTR] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CTR, 0); + + /* This CR0 assignment is probably wrong. There are 8 dwarf columns + assigned to the CR registers, but only one CR register in the + mcontext structure */ + c->dwarf.loc[UNW_PPC32_CCR] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0); + c->dwarf.loc[UNW_PPC32_XER] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0); + + c->dwarf.loc[UNW_PPC32_F0] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0); + c->dwarf.loc[UNW_PPC32_F1] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R1, 0); + c->dwarf.loc[UNW_PPC32_F2] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R2, 0); + c->dwarf.loc[UNW_PPC32_F3] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R3, 0); + c->dwarf.loc[UNW_PPC32_F4] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R4, 0); + c->dwarf.loc[UNW_PPC32_F5] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R5, 0); + c->dwarf.loc[UNW_PPC32_F6] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R6, 0); + c->dwarf.loc[UNW_PPC32_F7] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R7, 0); + c->dwarf.loc[UNW_PPC32_F8] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R8, 0); + c->dwarf.loc[UNW_PPC32_F9] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R9, 0); + c->dwarf.loc[UNW_PPC32_F10] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R10, 0); + c->dwarf.loc[UNW_PPC32_F11] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R11, 0); + c->dwarf.loc[UNW_PPC32_F12] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R12, 0); + c->dwarf.loc[UNW_PPC32_F13] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R13, 0); + c->dwarf.loc[UNW_PPC32_F14] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R14, 0); + c->dwarf.loc[UNW_PPC32_F15] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R15, 0); + c->dwarf.loc[UNW_PPC32_F16] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R16, 0); + c->dwarf.loc[UNW_PPC32_F17] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R17, 0); + c->dwarf.loc[UNW_PPC32_F18] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R18, 0); + c->dwarf.loc[UNW_PPC32_F19] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R19, 0); + c->dwarf.loc[UNW_PPC32_F20] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R20, 0); + c->dwarf.loc[UNW_PPC32_F21] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R21, 0); + c->dwarf.loc[UNW_PPC32_F22] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R22, 0); + c->dwarf.loc[UNW_PPC32_F23] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R23, 0); + c->dwarf.loc[UNW_PPC32_F24] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R24, 0); + c->dwarf.loc[UNW_PPC32_F25] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R25, 0); + c->dwarf.loc[UNW_PPC32_F26] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R26, 0); + c->dwarf.loc[UNW_PPC32_F27] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R27, 0); + c->dwarf.loc[UNW_PPC32_F28] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R28, 0); + c->dwarf.loc[UNW_PPC32_F29] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R29, 0); + c->dwarf.loc[UNW_PPC32_F30] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R30, 0); + c->dwarf.loc[UNW_PPC32_F31] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R31, 0); + + ret = 1; + } + } + return ret; +} diff --git a/src/libs/libunwind/ppc32/Lcreate_addr_space.c b/src/libs/libunwind/ppc32/Lcreate_addr_space.c new file mode 100644 index 0000000000..0f2dc6be90 --- /dev/null +++ b/src/libs/libunwind/ppc32/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/libs/libunwind/ppc32/Lglobal.c b/src/libs/libunwind/ppc32/Lglobal.c new file mode 100644 index 0000000000..6d7b489e14 --- /dev/null +++ b/src/libs/libunwind/ppc32/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/libs/libunwind/ppc32/Linit.c b/src/libs/libunwind/ppc32/Linit.c new file mode 100644 index 0000000000..e9abfdd46a --- /dev/null +++ b/src/libs/libunwind/ppc32/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/libs/libunwind/ppc32/Lregs.c b/src/libs/libunwind/ppc32/Lregs.c new file mode 100644 index 0000000000..2c9c75cd7d --- /dev/null +++ b/src/libs/libunwind/ppc32/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/libs/libunwind/ppc32/Lresume.c b/src/libs/libunwind/ppc32/Lresume.c new file mode 100644 index 0000000000..41a8cf003d --- /dev/null +++ b/src/libs/libunwind/ppc32/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/libs/libunwind/ppc32/Lstep.c b/src/libs/libunwind/ppc32/Lstep.c new file mode 100644 index 0000000000..c1ac3c7547 --- /dev/null +++ b/src/libs/libunwind/ppc32/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/libs/libunwind/ppc32/get_func_addr.c b/src/libs/libunwind/ppc32/get_func_addr.c new file mode 100644 index 0000000000..66ff795fe7 --- /dev/null +++ b/src/libs/libunwind/ppc32/get_func_addr.c @@ -0,0 +1,36 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +tdep_get_func_addr (unw_addr_space_t as, unw_word_t symbol_val_addr, + unw_word_t *real_func_addr) +{ + *real_func_addr = symbol_val_addr; + return 0; +} diff --git a/src/libs/libunwind/ppc32/init.h b/src/libs/libunwind/ppc32/init.h new file mode 100644 index 0000000000..e8bb3ba563 --- /dev/null +++ b/src/libs/libunwind/ppc32/init.h @@ -0,0 +1,73 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* Here is the "common" init, for remote and local debuging" */ + +static inline int +common_init_ppc32 (struct cursor *c, unsigned use_prev_instr) +{ + int ret; + int i; + + for (i = UNW_PPC32_R0; i <= UNW_PPC32_R31; i++) { + c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i); + } + for (i = UNW_PPC32_F0; i <= UNW_PPC32_F31; i++) { + c->dwarf.loc[i] = DWARF_FPREG_LOC (&c->dwarf, i); + } + + c->dwarf.loc[UNW_PPC32_CTR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_CTR); + c->dwarf.loc[UNW_PPC32_XER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_XER); + c->dwarf.loc[UNW_PPC32_CCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_CCR); + c->dwarf.loc[UNW_PPC32_LR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_LR); + c->dwarf.loc[UNW_PPC32_FPSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_FPSCR); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_PPC32_LR], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_PPC32_R1), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = PPC_SCF_NONE; + c->sigcontext_addr = 0; + + c->dwarf.args_size = 0; + c->dwarf.ret_addr_column = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/libs/libunwind/ppc32/is_fpreg.c b/src/libs/libunwind/ppc32/is_fpreg.c new file mode 100644 index 0000000000..cccc5112bc --- /dev/null +++ b/src/libs/libunwind/ppc32/is_fpreg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED int +unw_is_fpreg (int regnum) +{ + return (regnum >= UNW_PPC32_F0 && regnum <= UNW_PPC32_F31); +} diff --git a/src/libs/libunwind/ppc32/regname.c b/src/libs/libunwind/ppc32/regname.c new file mode 100644 index 0000000000..79ba88aa56 --- /dev/null +++ b/src/libs/libunwind/ppc32/regname.c @@ -0,0 +1,112 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + [UNW_PPC32_R0]="GPR0", + [UNW_PPC32_R1]="GPR1", + [UNW_PPC32_R2]="GPR2", + [UNW_PPC32_R3]="GPR3", + [UNW_PPC32_R4]="GPR4", + [UNW_PPC32_R5]="GPR5", + [UNW_PPC32_R6]="GPR6", + [UNW_PPC32_R7]="GPR7", + [UNW_PPC32_R8]="GPR8", + [UNW_PPC32_R9]="GPR9", + [UNW_PPC32_R10]="GPR10", + [UNW_PPC32_R11]="GPR11", + [UNW_PPC32_R12]="GPR12", + [UNW_PPC32_R13]="GPR13", + [UNW_PPC32_R14]="GPR14", + [UNW_PPC32_R15]="GPR15", + [UNW_PPC32_R16]="GPR16", + [UNW_PPC32_R17]="GPR17", + [UNW_PPC32_R18]="GPR18", + [UNW_PPC32_R19]="GPR19", + [UNW_PPC32_R20]="GPR20", + [UNW_PPC32_R21]="GPR21", + [UNW_PPC32_R22]="GPR22", + [UNW_PPC32_R23]="GPR23", + [UNW_PPC32_R24]="GPR24", + [UNW_PPC32_R25]="GPR25", + [UNW_PPC32_R26]="GPR26", + [UNW_PPC32_R27]="GPR27", + [UNW_PPC32_R28]="GPR28", + [UNW_PPC32_R29]="GPR29", + [UNW_PPC32_R30]="GPR30", + [UNW_PPC32_R31]="GPR31", + + [UNW_PPC32_CTR]="CTR", + [UNW_PPC32_XER]="XER", + [UNW_PPC32_CCR]="CCR", + [UNW_PPC32_LR]="LR", + [UNW_PPC32_FPSCR]="FPSCR", + + [UNW_PPC32_F0]="FPR0", + [UNW_PPC32_F1]="FPR1", + [UNW_PPC32_F2]="FPR2", + [UNW_PPC32_F3]="FPR3", + [UNW_PPC32_F4]="FPR4", + [UNW_PPC32_F5]="FPR5", + [UNW_PPC32_F6]="FPR6", + [UNW_PPC32_F7]="FPR7", + [UNW_PPC32_F8]="FPR8", + [UNW_PPC32_F9]="FPR9", + [UNW_PPC32_F10]="FPR10", + [UNW_PPC32_F11]="FPR11", + [UNW_PPC32_F12]="FPR12", + [UNW_PPC32_F13]="FPR13", + [UNW_PPC32_F14]="FPR14", + [UNW_PPC32_F15]="FPR15", + [UNW_PPC32_F16]="FPR16", + [UNW_PPC32_F17]="FPR17", + [UNW_PPC32_F18]="FPR18", + [UNW_PPC32_F19]="FPR19", + [UNW_PPC32_F20]="FPR20", + [UNW_PPC32_F21]="FPR21", + [UNW_PPC32_F22]="FPR22", + [UNW_PPC32_F23]="FPR23", + [UNW_PPC32_F24]="FPR24", + [UNW_PPC32_F25]="FPR25", + [UNW_PPC32_F26]="FPR26", + [UNW_PPC32_F27]="FPR27", + [UNW_PPC32_F28]="FPR28", + [UNW_PPC32_F29]="FPR29", + [UNW_PPC32_F30]="FPR30", + [UNW_PPC32_F31]="FPR31" +}; + +PROTECTED const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/libs/libunwind/ppc32/setcontext.S b/src/libs/libunwind/ppc32/setcontext.S new file mode 100644 index 0000000000..b54378a9dc --- /dev/null +++ b/src/libs/libunwind/ppc32/setcontext.S @@ -0,0 +1,9 @@ + .global _UI_setcontext + +_UI_setcontext: + retq + +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/ppc32/ucontext_i.h b/src/libs/libunwind/ppc32/ucontext_i.h new file mode 100644 index 0000000000..c6ba806a00 --- /dev/null +++ b/src/libs/libunwind/ppc32/ucontext_i.h @@ -0,0 +1,128 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef ucontext_i_h +#define ucontext_i_h + +#include "compiler.h" +#include + +/* These values were derived by reading + /usr/src/linux-2.6.18-1.8/arch/um/include/sysdep-ppc/ptrace.h and + /usr/src/linux-2.6.18-1.8/arch/powerpc/kernel/ppc32.h +*/ + +//#define NIP_IDX 32 +#define CTR_IDX 32 +#define XER_IDX 33 +#define CCR_IDX 34 +#define MSR_IDX 35 +//#define MQ_IDX 36 +#define LINK_IDX 36 + +/* These are dummy structures used only for obtaining the offsets of the + various structure members. */ +static ucontext_t dmy_ctxt UNUSED; + +#define UC_MCONTEXT_GREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[0] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[1] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[2] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[3] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[4] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[5] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[6] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[7] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[8] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[9] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[10] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[11] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[12] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[13] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[14] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[15] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[16] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[17] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[18] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[19] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[20] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[21] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[22] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[23] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[24] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[25] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[26] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[27] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[28] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[29] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[30] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[31] - (void *)&dmy_ctxt) + +#define UC_MCONTEXT_GREGS_MSR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[MSR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_ORIG_GPR3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[ORIG_GPR3_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_CTR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[CTR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_LINK ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[LINK_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_XER ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[XER_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_CCR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[CCR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_SOFTE ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[SOFTE_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_TRAP ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[TRAP_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_DAR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[DAR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_DSISR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[DSISR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_RESULT ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[RESULT_IDX] - (void *)&dmy_ctxt) + +#define UC_MCONTEXT_FREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[0] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[1] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[2] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[3] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[4] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[5] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[6] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[7] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[8] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[9] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[10] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[11] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[12] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[13] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[14] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[15] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[16] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[17] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[18] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[19] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[20] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[21] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[22] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[23] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[24] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[25] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[26] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[27] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[28] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[29] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[30] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[31] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_FPSCR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[32] - (void *)&dmy_ctxt) + +#endif diff --git a/src/libs/libunwind/ppc32/unwind_i.h b/src/libs/libunwind/ppc32/unwind_i.h new file mode 100644 index 0000000000..ad32d05654 --- /dev/null +++ b/src/libs/libunwind/ppc32/unwind_i.h @@ -0,0 +1,46 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include + +#include + +#include +#include + +#define ppc32_lock UNW_OBJ(lock) +#define ppc32_local_resume UNW_OBJ(local_resume) +#define ppc32_local_addr_space_init UNW_OBJ(local_addr_space_init) + +extern void ppc32_local_addr_space_init (void); +extern int ppc32_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); + +#endif /* unwind_i_h */ diff --git a/src/libs/libunwind/ppc64/Gcreate_addr_space.c b/src/libs/libunwind/ppc64/Gcreate_addr_space.c new file mode 100644 index 0000000000..686653a96e --- /dev/null +++ b/src/libs/libunwind/ppc64/Gcreate_addr_space.c @@ -0,0 +1,71 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include + +PROTECTED unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * We support both big- and little-endian on Linux ppc64. + */ + if (byte_order != 0 + && byte_order != __LITTLE_ENDIAN + && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + if (byte_order == 0) + /* use host default: */ + as->big_endian = (__BYTE_ORDER == __BIG_ENDIAN); + else + as->big_endian = (byte_order == __BIG_ENDIAN); + + /* FIXME! There is no way to specify the ABI. + Default to ELFv1 on big-endian and ELFv2 on little-endian. */ + if (as->big_endian) + as->abi = UNW_PPC64_ABI_ELFv1; + else + as->abi = UNW_PPC64_ABI_ELFv2; + + return as; +#endif +} diff --git a/src/libs/libunwind/ppc64/Gglobal.c b/src/libs/libunwind/ppc64/Gglobal.c new file mode 100644 index 0000000000..9d0b0f55a6 --- /dev/null +++ b/src/libs/libunwind/ppc64/Gglobal.c @@ -0,0 +1,182 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (ppc64_lock); +HIDDEN int tdep_init_done; + +/* The API register numbers are exactly the same as the .eh_frame + registers, for now at least. */ +HIDDEN const uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH] = + { + [UNW_PPC64_R0]=UNW_PPC64_R0, + [UNW_PPC64_R1]=UNW_PPC64_R1, + [UNW_PPC64_R2]=UNW_PPC64_R2, + [UNW_PPC64_R3]=UNW_PPC64_R3, + [UNW_PPC64_R4]=UNW_PPC64_R4, + [UNW_PPC64_R5]=UNW_PPC64_R5, + [UNW_PPC64_R6]=UNW_PPC64_R6, + [UNW_PPC64_R7]=UNW_PPC64_R7, + [UNW_PPC64_R8]=UNW_PPC64_R8, + [UNW_PPC64_R9]=UNW_PPC64_R9, + [UNW_PPC64_R10]=UNW_PPC64_R10, + [UNW_PPC64_R11]=UNW_PPC64_R11, + [UNW_PPC64_R12]=UNW_PPC64_R12, + [UNW_PPC64_R13]=UNW_PPC64_R13, + [UNW_PPC64_R14]=UNW_PPC64_R14, + [UNW_PPC64_R15]=UNW_PPC64_R15, + [UNW_PPC64_R16]=UNW_PPC64_R16, + [UNW_PPC64_R17]=UNW_PPC64_R17, + [UNW_PPC64_R18]=UNW_PPC64_R18, + [UNW_PPC64_R19]=UNW_PPC64_R19, + [UNW_PPC64_R20]=UNW_PPC64_R20, + [UNW_PPC64_R21]=UNW_PPC64_R21, + [UNW_PPC64_R22]=UNW_PPC64_R22, + [UNW_PPC64_R23]=UNW_PPC64_R23, + [UNW_PPC64_R24]=UNW_PPC64_R24, + [UNW_PPC64_R25]=UNW_PPC64_R25, + [UNW_PPC64_R26]=UNW_PPC64_R26, + [UNW_PPC64_R27]=UNW_PPC64_R27, + [UNW_PPC64_R28]=UNW_PPC64_R28, + [UNW_PPC64_R29]=UNW_PPC64_R29, + [UNW_PPC64_R30]=UNW_PPC64_R30, + [UNW_PPC64_R31]=UNW_PPC64_R31, + + [UNW_PPC64_F0]=UNW_PPC64_F0, + [UNW_PPC64_F1]=UNW_PPC64_F1, + [UNW_PPC64_F2]=UNW_PPC64_F2, + [UNW_PPC64_F3]=UNW_PPC64_F3, + [UNW_PPC64_F4]=UNW_PPC64_F4, + [UNW_PPC64_F5]=UNW_PPC64_F5, + [UNW_PPC64_F6]=UNW_PPC64_F6, + [UNW_PPC64_F7]=UNW_PPC64_F7, + [UNW_PPC64_F8]=UNW_PPC64_F8, + [UNW_PPC64_F9]=UNW_PPC64_F9, + [UNW_PPC64_F10]=UNW_PPC64_F10, + [UNW_PPC64_F11]=UNW_PPC64_F11, + [UNW_PPC64_F12]=UNW_PPC64_F12, + [UNW_PPC64_F13]=UNW_PPC64_F13, + [UNW_PPC64_F14]=UNW_PPC64_F14, + [UNW_PPC64_F15]=UNW_PPC64_F15, + [UNW_PPC64_F16]=UNW_PPC64_F16, + [UNW_PPC64_F17]=UNW_PPC64_F17, + [UNW_PPC64_F18]=UNW_PPC64_F18, + [UNW_PPC64_F19]=UNW_PPC64_F19, + [UNW_PPC64_F20]=UNW_PPC64_F20, + [UNW_PPC64_F21]=UNW_PPC64_F21, + [UNW_PPC64_F22]=UNW_PPC64_F22, + [UNW_PPC64_F23]=UNW_PPC64_F23, + [UNW_PPC64_F24]=UNW_PPC64_F24, + [UNW_PPC64_F25]=UNW_PPC64_F25, + [UNW_PPC64_F26]=UNW_PPC64_F26, + [UNW_PPC64_F27]=UNW_PPC64_F27, + [UNW_PPC64_F28]=UNW_PPC64_F28, + [UNW_PPC64_F29]=UNW_PPC64_F29, + [UNW_PPC64_F30]=UNW_PPC64_F30, + [UNW_PPC64_F31]=UNW_PPC64_F31, + + [UNW_PPC64_LR]=UNW_PPC64_LR, + [UNW_PPC64_CTR]=UNW_PPC64_CTR, + [UNW_PPC64_ARG_POINTER]=UNW_PPC64_ARG_POINTER, + + [UNW_PPC64_CR0]=UNW_PPC64_CR0, + [UNW_PPC64_CR1]=UNW_PPC64_CR1, + [UNW_PPC64_CR2]=UNW_PPC64_CR2, + [UNW_PPC64_CR3]=UNW_PPC64_CR3, + [UNW_PPC64_CR4]=UNW_PPC64_CR4, + [UNW_PPC64_CR5]=UNW_PPC64_CR5, + [UNW_PPC64_CR6]=UNW_PPC64_CR6, + [UNW_PPC64_CR7]=UNW_PPC64_CR7, + + [UNW_PPC64_XER]=UNW_PPC64_XER, + + [UNW_PPC64_V0]=UNW_PPC64_V0, + [UNW_PPC64_V1]=UNW_PPC64_V1, + [UNW_PPC64_V2]=UNW_PPC64_V2, + [UNW_PPC64_V3]=UNW_PPC64_V3, + [UNW_PPC64_V4]=UNW_PPC64_V4, + [UNW_PPC64_V5]=UNW_PPC64_V5, + [UNW_PPC64_V6]=UNW_PPC64_V6, + [UNW_PPC64_V7]=UNW_PPC64_V7, + [UNW_PPC64_V8]=UNW_PPC64_V8, + [UNW_PPC64_V9]=UNW_PPC64_V9, + [UNW_PPC64_V10]=UNW_PPC64_V10, + [UNW_PPC64_V11]=UNW_PPC64_V11, + [UNW_PPC64_V12]=UNW_PPC64_V12, + [UNW_PPC64_V13]=UNW_PPC64_V13, + [UNW_PPC64_V14]=UNW_PPC64_V14, + [UNW_PPC64_V15]=UNW_PPC64_V15, + [UNW_PPC64_V16]=UNW_PPC64_V16, + [UNW_PPC64_V17]=UNW_PPC64_V17, + [UNW_PPC64_V18]=UNW_PPC64_V18, + [UNW_PPC64_V19]=UNW_PPC64_V19, + [UNW_PPC64_V20]=UNW_PPC64_V20, + [UNW_PPC64_V21]=UNW_PPC64_V21, + [UNW_PPC64_V22]=UNW_PPC64_V22, + [UNW_PPC64_V23]=UNW_PPC64_V23, + [UNW_PPC64_V24]=UNW_PPC64_V24, + [UNW_PPC64_V25]=UNW_PPC64_V25, + [UNW_PPC64_V26]=UNW_PPC64_V26, + [UNW_PPC64_V27]=UNW_PPC64_V27, + [UNW_PPC64_V28]=UNW_PPC64_V28, + [UNW_PPC64_V29]=UNW_PPC64_V29, + [UNW_PPC64_V30]=UNW_PPC64_V30, + [UNW_PPC64_V31]=UNW_PPC64_V31, + + [UNW_PPC64_VRSAVE]=UNW_PPC64_VRSAVE, + [UNW_PPC64_VSCR]=UNW_PPC64_VSCR, + [UNW_PPC64_SPE_ACC]=UNW_PPC64_SPE_ACC, + [UNW_PPC64_SPEFSCR]=UNW_PPC64_SPEFSCR, + }; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&ppc64_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + ppc64_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&ppc64_lock, saved_mask); +} diff --git a/src/libs/libunwind/ppc64/Ginit.c b/src/libs/libunwind/ppc64/Ginit.c new file mode 100644 index 0000000000..0740961085 --- /dev/null +++ b/src/libs/libunwind/ppc64/Ginit.c @@ -0,0 +1,231 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "ucontext_i.h" +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +PROTECTED unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static void * +uc_addr (ucontext_t *uc, int reg) +{ + void *addr; + + if ((unsigned) (reg - UNW_PPC64_R0) < 32) + addr = &uc->uc_mcontext.gp_regs[reg - UNW_PPC64_R0]; + + else if ((unsigned) (reg - UNW_PPC64_F0) < 32) + addr = &uc->uc_mcontext.fp_regs[reg - UNW_PPC64_F0]; + + else if ((unsigned) (reg - UNW_PPC64_V0) < 32) + addr = (uc->uc_mcontext.v_regs == 0) ? NULL : &uc->uc_mcontext.v_regs->vrregs[reg - UNW_PPC64_V0][0]; + + else + { + unsigned gregs_idx; + + switch (reg) + { + case UNW_PPC64_NIP: + gregs_idx = NIP_IDX; + break; + case UNW_PPC64_CTR: + gregs_idx = CTR_IDX; + break; + case UNW_PPC64_LR: + gregs_idx = LINK_IDX; + break; + case UNW_PPC64_XER: + gregs_idx = XER_IDX; + break; + case UNW_PPC64_CR0: + gregs_idx = CCR_IDX; + break; + default: + return NULL; + } + addr = &uc->uc_mcontext.gp_regs[gregs_idx]; + } + return addr; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (12, "mem[%lx] <- %lx\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "mem[%lx] -> %lx\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, + int write, void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = arg; + + if (UNW_PPC64_F0 <= reg && reg <= UNW_PPC64_F31) + goto badreg; + if (UNW_PPC64_V0 <= reg && reg <= UNW_PPC64_V31) + goto badreg; + + addr = uc_addr (uc, reg); + if (!addr) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %lx\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %lx\n", unw_regname (reg), *val); + } + return 0; + +badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + unw_fpreg_t *addr; + + if ((reg - UNW_PPC64_F0) < 0) + goto badreg; + + if ((unsigned) (reg - UNW_PPC64_V0) >= 32) + goto badreg; + + + addr = uc_addr (uc, reg); + if (!addr) + goto badreg; + + if (write) + { + Debug (12, "%s <- %016Lf\n", unw_regname (reg), *val); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %016Lf\n", unw_regname (reg), *val); + } + return 0; + +badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +ppc64_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); +#if _CALL_ELF == 2 + local_addr_space.abi = UNW_PPC64_ABI_ELFv2; +#else + local_addr_space.abi = UNW_PPC64_ABI_ELFv1; +#endif + local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = ppc64_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/ppc64/Gregs.c b/src/libs/libunwind/ppc64/Gregs.c new file mode 100644 index 0000000000..1cb5d9dc65 --- /dev/null +++ b/src/libs/libunwind/ppc64/Gregs.c @@ -0,0 +1,141 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + struct dwarf_loc loc; + + switch (reg) + { + case UNW_PPC64_R0: + case UNW_PPC64_R2: + case UNW_PPC64_R3: + case UNW_PPC64_R4: + case UNW_PPC64_R5: + case UNW_PPC64_R6: + case UNW_PPC64_R7: + case UNW_PPC64_R8: + case UNW_PPC64_R9: + case UNW_PPC64_R10: + case UNW_PPC64_R11: + case UNW_PPC64_R12: + case UNW_PPC64_R13: + case UNW_PPC64_R14: + case UNW_PPC64_R15: + case UNW_PPC64_R16: + case UNW_PPC64_R17: + case UNW_PPC64_R18: + case UNW_PPC64_R19: + case UNW_PPC64_R20: + case UNW_PPC64_R21: + case UNW_PPC64_R22: + case UNW_PPC64_R23: + case UNW_PPC64_R24: + case UNW_PPC64_R25: + case UNW_PPC64_R26: + case UNW_PPC64_R27: + case UNW_PPC64_R28: + case UNW_PPC64_R29: + case UNW_PPC64_R30: + case UNW_PPC64_R31: + case UNW_PPC64_LR: + case UNW_PPC64_CTR: + case UNW_PPC64_CR0: + case UNW_PPC64_CR1: + case UNW_PPC64_CR2: + case UNW_PPC64_CR3: + case UNW_PPC64_CR4: + case UNW_PPC64_CR5: + case UNW_PPC64_CR6: + case UNW_PPC64_CR7: + case UNW_PPC64_VRSAVE: + case UNW_PPC64_VSCR: + case UNW_PPC64_SPE_ACC: + case UNW_PPC64_SPEFSCR: + loc = c->dwarf.loc[reg]; + break; + + case UNW_TDEP_IP: + if (write) + { + c->dwarf.ip = *valp; /* update the IP cache */ + if (c->dwarf.pi_valid && (*valp < c->dwarf.pi.start_ip + || *valp >= c->dwarf.pi.end_ip)) + c->dwarf.pi_valid = 0; /* new IP outside of current proc */ + } + else + *valp = c->dwarf.ip; + return 0; + + case UNW_TDEP_SP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + default: + return -UNW_EBADREG; + break; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + struct dwarf_loc loc; + + if ((unsigned) (reg - UNW_PPC64_F0) < 32) + { + loc = c->dwarf.loc[reg]; + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); + } + else + if ((unsigned) (reg - UNW_PPC64_V0) < 32) + { + loc = c->dwarf.loc[reg]; + if (write) + return dwarf_putvr (&c->dwarf, loc, *valp); + else + return dwarf_getvr (&c->dwarf, loc, valp); + } + + return -UNW_EBADREG; +} + diff --git a/src/libs/libunwind/ppc64/Gresume.c b/src/libs/libunwind/ppc64/Gresume.c new file mode 100644 index 0000000000..2edeca63fd --- /dev/null +++ b/src/libs/libunwind/ppc64/Gresume.c @@ -0,0 +1,111 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford cjashfor@us.ibm.com + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#ifndef UNW_REMOTE_ONLY + +#include + +/* sigreturn() is a no-op on x86_64 glibc. */ + +static NORETURN inline long +my_rt_sigreturn (void *new_sp) +{ + /* XXX: empty stub. */ + abort (); +} + +HIDDEN inline int +ppc64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = (ucontext_t *)c->dwarf.as_arg; + + if (unlikely (c->sigcontext_format != PPC_SCF_NONE)) + { + my_rt_sigreturn(cursor); + abort(); + } + else + { + Debug (8, "resuming at ip=%llx via setcontext()\n", + (unsigned long long) c->dwarf.ip); + setcontext (uc); + } + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +/* This routine is responsible for copying the register values in + cursor C and establishing them as the current machine state. */ + +static inline int +establish_machine_state (struct cursor *c) +{ + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + as->acc.access_fpreg (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + as->acc.access_reg (as, reg, &val, 1, arg); + } + } + return 0; +} + +PROTECTED int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if ((ret = establish_machine_state (c)) < 0) + return ret; + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/libs/libunwind/ppc64/Gstep.c b/src/libs/libunwind/ppc64/Gstep.c new file mode 100644 index 0000000000..6170adc53c --- /dev/null +++ b/src/libs/libunwind/ppc64/Gstep.c @@ -0,0 +1,450 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "ucontext_i.h" +#include + +/* This definition originates in /usr/include/asm-ppc64/ptrace.h, but is + defined there only when __KERNEL__ is defined. We reproduce it here for + our use at the user level in order to locate the ucontext record, which + appears to be at this offset relative to the stack pointer when in the + context of the signal handler return trampoline code - + __kernel_sigtramp_rt64. */ +#define __SIGNAL_FRAMESIZE 128 + +/* This definition comes from the document "64-bit PowerPC ELF Application + Binary Interface Supplement 1.9", section 3.2.2. + http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK */ + +typedef struct +{ + long unsigned back_chain; + long unsigned cr_save; + long unsigned lr_save; + /* many more fields here, but they are unused by this code */ +} stack_frame_t; + + +PROTECTED int +unw_step (unw_cursor_t * cursor) +{ + struct cursor *c = (struct cursor *) cursor; + stack_frame_t dummy; + unw_word_t back_chain_offset, lr_save_offset, v_regs_ptr; + struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc, v_regs_loc; + int ret; + + Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip); + + if (c->dwarf.ip == 0) + { + /* Unless the cursor or stack is corrupt or uninitialized, + we've most likely hit the top of the stack */ + return 0; + } + + /* Try DWARF-based unwinding... */ + + ret = dwarf_step (&c->dwarf); + + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + if (unlikely (ret < 0)) + { + if (likely (!unw_is_signal_frame (cursor))) + { + /* DWARF unwinding failed. As of 09/26/2006, gcc in 64-bit mode + produces the mandatory level of traceback record in the code, but + I get the impression that this is transitory, that eventually gcc + will not produce any traceback records at all. So, for now, we + won't bother to try to find and use these records. + + We can, however, attempt to unwind the frame by using the callback + chain. This is very crude, however, and won't be able to unwind + any registers besides the IP, SP, and LR . */ + + back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy); + lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy); + + back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0); + + if ((ret = + dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0) + { + Debug (2, + "Unable to retrieve CFA from back chain in stack frame - %d\n", + ret); + return ret; + } + if (c->dwarf.cfa == 0) + /* Unless the cursor or stack is corrupt or uninitialized we've most + likely hit the top of the stack */ + return 0; + + lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0); + + if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0) + { + Debug (2, + "Unable to retrieve IP from lr save in stack frame - %d\n", + ret); + return ret; + } + ret = 1; + } + else + { + /* Find the sigcontext record by taking the CFA and adjusting by + the dummy signal frame size. + + Note that there isn't any way to determined if SA_SIGINFO was + set in the sa_flags parameter to sigaction when the signal + handler was established. If it was not set, the ucontext + record is not required to be on the stack, in which case the + following code will likely cause a seg fault or other crash + condition. */ + + unw_word_t ucontext = c->dwarf.cfa + __SIGNAL_FRAMESIZE; + + Debug (1, "signal frame, skip over trampoline\n"); + + c->sigcontext_format = PPC_SCF_LINUX_RT_SIGFRAME; + c->sigcontext_addr = ucontext; + + sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); + ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0); + + ret = dwarf_get (&c->dwarf, sp_loc, &c->dwarf.cfa); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + ret = dwarf_get (&c->dwarf, ip_loc, &c->dwarf.ip); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + /* Instead of just restoring the non-volatile registers, do all + of the registers for now. This will incur a performance hit, + but it's rare enough not to cause too much of a problem, and + might be useful in some cases. */ + c->dwarf.loc[UNW_PPC64_R0] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R0, 0); + c->dwarf.loc[UNW_PPC64_R1] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); + c->dwarf.loc[UNW_PPC64_R2] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R2, 0); + c->dwarf.loc[UNW_PPC64_R3] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R3, 0); + c->dwarf.loc[UNW_PPC64_R4] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R4, 0); + c->dwarf.loc[UNW_PPC64_R5] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R5, 0); + c->dwarf.loc[UNW_PPC64_R6] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R6, 0); + c->dwarf.loc[UNW_PPC64_R7] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R7, 0); + c->dwarf.loc[UNW_PPC64_R8] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); + c->dwarf.loc[UNW_PPC64_R9] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); + c->dwarf.loc[UNW_PPC64_R10] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); + c->dwarf.loc[UNW_PPC64_R11] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); + c->dwarf.loc[UNW_PPC64_R12] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); + c->dwarf.loc[UNW_PPC64_R13] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); + c->dwarf.loc[UNW_PPC64_R14] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); + c->dwarf.loc[UNW_PPC64_R15] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); + c->dwarf.loc[UNW_PPC64_R16] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R16, 0); + c->dwarf.loc[UNW_PPC64_R17] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R17, 0); + c->dwarf.loc[UNW_PPC64_R18] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R18, 0); + c->dwarf.loc[UNW_PPC64_R19] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R19, 0); + c->dwarf.loc[UNW_PPC64_R20] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R20, 0); + c->dwarf.loc[UNW_PPC64_R21] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R21, 0); + c->dwarf.loc[UNW_PPC64_R22] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R22, 0); + c->dwarf.loc[UNW_PPC64_R23] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R23, 0); + c->dwarf.loc[UNW_PPC64_R24] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R24, 0); + c->dwarf.loc[UNW_PPC64_R25] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R25, 0); + c->dwarf.loc[UNW_PPC64_R26] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R26, 0); + c->dwarf.loc[UNW_PPC64_R27] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R27, 0); + c->dwarf.loc[UNW_PPC64_R28] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R28, 0); + c->dwarf.loc[UNW_PPC64_R29] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R29, 0); + c->dwarf.loc[UNW_PPC64_R30] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R30, 0); + c->dwarf.loc[UNW_PPC64_R31] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R31, 0); + + c->dwarf.loc[UNW_PPC64_LR] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0); + c->dwarf.loc[UNW_PPC64_CTR] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CTR, 0); + /* This CR0 assignment is probably wrong. There are 8 dwarf columns + assigned to the CR registers, but only one CR register in the + mcontext structure */ + c->dwarf.loc[UNW_PPC64_CR0] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0); + c->dwarf.loc[UNW_PPC64_XER] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0); + c->dwarf.loc[UNW_PPC64_NIP] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0); + + /* TODO: Is there a way of obtaining the value of the + pseudo frame pointer (which is sp + some fixed offset, I + assume), based on the contents of the ucontext record + structure? For now, set this loc to null. */ + c->dwarf.loc[UNW_PPC64_FRAME_POINTER] = DWARF_NULL_LOC; + + c->dwarf.loc[UNW_PPC64_F0] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0); + c->dwarf.loc[UNW_PPC64_F1] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R1, 0); + c->dwarf.loc[UNW_PPC64_F2] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R2, 0); + c->dwarf.loc[UNW_PPC64_F3] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R3, 0); + c->dwarf.loc[UNW_PPC64_F4] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R4, 0); + c->dwarf.loc[UNW_PPC64_F5] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R5, 0); + c->dwarf.loc[UNW_PPC64_F6] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R6, 0); + c->dwarf.loc[UNW_PPC64_F7] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R7, 0); + c->dwarf.loc[UNW_PPC64_F8] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R8, 0); + c->dwarf.loc[UNW_PPC64_F9] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R9, 0); + c->dwarf.loc[UNW_PPC64_F10] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R10, 0); + c->dwarf.loc[UNW_PPC64_F11] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R11, 0); + c->dwarf.loc[UNW_PPC64_F12] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R12, 0); + c->dwarf.loc[UNW_PPC64_F13] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R13, 0); + c->dwarf.loc[UNW_PPC64_F14] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R14, 0); + c->dwarf.loc[UNW_PPC64_F15] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R15, 0); + c->dwarf.loc[UNW_PPC64_F16] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R16, 0); + c->dwarf.loc[UNW_PPC64_F17] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R17, 0); + c->dwarf.loc[UNW_PPC64_F18] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R18, 0); + c->dwarf.loc[UNW_PPC64_F19] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R19, 0); + c->dwarf.loc[UNW_PPC64_F20] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R20, 0); + c->dwarf.loc[UNW_PPC64_F21] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R21, 0); + c->dwarf.loc[UNW_PPC64_F22] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R22, 0); + c->dwarf.loc[UNW_PPC64_F23] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R23, 0); + c->dwarf.loc[UNW_PPC64_F24] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R24, 0); + c->dwarf.loc[UNW_PPC64_F25] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R25, 0); + c->dwarf.loc[UNW_PPC64_F26] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R26, 0); + c->dwarf.loc[UNW_PPC64_F27] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R27, 0); + c->dwarf.loc[UNW_PPC64_F28] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R28, 0); + c->dwarf.loc[UNW_PPC64_F29] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R29, 0); + c->dwarf.loc[UNW_PPC64_F30] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R30, 0); + c->dwarf.loc[UNW_PPC64_F31] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R31, 0); + /* Note that there is no .eh_section register column for the + FPSCR register. I don't know why this is. */ + + v_regs_loc = DWARF_LOC (ucontext + UC_MCONTEXT_V_REGS, 0); + ret = dwarf_get (&c->dwarf, v_regs_loc, &v_regs_ptr); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + if (v_regs_ptr != 0) + { + /* The v_regs_ptr is not null. Set all of the AltiVec locs */ + + c->dwarf.loc[UNW_PPC64_V0] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R0, 0); + c->dwarf.loc[UNW_PPC64_V1] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R1, 0); + c->dwarf.loc[UNW_PPC64_V2] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R2, 0); + c->dwarf.loc[UNW_PPC64_V3] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R3, 0); + c->dwarf.loc[UNW_PPC64_V4] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R4, 0); + c->dwarf.loc[UNW_PPC64_V5] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R5, 0); + c->dwarf.loc[UNW_PPC64_V6] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R6, 0); + c->dwarf.loc[UNW_PPC64_V7] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R7, 0); + c->dwarf.loc[UNW_PPC64_V8] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R8, 0); + c->dwarf.loc[UNW_PPC64_V9] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R9, 0); + c->dwarf.loc[UNW_PPC64_V10] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R10, 0); + c->dwarf.loc[UNW_PPC64_V11] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R11, 0); + c->dwarf.loc[UNW_PPC64_V12] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R12, 0); + c->dwarf.loc[UNW_PPC64_V13] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R13, 0); + c->dwarf.loc[UNW_PPC64_V14] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R14, 0); + c->dwarf.loc[UNW_PPC64_V15] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R15, 0); + c->dwarf.loc[UNW_PPC64_V16] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R16, 0); + c->dwarf.loc[UNW_PPC64_V17] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R17, 0); + c->dwarf.loc[UNW_PPC64_V18] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R18, 0); + c->dwarf.loc[UNW_PPC64_V19] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R19, 0); + c->dwarf.loc[UNW_PPC64_V20] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R20, 0); + c->dwarf.loc[UNW_PPC64_V21] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R21, 0); + c->dwarf.loc[UNW_PPC64_V22] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R22, 0); + c->dwarf.loc[UNW_PPC64_V23] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R23, 0); + c->dwarf.loc[UNW_PPC64_V24] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R24, 0); + c->dwarf.loc[UNW_PPC64_V25] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R25, 0); + c->dwarf.loc[UNW_PPC64_V26] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R26, 0); + c->dwarf.loc[UNW_PPC64_V27] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R27, 0); + c->dwarf.loc[UNW_PPC64_V28] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R28, 0); + c->dwarf.loc[UNW_PPC64_V29] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R29, 0); + c->dwarf.loc[UNW_PPC64_V30] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R30, 0); + c->dwarf.loc[UNW_PPC64_V31] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R31, 0); + c->dwarf.loc[UNW_PPC64_VRSAVE] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_VRSAVE, 0); + c->dwarf.loc[UNW_PPC64_VSCR] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_VSCR, 0); + } + else + { + c->dwarf.loc[UNW_PPC64_V0] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V1] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V2] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V3] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V4] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V5] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V6] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V7] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V8] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V9] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V10] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V11] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V12] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V13] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V14] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V15] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V16] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V17] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V18] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V19] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V20] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V21] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V22] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V23] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V24] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V25] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V26] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V27] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V28] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V29] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V30] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V31] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_VRSAVE] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_VSCR] = DWARF_NULL_LOC; + } + ret = 1; + } + } + + // on ppc64, R2 register is used as pointer to TOC + // section which is used for symbol lookup in PIC code + // ppc64 linker generates "ld r2, 24(r1)" instruction after each + // @plt call. We need restore R2, but only for @plt calls + { + unsigned int *inst = (unw_word_t*)c->dwarf.ip; + if (*inst == (0xE8410000 + 24)) { + // @plt call, restoring R2 from CFA+24 + c->dwarf.loc[UNW_PPC64_R2] = DWARF_LOC(c->dwarf.cfa + 24, 0); + } + } + + Debug (2, "returning %d with last return statement\n", ret); + return ret; +} diff --git a/src/libs/libunwind/ppc64/Lcreate_addr_space.c b/src/libs/libunwind/ppc64/Lcreate_addr_space.c new file mode 100644 index 0000000000..0f2dc6be90 --- /dev/null +++ b/src/libs/libunwind/ppc64/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/libs/libunwind/ppc64/Lglobal.c b/src/libs/libunwind/ppc64/Lglobal.c new file mode 100644 index 0000000000..6d7b489e14 --- /dev/null +++ b/src/libs/libunwind/ppc64/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/libs/libunwind/ppc64/Linit.c b/src/libs/libunwind/ppc64/Linit.c new file mode 100644 index 0000000000..e9abfdd46a --- /dev/null +++ b/src/libs/libunwind/ppc64/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/libs/libunwind/ppc64/Lregs.c b/src/libs/libunwind/ppc64/Lregs.c new file mode 100644 index 0000000000..2c9c75cd7d --- /dev/null +++ b/src/libs/libunwind/ppc64/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/libs/libunwind/ppc64/Lresume.c b/src/libs/libunwind/ppc64/Lresume.c new file mode 100644 index 0000000000..41a8cf003d --- /dev/null +++ b/src/libs/libunwind/ppc64/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/libs/libunwind/ppc64/Lstep.c b/src/libs/libunwind/ppc64/Lstep.c new file mode 100644 index 0000000000..c1ac3c7547 --- /dev/null +++ b/src/libs/libunwind/ppc64/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/libs/libunwind/ppc64/get_func_addr.c b/src/libs/libunwind/ppc64/get_func_addr.c new file mode 100644 index 0000000000..13abb7db88 --- /dev/null +++ b/src/libs/libunwind/ppc64/get_func_addr.c @@ -0,0 +1,51 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, + unw_word_t *entry_point) +{ + if (as->abi == UNW_PPC64_ABI_ELFv1) + { + unw_accessors_t *a; + int ret; + + a = unw_get_accessors (as); + /* Entry-point is stored in the 1st word of the function descriptor. + In case that changes in the future, we'd have to update the line + below and read the word at addr + offset: */ + ret = (*a->access_mem) (as, addr, entry_point, 0, NULL); + if (ret < 0) + return ret; + } + else + *entry_point = addr; + + return 0; +} diff --git a/src/libs/libunwind/ppc64/init.h b/src/libs/libunwind/ppc64/init.h new file mode 100644 index 0000000000..22376e71a4 --- /dev/null +++ b/src/libs/libunwind/ppc64/init.h @@ -0,0 +1,83 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init_ppc64 (struct cursor *c, unsigned use_prev_instr) +{ + int ret; + int i; + + for (i = UNW_PPC64_R0; i <= UNW_PPC64_R31; i++) { + c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i); + } + for (i = UNW_PPC64_F0; i <= UNW_PPC64_F31; i++) { + c->dwarf.loc[i] = DWARF_FPREG_LOC (&c->dwarf, i); + } + for (i = UNW_PPC64_V0; i <= UNW_PPC64_V31; i++) { + c->dwarf.loc[i] = DWARF_VREG_LOC (&c->dwarf, i); + } + + for (i = UNW_PPC64_CR0; i <= UNW_PPC64_CR7; i++) { + c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i); + } + c->dwarf.loc[UNW_PPC64_ARG_POINTER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_ARG_POINTER); + c->dwarf.loc[UNW_PPC64_CTR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_CTR); + c->dwarf.loc[UNW_PPC64_VSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_VSCR); + + c->dwarf.loc[UNW_PPC64_XER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_XER); + c->dwarf.loc[UNW_PPC64_LR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_LR); + c->dwarf.loc[UNW_PPC64_VRSAVE] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_VRSAVE); + c->dwarf.loc[UNW_PPC64_SPEFSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_SPEFSCR); + c->dwarf.loc[UNW_PPC64_SPE_ACC] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_SPE_ACC); + + c->dwarf.loc[UNW_PPC64_NIP] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_NIP); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_PPC64_NIP], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_PPC64_R1), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = PPC_SCF_NONE; + c->sigcontext_addr = 0; + + c->dwarf.args_size = 0; + c->dwarf.ret_addr_column = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/libs/libunwind/ppc64/is_fpreg.c b/src/libs/libunwind/ppc64/is_fpreg.c new file mode 100644 index 0000000000..b34bf8715c --- /dev/null +++ b/src/libs/libunwind/ppc64/is_fpreg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED int +unw_is_fpreg (int regnum) +{ + return (regnum >= UNW_PPC64_F0 && regnum <= UNW_PPC64_F31); +} diff --git a/src/libs/libunwind/ppc64/regname.c b/src/libs/libunwind/ppc64/regname.c new file mode 100644 index 0000000000..3e3a141988 --- /dev/null +++ b/src/libs/libunwind/ppc64/regname.c @@ -0,0 +1,164 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + [UNW_PPC64_R0]="GPR0", + [UNW_PPC64_R1]="GPR1", + [UNW_PPC64_R2]="GPR2", + [UNW_PPC64_R3]="GPR3", + [UNW_PPC64_R4]="GPR4", + [UNW_PPC64_R5]="GPR5", + [UNW_PPC64_R6]="GPR6", + [UNW_PPC64_R7]="GPR7", + [UNW_PPC64_R8]="GPR8", + [UNW_PPC64_R9]="GPR9", + [UNW_PPC64_R10]="GPR10", + [UNW_PPC64_R11]="GPR11", + [UNW_PPC64_R12]="GPR12", + [UNW_PPC64_R13]="GPR13", + [UNW_PPC64_R14]="GPR14", + [UNW_PPC64_R15]="GPR15", + [UNW_PPC64_R16]="GPR16", + [UNW_PPC64_R17]="GPR17", + [UNW_PPC64_R18]="GPR18", + [UNW_PPC64_R19]="GPR19", + [UNW_PPC64_R20]="GPR20", + [UNW_PPC64_R21]="GPR21", + [UNW_PPC64_R22]="GPR22", + [UNW_PPC64_R23]="GPR23", + [UNW_PPC64_R24]="GPR24", + [UNW_PPC64_R25]="GPR25", + [UNW_PPC64_R26]="GPR26", + [UNW_PPC64_R27]="GPR27", + [UNW_PPC64_R28]="GPR28", + [UNW_PPC64_R29]="GPR29", + [UNW_PPC64_R30]="GPR30", + [UNW_PPC64_R31]="GPR31", + + [UNW_PPC64_F0]="FPR0", + [UNW_PPC64_F1]="FPR1", + [UNW_PPC64_F2]="FPR2", + [UNW_PPC64_F3]="FPR3", + [UNW_PPC64_F4]="FPR4", + [UNW_PPC64_F5]="FPR5", + [UNW_PPC64_F6]="FPR6", + [UNW_PPC64_F7]="FPR7", + [UNW_PPC64_F8]="FPR8", + [UNW_PPC64_F9]="FPR9", + [UNW_PPC64_F10]="FPR10", + [UNW_PPC64_F11]="FPR11", + [UNW_PPC64_F12]="FPR12", + [UNW_PPC64_F13]="FPR13", + [UNW_PPC64_F14]="FPR14", + [UNW_PPC64_F15]="FPR15", + [UNW_PPC64_F16]="FPR16", + [UNW_PPC64_F17]="FPR17", + [UNW_PPC64_F18]="FPR18", + [UNW_PPC64_F19]="FPR19", + [UNW_PPC64_F20]="FPR20", + [UNW_PPC64_F21]="FPR21", + [UNW_PPC64_F22]="FPR22", + [UNW_PPC64_F23]="FPR23", + [UNW_PPC64_F24]="FPR24", + [UNW_PPC64_F25]="FPR25", + [UNW_PPC64_F26]="FPR26", + [UNW_PPC64_F27]="FPR27", + [UNW_PPC64_F28]="FPR28", + [UNW_PPC64_F29]="FPR29", + [UNW_PPC64_F30]="FPR30", + [UNW_PPC64_F31]="FPR31", + + [UNW_PPC64_LR]="LR", + [UNW_PPC64_CTR]="CTR", + [UNW_PPC64_ARG_POINTER]="ARG_POINTER", + + [UNW_PPC64_CR0]="CR0", + [UNW_PPC64_CR1]="CR1", + [UNW_PPC64_CR2]="CR2", + [UNW_PPC64_CR3]="CR3", + [UNW_PPC64_CR4]="CR4", + [UNW_PPC64_CR5]="CR5", + [UNW_PPC64_CR6]="CR6", + [UNW_PPC64_CR7]="CR7", + + [UNW_PPC64_XER]="XER", + + [UNW_PPC64_V0]="VR0", + [UNW_PPC64_V1]="VR1", + [UNW_PPC64_V2]="VR2", + [UNW_PPC64_V3]="VR3", + [UNW_PPC64_V4]="VR4", + [UNW_PPC64_V5]="VR5", + [UNW_PPC64_V6]="VR6", + [UNW_PPC64_V7]="VR7", + [UNW_PPC64_V8]="VR8", + [UNW_PPC64_V9]="VR9", + [UNW_PPC64_V10]="VR10", + [UNW_PPC64_V11]="VR11", + [UNW_PPC64_V12]="VR12", + [UNW_PPC64_V13]="VR13", + [UNW_PPC64_V14]="VR14", + [UNW_PPC64_V15]="VR15", + [UNW_PPC64_V16]="VR16", + [UNW_PPC64_V17]="VR17", + [UNW_PPC64_V18]="VR18", + [UNW_PPC64_V19]="VR19", + [UNW_PPC64_V20]="VR20", + [UNW_PPC64_V21]="VR21", + [UNW_PPC64_V22]="VR22", + [UNW_PPC64_V23]="VR23", + [UNW_PPC64_V24]="VR24", + [UNW_PPC64_V25]="VR25", + [UNW_PPC64_V26]="VR26", + [UNW_PPC64_V27]="VR27", + [UNW_PPC64_V28]="VR28", + [UNW_PPC64_V29]="VR29", + [UNW_PPC64_V30]="VR30", + [UNW_PPC64_V31]="VR31", + + [UNW_PPC64_VSCR]="VSCR", + + [UNW_PPC64_VRSAVE]="VRSAVE", + [UNW_PPC64_SPE_ACC]="SPE_ACC", + [UNW_PPC64_SPEFSCR]="SPEFSCR", + + [UNW_PPC64_FRAME_POINTER]="FRAME_POINTER", + [UNW_PPC64_NIP]="NIP", + + }; + +PROTECTED const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/libs/libunwind/ppc64/setcontext.S b/src/libs/libunwind/ppc64/setcontext.S new file mode 100644 index 0000000000..a72f81f583 --- /dev/null +++ b/src/libs/libunwind/ppc64/setcontext.S @@ -0,0 +1,9 @@ + .global _UI_setcontext + +_UI_setcontext: + blr + +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/libs/libunwind/ppc64/ucontext_i.h b/src/libs/libunwind/ppc64/ucontext_i.h new file mode 100644 index 0000000000..2ddfdb865a --- /dev/null +++ b/src/libs/libunwind/ppc64/ucontext_i.h @@ -0,0 +1,173 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef ucontext_i_h +#define ucontext_i_h + +#include + +/* These values were derived by reading + /usr/src/linux-2.6.18-1.8/arch/um/include/sysdep-ppc/ptrace.h and + /usr/src/linux-2.6.18-1.8/arch/powerpc/kernel/ppc32.h +*/ + +#define NIP_IDX 32 +#define MSR_IDX 33 +#define ORIG_GPR3_IDX 34 +#define CTR_IDX 35 +#define LINK_IDX 36 +#define XER_IDX 37 +#define CCR_IDX 38 +#define SOFTE_IDX 39 +#define TRAP_IDX 40 +#define DAR_IDX 41 +#define DSISR_IDX 42 +#define RESULT_IDX 43 + +#define VSCR_IDX 32 +#define VRSAVE_IDX 33 + +/* These are dummy structures used only for obtaining the offsets of the + various structure members. */ +static ucontext_t dmy_ctxt; +static vrregset_t dmy_vrregset; + +#define UC_MCONTEXT_GREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[0] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[1] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[2] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[3] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[4] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[5] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[6] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[7] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[8] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[9] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[10] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[11] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[12] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[13] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[14] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[15] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[16] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[17] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[18] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[19] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[20] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[21] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[22] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[23] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[24] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[25] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[26] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[27] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[28] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[29] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[30] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[31] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_NIP ((void *)&dmy_ctxt.uc_mcontext.gp_regs[NIP_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_MSR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[MSR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_ORIG_GPR3 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[ORIG_GPR3_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_CTR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[CTR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_LINK ((void *)&dmy_ctxt.uc_mcontext.gp_regs[LINK_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_XER ((void *)&dmy_ctxt.uc_mcontext.gp_regs[XER_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_CCR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[CCR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_SOFTE ((void *)&dmy_ctxt.uc_mcontext.gp_regs[SOFTE_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_TRAP ((void *)&dmy_ctxt.uc_mcontext.gp_regs[TRAP_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_DAR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[DAR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_DSISR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[DSISR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_RESULT ((void *)&dmy_ctxt.uc_mcontext.gp_regs[RESULT_IDX] - (void *)&dmy_ctxt) + +#define UC_MCONTEXT_FREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[0] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[1] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[2] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[3] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[4] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[5] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[6] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[7] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[8] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[9] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[10] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[11] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[12] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[13] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[14] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[15] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[16] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[17] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[18] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[19] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[20] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[21] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[22] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[23] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[24] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[25] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[26] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[27] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[28] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[29] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[30] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[31] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_FPSCR ((void *)&dmy_ctxt.uc_mcontext.fp_regs[32] - (void *)&dmy_ctxt) + +#define UC_MCONTEXT_V_REGS ((void *)&dmy_ctxt.uc_mcontext.v_regs - (void *)&dmy_ctxt) + +#define UC_MCONTEXT_VREGS_R0 ((void *)&dmy_vrregset.vrregs[0] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R1 ((void *)&dmy_vrregset.vrregs[1] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R2 ((void *)&dmy_vrregset.vrregs[2] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R3 ((void *)&dmy_vrregset.vrregs[3] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R4 ((void *)&dmy_vrregset.vrregs[4] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R5 ((void *)&dmy_vrregset.vrregs[5] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R6 ((void *)&dmy_vrregset.vrregs[6] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R7 ((void *)&dmy_vrregset.vrregs[7] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R8 ((void *)&dmy_vrregset.vrregs[8] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R9 ((void *)&dmy_vrregset.vrregs[9] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R10 ((void *)&dmy_vrregset.vrregs[10] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R11 ((void *)&dmy_vrregset.vrregs[11] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R12 ((void *)&dmy_vrregset.vrregs[12] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R13 ((void *)&dmy_vrregset.vrregs[13] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R14 ((void *)&dmy_vrregset.vrregs[14] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R15 ((void *)&dmy_vrregset.vrregs[15] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R16 ((void *)&dmy_vrregset.vrregs[16] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R17 ((void *)&dmy_vrregset.vrregs[17] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R18 ((void *)&dmy_vrregset.vrregs[18] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R19 ((void *)&dmy_vrregset.vrregs[19] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R20 ((void *)&dmy_vrregset.vrregs[20] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R21 ((void *)&dmy_vrregset.vrregs[21] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R22 ((void *)&dmy_vrregset.vrregs[22] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R23 ((void *)&dmy_vrregset.vrregs[23] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R24 ((void *)&dmy_vrregset.vrregs[24] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R25 ((void *)&dmy_vrregset.vrregs[25] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R26 ((void *)&dmy_vrregset.vrregs[26] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R27 ((void *)&dmy_vrregset.vrregs[27] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R28 ((void *)&dmy_vrregset.vrregs[28] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R29 ((void *)&dmy_vrregset.vrregs[29] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R30 ((void *)&dmy_vrregset.vrregs[30] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R31 ((void *)&dmy_vrregset.vrregs[31] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_VSCR ((void *)&dmy_vrregset.vscr - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_VRSAVE ((void *)&dmy_vrregset.vrsave - (void *)&dmy_vrregset) + +#endif diff --git a/src/libs/libunwind/ppc64/unwind_i.h b/src/libs/libunwind/ppc64/unwind_i.h new file mode 100644 index 0000000000..26bbc2df83 --- /dev/null +++ b/src/libs/libunwind/ppc64/unwind_i.h @@ -0,0 +1,52 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include + +#include + +#include +#include + +#define ppc64_lock UNW_OBJ(lock) +#define ppc64_local_resume UNW_OBJ(local_resume) +#define ppc64_local_addr_space_init UNW_OBJ(local_addr_space_init) +#if 0 +#define ppc64_scratch_loc UNW_OBJ(scratch_loc) +#endif + +extern void ppc64_local_addr_space_init (void); +extern int ppc64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); +#if 0 +extern dwarf_loc_t ppc64_scratch_loc (struct cursor *c, unw_regnum_t reg); +#endif + +#endif /* unwind_i_h */ diff --git a/src/libs/libunwind/ptrace/_UPT_access_fpreg.c b/src/libs/libunwind/ptrace/_UPT_access_fpreg.c new file mode 100644 index 0000000000..e90ec47d08 --- /dev/null +++ b/src/libs/libunwind/ptrace/_UPT_access_fpreg.c @@ -0,0 +1,105 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +#if HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE +int +_UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + unw_word_t *wp = (unw_word_t *) val; + struct UPT_info *ui = arg; + pid_t pid = ui->pid; + int i; + + if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) + return -UNW_EBADREG; + + errno = 0; + if (write) + for (i = 0; i < (int) (sizeof (*val) / sizeof (wp[i])); ++i) + { +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + ptrace (PTRACE_POKEUSER, pid, _UPT_reg_offset[reg] + i * sizeof(wp[i]), + wp[i]); +#endif + if (errno) + return -UNW_EBADREG; + } + else + for (i = 0; i < (int) (sizeof (*val) / sizeof (wp[i])); ++i) + { +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + wp[i] = ptrace (PTRACE_PEEKUSER, pid, + _UPT_reg_offset[reg] + i * sizeof(wp[i]), 0); +#endif + if (errno) + return -UNW_EBADREG; + } + return 0; +} +#elif HAVE_DECL_PT_GETFPREGS +int +_UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + struct UPT_info *ui = arg; + pid_t pid = ui->pid; + fpregset_t fpreg; + + if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) + return -UNW_EBADREG; + + if (ptrace(PT_GETFPREGS, pid, (caddr_t)&fpreg, 0) == -1) + return -UNW_EBADREG; + if (write) { +#if defined(__amd64__) + memcpy(&fpreg.fpr_xacc[reg], val, sizeof(unw_fpreg_t)); +#elif defined(__i386__) + memcpy(&fpreg.fpr_acc[reg], val, sizeof(unw_fpreg_t)); +#else +#error Fix me +#endif + if (ptrace(PT_SETFPREGS, pid, (caddr_t)&fpreg, 0) == -1) + return -UNW_EBADREG; + } else +#if defined(__amd64__) + memcpy(val, &fpreg.fpr_xacc[reg], sizeof(unw_fpreg_t)); +#elif defined(__i386__) + memcpy(val, &fpreg.fpr_acc[reg], sizeof(unw_fpreg_t)); +#else +#error Fix me +#endif + return 0; +} +#else +#error Fix me +#endif diff --git a/src/libs/libunwind/ptrace/_UPT_access_mem.c b/src/libs/libunwind/ptrace/_UPT_access_mem.c new file mode 100644 index 0000000000..ab93ce30e4 --- /dev/null +++ b/src/libs/libunwind/ptrace/_UPT_access_mem.c @@ -0,0 +1,90 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +#if HAVE_DECL_PTRACE_POKEDATA || HAVE_TTRACE +int +_UPT_access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, + int write, void *arg) +{ + struct UPT_info *ui = arg; + if (!ui) + return -UNW_EINVAL; + + pid_t pid = ui->pid; + + errno = 0; + if (write) + { + Debug (16, "mem[%lx] <- %lx\n", (long) addr, (long) *val); +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + ptrace (PTRACE_POKEDATA, pid, addr, *val); + if (errno) + return -UNW_EINVAL; +#endif + } + else + { +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + *val = ptrace (PTRACE_PEEKDATA, pid, addr, 0); + if (errno) + return -UNW_EINVAL; +#endif + Debug (16, "mem[%lx] -> %lx\n", (long) addr, (long) *val); + } + return 0; +} +#elif HAVE_DECL_PT_IO +int +_UPT_access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, + int write, void *arg) +{ + struct UPT_info *ui = arg; + if (!ui) + return -UNW_EINVAL; + pid_t pid = ui->pid; + struct ptrace_io_desc iod; + + iod.piod_offs = (void *)addr; + iod.piod_addr = val; + iod.piod_len = sizeof(*val); + iod.piod_op = write ? PIOD_WRITE_D : PIOD_READ_D; + if (write) + Debug (16, "mem[%lx] <- %lx\n", (long) addr, (long) *val); + if (ptrace(PT_IO, pid, (caddr_t)&iod, 0) == -1) + return -UNW_EINVAL; + if (!write) + Debug (16, "mem[%lx] -> %lx\n", (long) addr, (long) *val); + return 0; +} +#else +#error Fix me +#endif diff --git a/src/libs/libunwind/ptrace/_UPT_access_reg.c b/src/libs/libunwind/ptrace/_UPT_access_reg.c new file mode 100644 index 0000000000..ae71608b3d --- /dev/null +++ b/src/libs/libunwind/ptrace/_UPT_access_reg.c @@ -0,0 +1,309 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +#if UNW_TARGET_IA64 +# include +# ifdef HAVE_ASM_PTRACE_OFFSETS_H +# include +# endif +# include "tdep-ia64/rse.h" +#endif + +#if HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE +int +_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, + int write, void *arg) +{ + struct UPT_info *ui = arg; + pid_t pid = ui->pid; + +#if UNW_DEBUG + Debug(16, "using pokeuser: reg: %s [%u], val: %lx, write: %d\n", unw_regname(reg), (unsigned) reg, (long) val, write); + + if (write) + Debug (16, "%s <- %lx\n", unw_regname (reg), (long) *val); +#endif + +#if UNW_TARGET_IA64 + if ((unsigned) reg - UNW_IA64_NAT < 32) + { + unsigned long nat_bits, mask; + + /* The Linux ptrace represents the statc NaT bits as a single word. */ + mask = ((unw_word_t) 1) << (reg - UNW_IA64_NAT); + errno = 0; +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + nat_bits = ptrace (PTRACE_PEEKUSER, pid, PT_NAT_BITS, 0); + if (errno) + goto badreg; +#endif + + if (write) + { + if (*val) + nat_bits |= mask; + else + nat_bits &= ~mask; +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + ptrace (PTRACE_POKEUSER, pid, PT_NAT_BITS, nat_bits); + if (errno) + goto badreg; +#endif + } + goto out; + } + else + switch (reg) + { + case UNW_IA64_GR + 0: + if (write) + goto badreg; + *val = 0; + return 0; + + case UNW_REG_IP: + { + unsigned long ip, psr; + + /* distribute bundle-addr. & slot-number across PT_IIP & PT_IPSR. */ +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + psr = ptrace (PTRACE_PEEKUSER, pid, PT_CR_IPSR, 0); + if (errno) + goto badreg; +#endif + if (write) + { + ip = *val & ~0xfUL; + psr = (psr & ~0x3UL << 41) | (*val & 0x3); +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + ptrace (PTRACE_POKEUSER, pid, PT_CR_IIP, ip); + ptrace (PTRACE_POKEUSER, pid, PT_CR_IPSR, psr); + if (errno) + goto badreg; +#endif + } + else + { +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + ip = ptrace (PTRACE_PEEKUSER, pid, PT_CR_IIP, 0); + if (errno) + goto badreg; +#endif + *val = ip + ((psr >> 41) & 0x3); + } + goto out; + } + + case UNW_IA64_AR_BSPSTORE: + reg = UNW_IA64_AR_BSP; + break; + + case UNW_IA64_AR_BSP: + case UNW_IA64_BSP: + { + unsigned long sof, cfm, bsp; + +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + /* Account for the fact that ptrace() expects bsp to point + _after_ the current register frame. */ + errno = 0; + cfm = ptrace (PTRACE_PEEKUSER, pid, PT_CFM, 0); + if (errno) + goto badreg; +#endif + sof = (cfm & 0x7f); + + if (write) + { + bsp = rse_skip_regs (*val, sof); +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + ptrace (PTRACE_POKEUSER, pid, PT_AR_BSP, bsp); + if (errno) + goto badreg; +#endif + } + else + { +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + bsp = ptrace (PTRACE_PEEKUSER, pid, PT_AR_BSP, 0); + if (errno) + goto badreg; +#endif + *val = rse_skip_regs (bsp, -sof); + } + goto out; + } + + case UNW_IA64_CFM: + /* If we change CFM, we need to adjust ptrace's notion of bsp + accordingly, so that the real bsp remains unchanged. */ + if (write) + { + unsigned long new_sof, old_sof, cfm, bsp; + +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + bsp = ptrace (PTRACE_PEEKUSER, pid, PT_AR_BSP, 0); + cfm = ptrace (PTRACE_PEEKUSER, pid, PT_CFM, 0); +#endif + if (errno) + goto badreg; + old_sof = (cfm & 0x7f); + new_sof = (*val & 0x7f); + if (old_sof != new_sof) + { + bsp = rse_skip_regs (bsp, -old_sof + new_sof); +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + ptrace (PTRACE_POKEUSER, pid, PT_AR_BSP, 0); + if (errno) + goto badreg; +#endif + } +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + ptrace (PTRACE_POKEUSER, pid, PT_CFM, *val); + if (errno) + goto badreg; +#endif + goto out; + } + break; + } +#endif /* End of IA64 */ + + if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) + { +#if UNW_DEBUG + Debug(2, "register out of range: >= %zu / %zu\n", sizeof(_UPT_reg_offset), sizeof(_UPT_reg_offset[0])); +#endif + errno = EINVAL; + goto badreg; + } + +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + if (write) + ptrace (PTRACE_POKEUSER, pid, _UPT_reg_offset[reg], *val); + else { +#if UNW_DEBUG + Debug(16, "ptrace PEEKUSER pid: %lu , reg: %lu , offs: %lu\n", (unsigned long)pid, (unsigned long)reg, + (unsigned long)_UPT_reg_offset[reg]); +#endif + *val = ptrace (PTRACE_PEEKUSER, pid, _UPT_reg_offset[reg], 0); + } + if (errno) { +#if UNW_DEBUG + Debug(2, "ptrace failure\n"); +#endif + goto badreg; + } +#endif + +#ifdef UNW_TARGET_IA64 + out: +#endif +#if UNW_DEBUG + if (!write) + Debug (16, "%s[%u] -> %lx\n", unw_regname (reg), (unsigned) reg, (long) *val); +#endif + return 0; + + badreg: + Debug (1, "bad register %s [%u] (error: %s)\n", unw_regname(reg), reg, strerror (errno)); + return -UNW_EBADREG; +} +#elif HAVE_DECL_PT_GETREGS +int +_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, + int write, void *arg) +{ + struct UPT_info *ui = arg; + pid_t pid = ui->pid; + gregset_t regs; + char *r; + +#if UNW_DEBUG + Debug(16, "using getregs: reg: %s [%u], val: %lx, write: %u\n", unw_regname(reg), (unsigned) reg, (long) val, write); + + if (write) + Debug (16, "%s [%u] <- %lx\n", unw_regname (reg), (unsigned) reg, (long) *val); +#endif + if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) + { + errno = EINVAL; + goto badreg; + } + r = (char *)®s + _UPT_reg_offset[reg]; + if (ptrace(PT_GETREGS, pid, (caddr_t)®s, 0) == -1) + goto badreg; + if (write) { + memcpy(r, val, sizeof(unw_word_t)); + if (ptrace(PT_SETREGS, pid, (caddr_t)®s, 0) == -1) + goto badreg; + } else + memcpy(val, r, sizeof(unw_word_t)); + return 0; + + badreg: + Debug (1, "bad register %s [%u] (error: %s)\n", unw_regname(reg), reg, strerror (errno)); + return -UNW_EBADREG; +} +#else +#error Port me +#endif diff --git a/src/libs/libunwind/ptrace/_UPT_accessors.c b/src/libs/libunwind/ptrace/_UPT_accessors.c new file mode 100644 index 0000000000..3190e7894a --- /dev/null +++ b/src/libs/libunwind/ptrace/_UPT_accessors.c @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +PROTECTED unw_accessors_t _UPT_accessors = + { + .find_proc_info = _UPT_find_proc_info, + .put_unwind_info = _UPT_put_unwind_info, + .get_dyn_info_list_addr = _UPT_get_dyn_info_list_addr, + .access_mem = _UPT_access_mem, + .access_reg = _UPT_access_reg, + .access_fpreg = _UPT_access_fpreg, + .resume = _UPT_resume, + .get_proc_name = _UPT_get_proc_name + }; diff --git a/src/libs/libunwind/ptrace/_UPT_create.c b/src/libs/libunwind/ptrace/_UPT_create.c new file mode 100644 index 0000000000..dd59e974a7 --- /dev/null +++ b/src/libs/libunwind/ptrace/_UPT_create.c @@ -0,0 +1,46 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "_UPT_internal.h" + +void * +_UPT_create (pid_t pid) +{ + struct UPT_info *ui = malloc (sizeof (struct UPT_info)); + + if (!ui) + return NULL; + + memset (ui, 0, sizeof (*ui)); + ui->pid = pid; + ui->edi.di_cache.format = -1; + ui->edi.di_debug.format = -1; +#if UNW_TARGET_IA64 + ui->edi.ktab.format = -1; +#endif + return ui; +} diff --git a/src/libs/libunwind/ptrace/_UPT_destroy.c b/src/libs/libunwind/ptrace/_UPT_destroy.c new file mode 100644 index 0000000000..edb664ce12 --- /dev/null +++ b/src/libs/libunwind/ptrace/_UPT_destroy.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +void +_UPT_destroy (void *ptr) +{ + struct UPT_info *ui = (struct UPT_info *) ptr; + invalidate_edi (&ui->edi); + free (ptr); +} diff --git a/src/libs/libunwind/ptrace/_UPT_elf.c b/src/libs/libunwind/ptrace/_UPT_elf.c new file mode 100644 index 0000000000..efc43b578b --- /dev/null +++ b/src/libs/libunwind/ptrace/_UPT_elf.c @@ -0,0 +1,5 @@ +/* We need to get a separate copy of the ELF-code into + libunwind-ptrace since it cannot (and must not) have any ELF + dependencies on libunwind. */ +#include "libunwind_i.h" /* get ELFCLASS defined */ +#include "../elfxx.c" diff --git a/src/libs/libunwind/ptrace/_UPT_find_proc_info.c b/src/libs/libunwind/ptrace/_UPT_find_proc_info.c new file mode 100644 index 0000000000..d2a37eac56 --- /dev/null +++ b/src/libs/libunwind/ptrace/_UPT_find_proc_info.c @@ -0,0 +1,145 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include +#include + +#include + +#include "_UPT_internal.h" + +static int +get_unwind_info (struct elf_dyn_info *edi, pid_t pid, unw_addr_space_t as, unw_word_t ip) +{ + unsigned long segbase, mapoff; + char path[PATH_MAX]; + +#if UNW_TARGET_IA64 && defined(__linux) + if (!edi->ktab.start_ip && _Uia64_get_kernel_table (&edi->ktab) < 0) + return -UNW_ENOINFO; + + if (edi->ktab.format != -1 && ip >= edi->ktab.start_ip && ip < edi->ktab.end_ip) + return 0; +#endif + + if ((edi->di_cache.format != -1 + && ip >= edi->di_cache.start_ip && ip < edi->di_cache.end_ip) +#if UNW_TARGET_ARM + || (edi->di_debug.format != -1 + && ip >= edi->di_arm.start_ip && ip < edi->di_arm.end_ip) +#endif + || (edi->di_debug.format != -1 + && ip >= edi->di_debug.start_ip && ip < edi->di_debug.end_ip)) + return 0; + + invalidate_edi(edi); + + if (tdep_get_elf_image (&edi->ei, pid, ip, &segbase, &mapoff, path, + sizeof(path)) < 0) + return -UNW_ENOINFO; + + /* Here, SEGBASE is the starting-address of the (mmap'ped) segment + which covers the IP we're looking for. */ + if (tdep_find_unwind_table (edi, as, path, segbase, mapoff, ip) < 0) + return -UNW_ENOINFO; + + /* This can happen in corner cases where dynamically generated + code falls into the same page that contains the data-segment + and the page-offset of the code is within the first page of + the executable. */ + if (edi->di_cache.format != -1 + && (ip < edi->di_cache.start_ip || ip >= edi->di_cache.end_ip)) + edi->di_cache.format = -1; + + if (edi->di_debug.format != -1 + && (ip < edi->di_debug.start_ip || ip >= edi->di_debug.end_ip)) + edi->di_debug.format = -1; + + if (edi->di_cache.format == -1 +#if UNW_TARGET_ARM + && edi->di_arm.format == -1 +#endif + && edi->di_debug.format == -1) + return -UNW_ENOINFO; + + return 0; +} + +int +_UPT_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + struct UPT_info *ui = arg; + int ret = -UNW_ENOINFO; + + if (get_unwind_info (&ui->edi, ui->pid, as, ip) < 0) + return -UNW_ENOINFO; + +#if UNW_TARGET_IA64 + if (ui->edi.ktab.format != -1) + { + /* The kernel unwind table resides in local memory, so we have + to use the local address space to search it. Since + _UPT_put_unwind_info() has no easy way of detecting this + case, we simply make a copy of the unwind-info, so + _UPT_put_unwind_info() can always free() the unwind-info + without ill effects. */ + ret = tdep_search_unwind_table (unw_local_addr_space, ip, &ui->edi.ktab, pi, + need_unwind_info, arg); + if (ret >= 0) + { + if (!need_unwind_info) + pi->unwind_info = NULL; + else + { + void *mem = malloc (pi->unwind_info_size); + + if (!mem) + return -UNW_ENOMEM; + memcpy (mem, pi->unwind_info, pi->unwind_info_size); + pi->unwind_info = mem; + } + } + } +#endif + + if (ret == -UNW_ENOINFO && ui->edi.di_cache.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_cache, + pi, need_unwind_info, arg); + +#if UNW_TARGET_ARM + if (ret == -UNW_ENOINFO && ui->edi.di_arm.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_arm, pi, + need_unwind_info, arg); +#endif + + if (ret == -UNW_ENOINFO && ui->edi.di_debug.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_debug, pi, + need_unwind_info, arg); + + return ret; +} diff --git a/src/libs/libunwind/ptrace/_UPT_get_dyn_info_list_addr.c b/src/libs/libunwind/ptrace/_UPT_get_dyn_info_list_addr.c new file mode 100644 index 0000000000..cc5ed04418 --- /dev/null +++ b/src/libs/libunwind/ptrace/_UPT_get_dyn_info_list_addr.c @@ -0,0 +1,105 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +#if UNW_TARGET_IA64 && defined(__linux) +# include "elf64.h" +# include "os-linux.h" + +static inline int +get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, + int *countp) +{ + unsigned long lo, hi, off; + struct UPT_info *ui = arg; + struct map_iterator mi; + char path[PATH_MAX]; + unw_word_t res; + int count = 0; + + maps_init (&mi, ui->pid); + while (maps_next (&mi, &lo, &hi, &off)) + { + if (off) + continue; + + invalidate_edi(&ui->edi); + + if (elf_map_image (&ui->edi.ei, path) < 0) + /* ignore unmappable stuff like "/SYSV00001b58 (deleted)" */ + continue; + + Debug (16, "checking object %s\n", path); + + if (tdep_find_unwind_table (&ui->edi, as, path, lo, off, 0) > 0) + { + res = _Uia64_find_dyn_list (as, &ui->edi.di_cache, arg); + if (res && count++ == 0) + { + Debug (12, "dyn_info_list_addr = 0x%lx\n", (long) res); + *dil_addr = res; + } + } + } + maps_close (&mi); + *countp = count; + return 0; +} + +#else + +static inline int +get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, + int *countp) +{ +# warning Implement get_list_addr(), please. + *countp = 0; + return 0; +} + +#endif + +int +_UPT_get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, + void *arg) +{ + int count, ret; + + Debug (12, "looking for dyn_info list\n"); + + if ((ret = get_list_addr (as, dil_addr, arg, &count)) < 0) + return ret; + + /* If multiple dynamic-info list addresses are found, we would have + to determine which was is the one actually in use (since the + dynamic name resolution algorithm will pick one "winner"). + Perhaps we'd have to track them all until we find one that's + non-empty. Hopefully, this case simply will never arise, since + only libunwind defines the dynamic info list head. */ + assert (count <= 1); + + return (count > 0) ? 0 : -UNW_ENOINFO; +} diff --git a/src/libs/libunwind/ptrace/_UPT_get_proc_name.c b/src/libs/libunwind/ptrace/_UPT_get_proc_name.c new file mode 100644 index 0000000000..79c1f38e25 --- /dev/null +++ b/src/libs/libunwind/ptrace/_UPT_get_proc_name.c @@ -0,0 +1,42 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +int +_UPT_get_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, void *arg) +{ + struct UPT_info *ui = arg; + +#if ELF_CLASS == ELFCLASS64 + return _Uelf64_get_proc_name (as, ui->pid, ip, buf, buf_len, offp); +#elif ELF_CLASS == ELFCLASS32 + return _Uelf32_get_proc_name (as, ui->pid, ip, buf, buf_len, offp); +#else + return -UNW_ENOINFO; +#endif +} diff --git a/src/libs/libunwind/ptrace/_UPT_internal.h b/src/libs/libunwind/ptrace/_UPT_internal.h new file mode 100644 index 0000000000..5cef2573ee --- /dev/null +++ b/src/libs/libunwind/ptrace/_UPT_internal.h @@ -0,0 +1,59 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _UPT_internal_h +#define _UPT_internal_h + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_PTRACE_H +#include +#endif +#ifdef HAVE_SYS_PROCFS_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "libunwind_i.h" + +struct UPT_info + { + pid_t pid; /* the process-id of the child we're unwinding */ + struct elf_dyn_info edi; + }; + +extern const int _UPT_reg_offset[UNW_REG_LAST + 1]; + +#endif /* _UPT_internal_h */ diff --git a/src/libs/libunwind/ptrace/_UPT_put_unwind_info.c b/src/libs/libunwind/ptrace/_UPT_put_unwind_info.c new file mode 100644 index 0000000000..d4b8463147 --- /dev/null +++ b/src/libs/libunwind/ptrace/_UPT_put_unwind_info.c @@ -0,0 +1,35 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +void +_UPT_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) +{ + if (!pi->unwind_info) + return; + free (pi->unwind_info); + pi->unwind_info = NULL; +} diff --git a/src/libs/libunwind/ptrace/_UPT_reg_offset.c b/src/libs/libunwind/ptrace/_UPT_reg_offset.c new file mode 100644 index 0000000000..68461a2fb1 --- /dev/null +++ b/src/libs/libunwind/ptrace/_UPT_reg_offset.c @@ -0,0 +1,601 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + Copyright (C) 2013 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +#include + +#ifdef HAVE_ASM_PTRACE_OFFSETS_H +# include +#endif + +const int _UPT_reg_offset[UNW_REG_LAST + 1] = + { +#ifdef HAVE_ASM_PTRACE_OFFSETS_H +# ifndef PT_AR_CSD +# define PT_AR_CSD -1 /* this was introduced with rev 2.1 of ia64 */ +# endif + + [UNW_IA64_GR + 0] = -1, [UNW_IA64_GR + 1] = PT_R1, + [UNW_IA64_GR + 2] = PT_R2, [UNW_IA64_GR + 3] = PT_R3, + [UNW_IA64_GR + 4] = PT_R4, [UNW_IA64_GR + 5] = PT_R5, + [UNW_IA64_GR + 6] = PT_R6, [UNW_IA64_GR + 7] = PT_R7, + [UNW_IA64_GR + 8] = PT_R8, [UNW_IA64_GR + 9] = PT_R9, + [UNW_IA64_GR + 10] = PT_R10, [UNW_IA64_GR + 11] = PT_R11, + [UNW_IA64_GR + 12] = PT_R12, [UNW_IA64_GR + 13] = PT_R13, + [UNW_IA64_GR + 14] = PT_R14, [UNW_IA64_GR + 15] = PT_R15, + [UNW_IA64_GR + 16] = PT_R16, [UNW_IA64_GR + 17] = PT_R17, + [UNW_IA64_GR + 18] = PT_R18, [UNW_IA64_GR + 19] = PT_R19, + [UNW_IA64_GR + 20] = PT_R20, [UNW_IA64_GR + 21] = PT_R21, + [UNW_IA64_GR + 22] = PT_R22, [UNW_IA64_GR + 23] = PT_R23, + [UNW_IA64_GR + 24] = PT_R24, [UNW_IA64_GR + 25] = PT_R25, + [UNW_IA64_GR + 26] = PT_R26, [UNW_IA64_GR + 27] = PT_R27, + [UNW_IA64_GR + 28] = PT_R28, [UNW_IA64_GR + 29] = PT_R29, + [UNW_IA64_GR + 30] = PT_R30, [UNW_IA64_GR + 31] = PT_R31, + + [UNW_IA64_NAT+ 0] = -1, [UNW_IA64_NAT+ 1] = PT_NAT_BITS, + [UNW_IA64_NAT+ 2] = PT_NAT_BITS, [UNW_IA64_NAT+ 3] = PT_NAT_BITS, + [UNW_IA64_NAT+ 4] = PT_NAT_BITS, [UNW_IA64_NAT+ 5] = PT_NAT_BITS, + [UNW_IA64_NAT+ 6] = PT_NAT_BITS, [UNW_IA64_NAT+ 7] = PT_NAT_BITS, + [UNW_IA64_NAT+ 8] = PT_NAT_BITS, [UNW_IA64_NAT+ 9] = PT_NAT_BITS, + [UNW_IA64_NAT+ 10] = PT_NAT_BITS, [UNW_IA64_NAT+ 11] = PT_NAT_BITS, + [UNW_IA64_NAT+ 12] = PT_NAT_BITS, [UNW_IA64_NAT+ 13] = PT_NAT_BITS, + [UNW_IA64_NAT+ 14] = PT_NAT_BITS, [UNW_IA64_NAT+ 15] = PT_NAT_BITS, + [UNW_IA64_NAT+ 16] = PT_NAT_BITS, [UNW_IA64_NAT+ 17] = PT_NAT_BITS, + [UNW_IA64_NAT+ 18] = PT_NAT_BITS, [UNW_IA64_NAT+ 19] = PT_NAT_BITS, + [UNW_IA64_NAT+ 20] = PT_NAT_BITS, [UNW_IA64_NAT+ 21] = PT_NAT_BITS, + [UNW_IA64_NAT+ 22] = PT_NAT_BITS, [UNW_IA64_NAT+ 23] = PT_NAT_BITS, + [UNW_IA64_NAT+ 24] = PT_NAT_BITS, [UNW_IA64_NAT+ 25] = PT_NAT_BITS, + [UNW_IA64_NAT+ 26] = PT_NAT_BITS, [UNW_IA64_NAT+ 27] = PT_NAT_BITS, + [UNW_IA64_NAT+ 28] = PT_NAT_BITS, [UNW_IA64_NAT+ 29] = PT_NAT_BITS, + [UNW_IA64_NAT+ 30] = PT_NAT_BITS, [UNW_IA64_NAT+ 31] = PT_NAT_BITS, + + [UNW_IA64_FR + 0] = -1, [UNW_IA64_FR + 1] = -1, + [UNW_IA64_FR + 2] = PT_F2, [UNW_IA64_FR + 3] = PT_F3, + [UNW_IA64_FR + 4] = PT_F4, [UNW_IA64_FR + 5] = PT_F5, + [UNW_IA64_FR + 6] = PT_F6, [UNW_IA64_FR + 7] = PT_F7, + [UNW_IA64_FR + 8] = PT_F8, [UNW_IA64_FR + 9] = PT_F9, + [UNW_IA64_FR + 10] = PT_F10, [UNW_IA64_FR + 11] = PT_F11, + [UNW_IA64_FR + 12] = PT_F12, [UNW_IA64_FR + 13] = PT_F13, + [UNW_IA64_FR + 14] = PT_F14, [UNW_IA64_FR + 15] = PT_F15, + [UNW_IA64_FR + 16] = PT_F16, [UNW_IA64_FR + 17] = PT_F17, + [UNW_IA64_FR + 18] = PT_F18, [UNW_IA64_FR + 19] = PT_F19, + [UNW_IA64_FR + 20] = PT_F20, [UNW_IA64_FR + 21] = PT_F21, + [UNW_IA64_FR + 22] = PT_F22, [UNW_IA64_FR + 23] = PT_F23, + [UNW_IA64_FR + 24] = PT_F24, [UNW_IA64_FR + 25] = PT_F25, + [UNW_IA64_FR + 26] = PT_F26, [UNW_IA64_FR + 27] = PT_F27, + [UNW_IA64_FR + 28] = PT_F28, [UNW_IA64_FR + 29] = PT_F29, + [UNW_IA64_FR + 30] = PT_F30, [UNW_IA64_FR + 31] = PT_F31, + [UNW_IA64_FR + 32] = PT_F32, [UNW_IA64_FR + 33] = PT_F33, + [UNW_IA64_FR + 34] = PT_F34, [UNW_IA64_FR + 35] = PT_F35, + [UNW_IA64_FR + 36] = PT_F36, [UNW_IA64_FR + 37] = PT_F37, + [UNW_IA64_FR + 38] = PT_F38, [UNW_IA64_FR + 39] = PT_F39, + [UNW_IA64_FR + 40] = PT_F40, [UNW_IA64_FR + 41] = PT_F41, + [UNW_IA64_FR + 42] = PT_F42, [UNW_IA64_FR + 43] = PT_F43, + [UNW_IA64_FR + 44] = PT_F44, [UNW_IA64_FR + 45] = PT_F45, + [UNW_IA64_FR + 46] = PT_F46, [UNW_IA64_FR + 47] = PT_F47, + [UNW_IA64_FR + 48] = PT_F48, [UNW_IA64_FR + 49] = PT_F49, + [UNW_IA64_FR + 50] = PT_F50, [UNW_IA64_FR + 51] = PT_F51, + [UNW_IA64_FR + 52] = PT_F52, [UNW_IA64_FR + 53] = PT_F53, + [UNW_IA64_FR + 54] = PT_F54, [UNW_IA64_FR + 55] = PT_F55, + [UNW_IA64_FR + 56] = PT_F56, [UNW_IA64_FR + 57] = PT_F57, + [UNW_IA64_FR + 58] = PT_F58, [UNW_IA64_FR + 59] = PT_F59, + [UNW_IA64_FR + 60] = PT_F60, [UNW_IA64_FR + 61] = PT_F61, + [UNW_IA64_FR + 62] = PT_F62, [UNW_IA64_FR + 63] = PT_F63, + [UNW_IA64_FR + 64] = PT_F64, [UNW_IA64_FR + 65] = PT_F65, + [UNW_IA64_FR + 66] = PT_F66, [UNW_IA64_FR + 67] = PT_F67, + [UNW_IA64_FR + 68] = PT_F68, [UNW_IA64_FR + 69] = PT_F69, + [UNW_IA64_FR + 70] = PT_F70, [UNW_IA64_FR + 71] = PT_F71, + [UNW_IA64_FR + 72] = PT_F72, [UNW_IA64_FR + 73] = PT_F73, + [UNW_IA64_FR + 74] = PT_F74, [UNW_IA64_FR + 75] = PT_F75, + [UNW_IA64_FR + 76] = PT_F76, [UNW_IA64_FR + 77] = PT_F77, + [UNW_IA64_FR + 78] = PT_F78, [UNW_IA64_FR + 79] = PT_F79, + [UNW_IA64_FR + 80] = PT_F80, [UNW_IA64_FR + 81] = PT_F81, + [UNW_IA64_FR + 82] = PT_F82, [UNW_IA64_FR + 83] = PT_F83, + [UNW_IA64_FR + 84] = PT_F84, [UNW_IA64_FR + 85] = PT_F85, + [UNW_IA64_FR + 86] = PT_F86, [UNW_IA64_FR + 87] = PT_F87, + [UNW_IA64_FR + 88] = PT_F88, [UNW_IA64_FR + 89] = PT_F89, + [UNW_IA64_FR + 90] = PT_F90, [UNW_IA64_FR + 91] = PT_F91, + [UNW_IA64_FR + 92] = PT_F92, [UNW_IA64_FR + 93] = PT_F93, + [UNW_IA64_FR + 94] = PT_F94, [UNW_IA64_FR + 95] = PT_F95, + [UNW_IA64_FR + 96] = PT_F96, [UNW_IA64_FR + 97] = PT_F97, + [UNW_IA64_FR + 98] = PT_F98, [UNW_IA64_FR + 99] = PT_F99, + [UNW_IA64_FR +100] = PT_F100, [UNW_IA64_FR +101] = PT_F101, + [UNW_IA64_FR +102] = PT_F102, [UNW_IA64_FR +103] = PT_F103, + [UNW_IA64_FR +104] = PT_F104, [UNW_IA64_FR +105] = PT_F105, + [UNW_IA64_FR +106] = PT_F106, [UNW_IA64_FR +107] = PT_F107, + [UNW_IA64_FR +108] = PT_F108, [UNW_IA64_FR +109] = PT_F109, + [UNW_IA64_FR +110] = PT_F110, [UNW_IA64_FR +111] = PT_F111, + [UNW_IA64_FR +112] = PT_F112, [UNW_IA64_FR +113] = PT_F113, + [UNW_IA64_FR +114] = PT_F114, [UNW_IA64_FR +115] = PT_F115, + [UNW_IA64_FR +116] = PT_F116, [UNW_IA64_FR +117] = PT_F117, + [UNW_IA64_FR +118] = PT_F118, [UNW_IA64_FR +119] = PT_F119, + [UNW_IA64_FR +120] = PT_F120, [UNW_IA64_FR +121] = PT_F121, + [UNW_IA64_FR +122] = PT_F122, [UNW_IA64_FR +123] = PT_F123, + [UNW_IA64_FR +124] = PT_F124, [UNW_IA64_FR +125] = PT_F125, + [UNW_IA64_FR +126] = PT_F126, [UNW_IA64_FR +127] = PT_F127, + + [UNW_IA64_AR + 0] = -1, [UNW_IA64_AR + 1] = -1, + [UNW_IA64_AR + 2] = -1, [UNW_IA64_AR + 3] = -1, + [UNW_IA64_AR + 4] = -1, [UNW_IA64_AR + 5] = -1, + [UNW_IA64_AR + 6] = -1, [UNW_IA64_AR + 7] = -1, + [UNW_IA64_AR + 8] = -1, [UNW_IA64_AR + 9] = -1, + [UNW_IA64_AR + 10] = -1, [UNW_IA64_AR + 11] = -1, + [UNW_IA64_AR + 12] = -1, [UNW_IA64_AR + 13] = -1, + [UNW_IA64_AR + 14] = -1, [UNW_IA64_AR + 15] = -1, + [UNW_IA64_AR + 16] = PT_AR_RSC, [UNW_IA64_AR + 17] = PT_AR_BSP, + [UNW_IA64_AR + 18] = PT_AR_BSPSTORE,[UNW_IA64_AR + 19] = PT_AR_RNAT, + [UNW_IA64_AR + 20] = -1, [UNW_IA64_AR + 21] = -1, + [UNW_IA64_AR + 22] = -1, [UNW_IA64_AR + 23] = -1, + [UNW_IA64_AR + 24] = -1, [UNW_IA64_AR + 25] = PT_AR_CSD, + [UNW_IA64_AR + 26] = -1, [UNW_IA64_AR + 27] = -1, + [UNW_IA64_AR + 28] = -1, [UNW_IA64_AR + 29] = -1, + [UNW_IA64_AR + 30] = -1, [UNW_IA64_AR + 31] = -1, + [UNW_IA64_AR + 32] = PT_AR_CCV, [UNW_IA64_AR + 33] = -1, + [UNW_IA64_AR + 34] = -1, [UNW_IA64_AR + 35] = -1, + [UNW_IA64_AR + 36] = PT_AR_UNAT, [UNW_IA64_AR + 37] = -1, + [UNW_IA64_AR + 38] = -1, [UNW_IA64_AR + 39] = -1, + [UNW_IA64_AR + 40] = PT_AR_FPSR, [UNW_IA64_AR + 41] = -1, + [UNW_IA64_AR + 42] = -1, [UNW_IA64_AR + 43] = -1, + [UNW_IA64_AR + 44] = -1, [UNW_IA64_AR + 45] = -1, + [UNW_IA64_AR + 46] = -1, [UNW_IA64_AR + 47] = -1, + [UNW_IA64_AR + 48] = -1, [UNW_IA64_AR + 49] = -1, + [UNW_IA64_AR + 50] = -1, [UNW_IA64_AR + 51] = -1, + [UNW_IA64_AR + 52] = -1, [UNW_IA64_AR + 53] = -1, + [UNW_IA64_AR + 54] = -1, [UNW_IA64_AR + 55] = -1, + [UNW_IA64_AR + 56] = -1, [UNW_IA64_AR + 57] = -1, + [UNW_IA64_AR + 58] = -1, [UNW_IA64_AR + 59] = -1, + [UNW_IA64_AR + 60] = -1, [UNW_IA64_AR + 61] = -1, + [UNW_IA64_AR + 62] = -1, [UNW_IA64_AR + 63] = -1, + [UNW_IA64_AR + 64] = PT_AR_PFS, [UNW_IA64_AR + 65] = PT_AR_LC, + [UNW_IA64_AR + 66] = PT_AR_EC, [UNW_IA64_AR + 67] = -1, + [UNW_IA64_AR + 68] = -1, [UNW_IA64_AR + 69] = -1, + [UNW_IA64_AR + 70] = -1, [UNW_IA64_AR + 71] = -1, + [UNW_IA64_AR + 72] = -1, [UNW_IA64_AR + 73] = -1, + [UNW_IA64_AR + 74] = -1, [UNW_IA64_AR + 75] = -1, + [UNW_IA64_AR + 76] = -1, [UNW_IA64_AR + 77] = -1, + [UNW_IA64_AR + 78] = -1, [UNW_IA64_AR + 79] = -1, + [UNW_IA64_AR + 80] = -1, [UNW_IA64_AR + 81] = -1, + [UNW_IA64_AR + 82] = -1, [UNW_IA64_AR + 83] = -1, + [UNW_IA64_AR + 84] = -1, [UNW_IA64_AR + 85] = -1, + [UNW_IA64_AR + 86] = -1, [UNW_IA64_AR + 87] = -1, + [UNW_IA64_AR + 88] = -1, [UNW_IA64_AR + 89] = -1, + [UNW_IA64_AR + 90] = -1, [UNW_IA64_AR + 91] = -1, + [UNW_IA64_AR + 92] = -1, [UNW_IA64_AR + 93] = -1, + [UNW_IA64_AR + 94] = -1, [UNW_IA64_AR + 95] = -1, + [UNW_IA64_AR + 96] = -1, [UNW_IA64_AR + 97] = -1, + [UNW_IA64_AR + 98] = -1, [UNW_IA64_AR + 99] = -1, + [UNW_IA64_AR +100] = -1, [UNW_IA64_AR +101] = -1, + [UNW_IA64_AR +102] = -1, [UNW_IA64_AR +103] = -1, + [UNW_IA64_AR +104] = -1, [UNW_IA64_AR +105] = -1, + [UNW_IA64_AR +106] = -1, [UNW_IA64_AR +107] = -1, + [UNW_IA64_AR +108] = -1, [UNW_IA64_AR +109] = -1, + [UNW_IA64_AR +110] = -1, [UNW_IA64_AR +111] = -1, + [UNW_IA64_AR +112] = -1, [UNW_IA64_AR +113] = -1, + [UNW_IA64_AR +114] = -1, [UNW_IA64_AR +115] = -1, + [UNW_IA64_AR +116] = -1, [UNW_IA64_AR +117] = -1, + [UNW_IA64_AR +118] = -1, [UNW_IA64_AR +119] = -1, + [UNW_IA64_AR +120] = -1, [UNW_IA64_AR +121] = -1, + [UNW_IA64_AR +122] = -1, [UNW_IA64_AR +123] = -1, + [UNW_IA64_AR +124] = -1, [UNW_IA64_AR +125] = -1, + [UNW_IA64_AR +126] = -1, [UNW_IA64_AR +127] = -1, + + [UNW_IA64_BR + 0] = PT_B0, [UNW_IA64_BR + 1] = PT_B1, + [UNW_IA64_BR + 2] = PT_B2, [UNW_IA64_BR + 3] = PT_B3, + [UNW_IA64_BR + 4] = PT_B4, [UNW_IA64_BR + 5] = PT_B5, + [UNW_IA64_BR + 6] = PT_B6, [UNW_IA64_BR + 7] = PT_B7, + + [UNW_IA64_PR] = PT_PR, + [UNW_IA64_CFM] = PT_CFM, + [UNW_IA64_IP] = PT_CR_IIP +#elif defined(HAVE_TTRACE) +# warning No support for ttrace() yet. +#elif defined(UNW_TARGET_HPPA) + [UNW_HPPA_GR + 0] = 0x000, [UNW_HPPA_GR + 1] = 0x004, + [UNW_HPPA_GR + 2] = 0x008, [UNW_HPPA_GR + 3] = 0x00c, + [UNW_HPPA_GR + 4] = 0x010, [UNW_HPPA_GR + 5] = 0x014, + [UNW_HPPA_GR + 6] = 0x018, [UNW_HPPA_GR + 7] = 0x01c, + [UNW_HPPA_GR + 8] = 0x020, [UNW_HPPA_GR + 9] = 0x024, + [UNW_HPPA_GR + 10] = 0x028, [UNW_HPPA_GR + 11] = 0x02c, + [UNW_HPPA_GR + 12] = 0x030, [UNW_HPPA_GR + 13] = 0x034, + [UNW_HPPA_GR + 14] = 0x038, [UNW_HPPA_GR + 15] = 0x03c, + [UNW_HPPA_GR + 16] = 0x040, [UNW_HPPA_GR + 17] = 0x044, + [UNW_HPPA_GR + 18] = 0x048, [UNW_HPPA_GR + 19] = 0x04c, + [UNW_HPPA_GR + 20] = 0x050, [UNW_HPPA_GR + 21] = 0x054, + [UNW_HPPA_GR + 22] = 0x058, [UNW_HPPA_GR + 23] = 0x05c, + [UNW_HPPA_GR + 24] = 0x060, [UNW_HPPA_GR + 25] = 0x064, + [UNW_HPPA_GR + 26] = 0x068, [UNW_HPPA_GR + 27] = 0x06c, + [UNW_HPPA_GR + 28] = 0x070, [UNW_HPPA_GR + 29] = 0x074, + [UNW_HPPA_GR + 30] = 0x078, [UNW_HPPA_GR + 31] = 0x07c, + + [UNW_HPPA_FR + 0] = 0x080, [UNW_HPPA_FR + 1] = 0x088, + [UNW_HPPA_FR + 2] = 0x090, [UNW_HPPA_FR + 3] = 0x098, + [UNW_HPPA_FR + 4] = 0x0a0, [UNW_HPPA_FR + 5] = 0x0a8, + [UNW_HPPA_FR + 6] = 0x0b0, [UNW_HPPA_FR + 7] = 0x0b8, + [UNW_HPPA_FR + 8] = 0x0c0, [UNW_HPPA_FR + 9] = 0x0c8, + [UNW_HPPA_FR + 10] = 0x0d0, [UNW_HPPA_FR + 11] = 0x0d8, + [UNW_HPPA_FR + 12] = 0x0e0, [UNW_HPPA_FR + 13] = 0x0e8, + [UNW_HPPA_FR + 14] = 0x0f0, [UNW_HPPA_FR + 15] = 0x0f8, + [UNW_HPPA_FR + 16] = 0x100, [UNW_HPPA_FR + 17] = 0x108, + [UNW_HPPA_FR + 18] = 0x110, [UNW_HPPA_FR + 19] = 0x118, + [UNW_HPPA_FR + 20] = 0x120, [UNW_HPPA_FR + 21] = 0x128, + [UNW_HPPA_FR + 22] = 0x130, [UNW_HPPA_FR + 23] = 0x138, + [UNW_HPPA_FR + 24] = 0x140, [UNW_HPPA_FR + 25] = 0x148, + [UNW_HPPA_FR + 26] = 0x150, [UNW_HPPA_FR + 27] = 0x158, + [UNW_HPPA_FR + 28] = 0x160, [UNW_HPPA_FR + 29] = 0x168, + [UNW_HPPA_FR + 30] = 0x170, [UNW_HPPA_FR + 31] = 0x178, + + [UNW_HPPA_IP] = 0x1a8 /* IAOQ[0] */ +#elif defined(UNW_TARGET_X86) +#if defined __FreeBSD__ +#define UNW_R_OFF(R, r) \ + [UNW_X86_##R] = offsetof(gregset_t, r_##r), + UNW_R_OFF(EAX, eax) + UNW_R_OFF(EDX, edx) + UNW_R_OFF(ECX, ecx) + UNW_R_OFF(EBX, ebx) + UNW_R_OFF(ESI, esi) + UNW_R_OFF(EDI, edi) + UNW_R_OFF(EBP, ebp) + UNW_R_OFF(ESP, esp) + UNW_R_OFF(EIP, eip) +// UNW_R_OFF(CS, cs) +// UNW_R_OFF(EFLAGS, eflags) +// UNW_R_OFF(SS, ss) +#elif defined __linux__ + [UNW_X86_EAX] = 0x18, + [UNW_X86_EBX] = 0x00, + [UNW_X86_ECX] = 0x04, + [UNW_X86_EDX] = 0x08, + [UNW_X86_ESI] = 0x0c, + [UNW_X86_EDI] = 0x10, + [UNW_X86_EBP] = 0x14, + [UNW_X86_EIP] = 0x30, + [UNW_X86_ESP] = 0x3c +/* CS = 0x34, */ +/* DS = 0x1c, */ +/* ES = 0x20, */ +/* FS = 0x24, */ +/* GS = 0x28, */ +/* ORIG_EAX = 0x2c, */ +/* EFLAGS = 0x38, */ +/* SS = 0x40 */ +#else +#error Port me +#endif +#elif defined(UNW_TARGET_X86_64) +#if defined __FreeBSD__ +#define UNW_R_OFF(R, r) \ + [UNW_X86_64_##R] = offsetof(gregset_t, r_##r), + UNW_R_OFF(RAX, rax) + UNW_R_OFF(RDX, rdx) + UNW_R_OFF(RCX, rcx) + UNW_R_OFF(RBX, rbx) + UNW_R_OFF(RSI, rsi) + UNW_R_OFF(RDI, rdi) + UNW_R_OFF(RBP, rbp) + UNW_R_OFF(RSP, rsp) + UNW_R_OFF(R8, r8) + UNW_R_OFF(R9, r9) + UNW_R_OFF(R10, r10) + UNW_R_OFF(R11, r11) + UNW_R_OFF(R12, r12) + UNW_R_OFF(R13, r13) + UNW_R_OFF(R14, r14) + UNW_R_OFF(R15, r15) + UNW_R_OFF(RIP, rip) +// UNW_R_OFF(CS, cs) +// UNW_R_OFF(EFLAGS, rflags) +// UNW_R_OFF(SS, ss) +#undef UNW_R_OFF +#elif defined __linux__ + [UNW_X86_64_RAX] = 0x50, + [UNW_X86_64_RDX] = 0x60, + [UNW_X86_64_RCX] = 0x58, + [UNW_X86_64_RBX] = 0x28, + [UNW_X86_64_RSI] = 0x68, + [UNW_X86_64_RDI] = 0x70, + [UNW_X86_64_RBP] = 0x20, + [UNW_X86_64_RSP] = 0x98, + [UNW_X86_64_R8] = 0x48, + [UNW_X86_64_R9] = 0x40, + [UNW_X86_64_R10] = 0x38, + [UNW_X86_64_R11] = 0x30, + [UNW_X86_64_R12] = 0x18, + [UNW_X86_64_R13] = 0x10, + [UNW_X86_64_R14] = 0x08, + [UNW_X86_64_R15] = 0x00, + [UNW_X86_64_RIP] = 0x80 +// [UNW_X86_64_CS] = 0x88, +// [UNW_X86_64_EFLAGS] = 0x90, +// [UNW_X86_64_RSP] = 0x98, +// [UNW_X86_64_SS] = 0xa0 +#else +#error Port me +#endif +#elif defined(UNW_TARGET_PPC32) || defined(UNW_TARGET_PPC64) + +#define UNW_REG_SLOT_SIZE sizeof(unsigned long) +#define UNW_PPC_R(v) ((v) * UNW_REG_SLOT_SIZE) +#define UNW_PPC_PT(p) UNW_PPC_R(PT_##p) + +#define UNW_FP_OFF(b, i) \ + [UNW_PPC##b##_F##i] = UNW_PPC_R(PT_FPR0 + i * 8/UNW_REG_SLOT_SIZE) + +#define UNW_R_OFF(b, i) \ + [UNW_PPC##b##_R##i] = UNW_PPC_R(PT_R##i) + +#define UNW_PPC_REGS(b) \ + UNW_R_OFF(b, 0), \ + UNW_R_OFF(b, 1), \ + UNW_R_OFF(b, 2), \ + UNW_R_OFF(b, 3), \ + UNW_R_OFF(b, 4), \ + UNW_R_OFF(b, 5), \ + UNW_R_OFF(b, 6), \ + UNW_R_OFF(b, 7), \ + UNW_R_OFF(b, 8), \ + UNW_R_OFF(b, 9), \ + UNW_R_OFF(b, 10), \ + UNW_R_OFF(b, 11), \ + UNW_R_OFF(b, 12), \ + UNW_R_OFF(b, 13), \ + UNW_R_OFF(b, 14), \ + UNW_R_OFF(b, 15), \ + UNW_R_OFF(b, 16), \ + UNW_R_OFF(b, 17), \ + UNW_R_OFF(b, 18), \ + UNW_R_OFF(b, 19), \ + UNW_R_OFF(b, 20), \ + UNW_R_OFF(b, 21), \ + UNW_R_OFF(b, 22), \ + UNW_R_OFF(b, 23), \ + UNW_R_OFF(b, 24), \ + UNW_R_OFF(b, 25), \ + UNW_R_OFF(b, 26), \ + UNW_R_OFF(b, 27), \ + UNW_R_OFF(b, 28), \ + UNW_R_OFF(b, 29), \ + UNW_R_OFF(b, 30), \ + UNW_R_OFF(b, 31), \ + \ + [UNW_PPC##b##_CTR] = UNW_PPC_PT(CTR), \ + [UNW_PPC##b##_XER] = UNW_PPC_PT(XER), \ + [UNW_PPC##b##_LR] = UNW_PPC_PT(LNK), \ + \ + UNW_FP_OFF(b, 0), \ + UNW_FP_OFF(b, 1), \ + UNW_FP_OFF(b, 2), \ + UNW_FP_OFF(b, 3), \ + UNW_FP_OFF(b, 4), \ + UNW_FP_OFF(b, 5), \ + UNW_FP_OFF(b, 6), \ + UNW_FP_OFF(b, 7), \ + UNW_FP_OFF(b, 8), \ + UNW_FP_OFF(b, 9), \ + UNW_FP_OFF(b, 10), \ + UNW_FP_OFF(b, 11), \ + UNW_FP_OFF(b, 12), \ + UNW_FP_OFF(b, 13), \ + UNW_FP_OFF(b, 14), \ + UNW_FP_OFF(b, 15), \ + UNW_FP_OFF(b, 16), \ + UNW_FP_OFF(b, 17), \ + UNW_FP_OFF(b, 18), \ + UNW_FP_OFF(b, 19), \ + UNW_FP_OFF(b, 20), \ + UNW_FP_OFF(b, 21), \ + UNW_FP_OFF(b, 22), \ + UNW_FP_OFF(b, 23), \ + UNW_FP_OFF(b, 24), \ + UNW_FP_OFF(b, 25), \ + UNW_FP_OFF(b, 26), \ + UNW_FP_OFF(b, 27), \ + UNW_FP_OFF(b, 28), \ + UNW_FP_OFF(b, 29), \ + UNW_FP_OFF(b, 30), \ + UNW_FP_OFF(b, 31) + +#define UNW_PPC32_REGS \ + [UNW_PPC32_FPSCR] = UNW_PPC_PT(FPSCR), \ + [UNW_PPC32_CCR] = UNW_PPC_PT(CCR) + +#define UNW_VR_OFF(i) \ + [UNW_PPC64_V##i] = UNW_PPC_R(PT_VR0 + i * 2) + +#define UNW_PPC64_REGS \ + [UNW_PPC64_NIP] = UNW_PPC_PT(NIP), \ + [UNW_PPC64_FRAME_POINTER] = -1, \ + [UNW_PPC64_ARG_POINTER] = -1, \ + [UNW_PPC64_CR0] = -1, \ + [UNW_PPC64_CR1] = -1, \ + [UNW_PPC64_CR2] = -1, \ + [UNW_PPC64_CR3] = -1, \ + [UNW_PPC64_CR4] = -1, \ + [UNW_PPC64_CR5] = -1, \ + [UNW_PPC64_CR6] = -1, \ + [UNW_PPC64_CR7] = -1, \ + [UNW_PPC64_VRSAVE] = UNW_PPC_PT(VRSAVE), \ + [UNW_PPC64_VSCR] = UNW_PPC_PT(VSCR), \ + [UNW_PPC64_SPE_ACC] = -1, \ + [UNW_PPC64_SPEFSCR] = -1, \ + UNW_VR_OFF(0), \ + UNW_VR_OFF(1), \ + UNW_VR_OFF(2), \ + UNW_VR_OFF(3), \ + UNW_VR_OFF(4), \ + UNW_VR_OFF(5), \ + UNW_VR_OFF(6), \ + UNW_VR_OFF(7), \ + UNW_VR_OFF(8), \ + UNW_VR_OFF(9), \ + UNW_VR_OFF(10), \ + UNW_VR_OFF(11), \ + UNW_VR_OFF(12), \ + UNW_VR_OFF(13), \ + UNW_VR_OFF(14), \ + UNW_VR_OFF(15), \ + UNW_VR_OFF(16), \ + UNW_VR_OFF(17), \ + UNW_VR_OFF(18), \ + UNW_VR_OFF(19), \ + UNW_VR_OFF(20), \ + UNW_VR_OFF(21), \ + UNW_VR_OFF(22), \ + UNW_VR_OFF(23), \ + UNW_VR_OFF(24), \ + UNW_VR_OFF(25), \ + UNW_VR_OFF(26), \ + UNW_VR_OFF(27), \ + UNW_VR_OFF(28), \ + UNW_VR_OFF(29), \ + UNW_VR_OFF(30), \ + UNW_VR_OFF(31) + +#if defined(UNW_TARGET_PPC32) + UNW_PPC_REGS(32), + UNW_PPC32_REGS, +#else + UNW_PPC_REGS(64), + UNW_PPC64_REGS, +#endif + +#elif defined(UNW_TARGET_ARM) + [UNW_ARM_R0] = 0x00, + [UNW_ARM_R1] = 0x04, + [UNW_ARM_R2] = 0x08, + [UNW_ARM_R3] = 0x0c, + [UNW_ARM_R4] = 0x10, + [UNW_ARM_R5] = 0x14, + [UNW_ARM_R6] = 0x18, + [UNW_ARM_R7] = 0x1c, + [UNW_ARM_R8] = 0x20, + [UNW_ARM_R9] = 0x24, + [UNW_ARM_R10] = 0x28, + [UNW_ARM_R11] = 0x2c, + [UNW_ARM_R12] = 0x30, + [UNW_ARM_R13] = 0x34, + [UNW_ARM_R14] = 0x38, + [UNW_ARM_R15] = 0x3c, +#elif defined(UNW_TARGET_MIPS) +#elif defined(UNW_TARGET_SH) +#elif defined(UNW_TARGET_AARCH64) + [UNW_AARCH64_X0] = 0x00, + [UNW_AARCH64_X1] = 0x08, + [UNW_AARCH64_X2] = 0x10, + [UNW_AARCH64_X3] = 0x18, + [UNW_AARCH64_X4] = 0x20, + [UNW_AARCH64_X5] = 0x28, + [UNW_AARCH64_X6] = 0x30, + [UNW_AARCH64_X7] = 0x38, + [UNW_AARCH64_X8] = 0x40, + [UNW_AARCH64_X9] = 0x48, + [UNW_AARCH64_X10] = 0x50, + [UNW_AARCH64_X11] = 0x58, + [UNW_AARCH64_X12] = 0x60, + [UNW_AARCH64_X13] = 0x68, + [UNW_AARCH64_X14] = 0x70, + [UNW_AARCH64_X15] = 0x78, + [UNW_AARCH64_X16] = 0x80, + [UNW_AARCH64_X17] = 0x88, + [UNW_AARCH64_X18] = 0x90, + [UNW_AARCH64_X19] = 0x98, + [UNW_AARCH64_X20] = 0xa0, + [UNW_AARCH64_X21] = 0xa8, + [UNW_AARCH64_X22] = 0xb0, + [UNW_AARCH64_X23] = 0xb8, + [UNW_AARCH64_X24] = 0xc0, + [UNW_AARCH64_X25] = 0xc8, + [UNW_AARCH64_X26] = 0xd0, + [UNW_AARCH64_X27] = 0xd8, + [UNW_AARCH64_X28] = 0xe0, + [UNW_AARCH64_X29] = 0xe8, + [UNW_AARCH64_X30] = 0xf0, + [UNW_AARCH64_SP] = 0xf8, + [UNW_AARCH64_PC] = 0x100, + [UNW_AARCH64_PSTATE] = 0x108 +#elif defined(UNW_TARGET_TILEGX) + [UNW_TILEGX_R0] = 0x00, + [UNW_TILEGX_R1] = 0x08, + [UNW_TILEGX_R2] = 0x10, + [UNW_TILEGX_R3] = 0x08, + [UNW_TILEGX_R4] = 0x20, + [UNW_TILEGX_R5] = 0x28, + [UNW_TILEGX_R6] = 0x30, + [UNW_TILEGX_R7] = 0x38, + [UNW_TILEGX_R8] = 0x40, + [UNW_TILEGX_R9] = 0x48, + [UNW_TILEGX_R10] = 0x50, + [UNW_TILEGX_R11] = 0x58, + [UNW_TILEGX_R12] = 0x60, + [UNW_TILEGX_R13] = 0x68, + [UNW_TILEGX_R14] = 0x70, + [UNW_TILEGX_R15] = 0x78, + [UNW_TILEGX_R16] = 0x80, + [UNW_TILEGX_R17] = 0x88, + [UNW_TILEGX_R18] = 0x90, + [UNW_TILEGX_R19] = 0x98, + [UNW_TILEGX_R20] = 0xa0, + [UNW_TILEGX_R21] = 0xa8, + [UNW_TILEGX_R22] = 0xb0, + [UNW_TILEGX_R23] = 0xb8, + [UNW_TILEGX_R24] = 0xc0, + [UNW_TILEGX_R25] = 0xc8, + [UNW_TILEGX_R26] = 0xd0, + [UNW_TILEGX_R27] = 0xd8, + [UNW_TILEGX_R28] = 0xe0, + [UNW_TILEGX_R29] = 0xe8, + [UNW_TILEGX_R30] = 0xf0, + [UNW_TILEGX_R31] = 0xf8, + [UNW_TILEGX_R32] = 0x100, + [UNW_TILEGX_R33] = 0x108, + [UNW_TILEGX_R34] = 0x110, + [UNW_TILEGX_R35] = 0x118, + [UNW_TILEGX_R36] = 0x120, + [UNW_TILEGX_R37] = 0x128, + [UNW_TILEGX_R38] = 0x130, + [UNW_TILEGX_R39] = 0x138, + [UNW_TILEGX_R40] = 0x140, + [UNW_TILEGX_R41] = 0x148, + [UNW_TILEGX_R42] = 0x150, + [UNW_TILEGX_R43] = 0x158, + [UNW_TILEGX_R44] = 0x160, + [UNW_TILEGX_R45] = 0x168, + [UNW_TILEGX_R46] = 0x170, + [UNW_TILEGX_R47] = 0x178, + [UNW_TILEGX_R48] = 0x180, + [UNW_TILEGX_R49] = 0x188, + [UNW_TILEGX_R50] = 0x190, + [UNW_TILEGX_R51] = 0x198, + [UNW_TILEGX_R52] = 0x1a0, + [UNW_TILEGX_R53] = 0x1a8, + [UNW_TILEGX_R54] = 0x1b0, + [UNW_TILEGX_R55] = 0x1b8, + [UNW_TILEGX_PC] = 0x1a0 +#else +# error Fix me. +#endif + }; diff --git a/src/libs/libunwind/ptrace/_UPT_resume.c b/src/libs/libunwind/ptrace/_UPT_resume.c new file mode 100644 index 0000000000..d70a0d4821 --- /dev/null +++ b/src/libs/libunwind/ptrace/_UPT_resume.c @@ -0,0 +1,40 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +int +_UPT_resume (unw_addr_space_t as, unw_cursor_t *c, void *arg) +{ + struct UPT_info *ui = arg; + +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#elif HAVE_DECL_PTRACE_CONT + return ptrace (PTRACE_CONT, ui->pid, 0, 0); +#elif HAVE_DECL_PT_CONTINUE + return ptrace(PT_CONTINUE, ui->pid, (caddr_t)1, 0); +#endif +} diff --git a/src/libs/libunwind/setjmp/longjmp.c b/src/libs/libunwind/setjmp/longjmp.c new file mode 100644 index 0000000000..8295a9b8ed --- /dev/null +++ b/src/libs/libunwind/setjmp/longjmp.c @@ -0,0 +1,115 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#define UNW_LOCAL_ONLY + +#undef _FORTIFY_SOURCE +#include +#include +#include +#include +#include + +#include "jmpbuf.h" +#include "setjmp_i.h" + +#if defined(__GLIBC__) +#if __GLIBC_PREREQ(2, 4) + +/* Starting with glibc-2.4, {sig,}setjmp in GLIBC obfuscates the + register values in jmp_buf by XORing them with a "random" + canary value. + + This makes it impossible to implement longjmp, as we + can never match wp[JB_SP], unless we decode the canary first. + + Doing so is possible, but doesn't appear to be worth the trouble, + so we simply defer to glibc longjmp here. */ +#define _longjmp __nonworking__longjmp +#define longjmp __nonworking_longjmp +static void _longjmp (jmp_buf env, int val); +static void longjmp (jmp_buf env, int val); +#endif +#endif /* __GLIBC__ */ + +void +_longjmp (jmp_buf env, int val) +{ + extern int _UI_longjmp_cont; + unw_context_t uc; + unw_cursor_t c; + unw_word_t sp; + unw_word_t *wp = (unw_word_t *) env; + + if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0) + abort (); + + do + { + if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0) + abort (); +#ifdef __FreeBSD__ + if (sp != wp[JB_SP] + sizeof(unw_word_t)) +#else + if (sp != wp[JB_SP]) +#endif + continue; + + if (!bsp_match (&c, wp)) + continue; + + /* found the right frame: */ + + assert (UNW_NUM_EH_REGS >= 2); + + if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0 + || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0 + || unw_set_reg (&c, UNW_REG_IP, + (unw_word_t) (uintptr_t) &_UI_longjmp_cont)) + abort (); + + unw_resume (&c); + + abort (); + } + while (unw_step (&c) > 0); + + abort (); +} + +#ifdef __GNUC__ +#define STRINGIFY1(x) #x +#define STRINGIFY(x) STRINGIFY1(x) +void longjmp (jmp_buf env, int val) + __attribute__ ((alias (STRINGIFY(_longjmp)))); +#else + +void +longjmp (jmp_buf env, int val) +{ + _longjmp (env, val); +} + +#endif /* __GNUC__ */ diff --git a/src/libs/libunwind/setjmp/setjmp.c b/src/libs/libunwind/setjmp/setjmp.c new file mode 100644 index 0000000000..bec9fc7d5b --- /dev/null +++ b/src/libs/libunwind/setjmp/setjmp.c @@ -0,0 +1,49 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "jmpbuf.h" + +/* Why use K&R syntax here? setjmp() is often a macro and that + expands into a call to, say, __setjmp() and we need to define the + libunwind-version of setjmp() with the name of the actual function. + Using K&R syntax lets us keep the setjmp() macro while keeping the + syntax valid... This trick works provided setjmp() doesn't do + anything other than a function call. */ + +int +setjmp (env) + jmp_buf env; +{ + void **wp = (void **) env; + + /* this should work on most platforms, but may not be + performance-optimal; check the code! */ + wp[JB_SP] = __builtin_frame_address (0); + wp[JB_RP] = (void *) __builtin_return_address (0); + return 0; +} diff --git a/src/libs/libunwind/setjmp/setjmp_i.h b/src/libs/libunwind/setjmp/setjmp_i.h new file mode 100644 index 0000000000..4d9139693e --- /dev/null +++ b/src/libs/libunwind/setjmp/setjmp_i.h @@ -0,0 +1,118 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#if UNW_TARGET_IA64 + +#include "libunwind_i.h" +#include "tdep-ia64/rse.h" + +static inline int +bsp_match (unw_cursor_t *c, unw_word_t *wp) +{ + unw_word_t bsp, pfs, sol; + + if (unw_get_reg (c, UNW_IA64_BSP, &bsp) < 0 + || unw_get_reg (c, UNW_IA64_AR_PFS, &pfs) < 0) + abort (); + + /* simulate the effect of "br.call sigsetjmp" on ar.bsp: */ + sol = (pfs >> 7) & 0x7f; + bsp = rse_skip_regs (bsp, sol); + + if (bsp != wp[JB_BSP]) + return 0; + + if (unlikely (sol == 0)) + { + unw_word_t sp, prev_sp; + unw_cursor_t tmp = *c; + + /* The caller of {sig,}setjmp() cannot have a NULL-frame. If we + see a NULL-frame, we haven't reached the right target yet. + To have a NULL-frame, the number of locals must be zero and + the stack-frame must also be empty. */ + + if (unw_step (&tmp) < 0) + abort (); + + if (unw_get_reg (&tmp, UNW_REG_SP, &sp) < 0 + || unw_get_reg (&tmp, UNW_REG_SP, &prev_sp) < 0) + abort (); + + if (sp == prev_sp) + /* got a NULL-frame; keep looking... */ + return 0; + } + return 1; +} + +/* On ia64 we cannot always call sigprocmask() at + _UI_siglongjmp_cont() because the signal may have switched stacks + and the old stack's register-backing store may have overflown, + leaving us no space to allocate the stacked registers needed to + call sigprocmask(). Fortunately, we can just let unw_resume() (via + sigreturn) take care of restoring the signal-mask. That's faster + anyhow. */ +static inline int +resume_restores_sigmask (unw_cursor_t *c, unw_word_t *wp) +{ + unw_word_t sc_addr = ((struct cursor *) c)->sigcontext_addr; + struct sigcontext *sc = (struct sigcontext *) sc_addr; + sigset_t current_mask; + void *mp; + + if (!sc_addr) + return 0; + + /* let unw_resume() install the desired signal mask */ + + if (wp[JB_MASK_SAVED]) + mp = &wp[JB_MASK]; + else + { + if (sigprocmask (SIG_BLOCK, NULL, ¤t_mask) < 0) + abort (); + mp = ¤t_mask; + } + memcpy (&sc->sc_mask, mp, sizeof (sc->sc_mask)); + return 1; +} + +#else /* !UNW_TARGET_IA64 */ + +static inline int +bsp_match (unw_cursor_t *c, unw_word_t *wp) +{ + return 1; +} + +static inline int +resume_restores_sigmask (unw_cursor_t *c, unw_word_t *wp) +{ + /* We may want to do this analogously as for ia64... */ + return 0; +} + +#endif /* !UNW_TARGET_IA64 */ diff --git a/src/libs/libunwind/setjmp/siglongjmp.c b/src/libs/libunwind/setjmp/siglongjmp.c new file mode 100644 index 0000000000..0e286f6f08 --- /dev/null +++ b/src/libs/libunwind/setjmp/siglongjmp.c @@ -0,0 +1,127 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#define UNW_LOCAL_ONLY + +#include + +#include "libunwind_i.h" +#include "jmpbuf.h" +#include "setjmp_i.h" + +#if !defined(_NSIG) && defined(_SIG_MAXSIG) +# define _NSIG (_SIG_MAXSIG - 1) +#endif + +#if defined(__GLIBC__) +#if __GLIBC_PREREQ(2, 4) + +/* Starting with glibc-2.4, {sig,}setjmp in GLIBC obfuscates the + register values in jmp_buf by XORing them with a "random" + canary value. + + This makes it impossible to implement longjmp, as we + can never match wp[JB_SP], unless we decode the canary first. + + Doing so is possible, but doesn't appear to be worth the trouble, + so we simply defer to glibc siglongjmp here. */ + +#define siglongjmp __nonworking_siglongjmp +static void siglongjmp (sigjmp_buf env, int val) UNUSED; +#endif +#endif /* __GLIBC_PREREQ */ + +void +siglongjmp (sigjmp_buf env, int val) +{ + unw_word_t *wp = (unw_word_t *) env; + extern int _UI_siglongjmp_cont; + extern int _UI_longjmp_cont; + unw_context_t uc; + unw_cursor_t c; + unw_word_t sp; + int *cont; + + if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0) + abort (); + + do + { + if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0) + abort (); +#ifdef __FreeBSD__ + if (sp != wp[JB_SP] + sizeof(unw_word_t)) +#else + if (sp != wp[JB_SP]) +#endif + continue; + + if (!bsp_match (&c, wp)) + continue; + + /* found the right frame: */ + + /* default to resuming without restoring signal-mask */ + cont = &_UI_longjmp_cont; + + /* Order of evaluation is important here: if unw_resume() + restores signal mask, we must set it up appropriately, even + if wp[JB_MASK_SAVED] is FALSE. */ + if (!resume_restores_sigmask (&c, wp) && wp[JB_MASK_SAVED]) + { + /* sigmask was saved */ +#if defined(__linux__) + if (UNW_NUM_EH_REGS < 4 || _NSIG > 16 * sizeof (unw_word_t)) + /* signal mask doesn't fit into EH arguments and we can't + put it on the stack without overwriting something + else... */ + abort (); + else + if (unw_set_reg (&c, UNW_REG_EH + 2, wp[JB_MASK]) < 0 + || (_NSIG > 8 * sizeof (unw_word_t) + && unw_set_reg (&c, UNW_REG_EH + 3, wp[JB_MASK + 1]) < 0)) + abort (); +#elif defined(__FreeBSD__) + if (unw_set_reg (&c, UNW_REG_EH + 2, &wp[JB_MASK]) < 0) + abort(); +#else +#error Port me +#endif + cont = &_UI_siglongjmp_cont; + } + + if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0 + || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0 + || unw_set_reg (&c, UNW_REG_IP, (unw_word_t) (uintptr_t) cont)) + abort (); + + unw_resume (&c); + + abort (); + } + while (unw_step (&c) > 0); + + abort (); +} diff --git a/src/libs/libunwind/setjmp/sigsetjmp.c b/src/libs/libunwind/setjmp/sigsetjmp.c new file mode 100644 index 0000000000..f84935d638 --- /dev/null +++ b/src/libs/libunwind/setjmp/sigsetjmp.c @@ -0,0 +1,50 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include + +#include "jmpbuf.h" + +int +sigsetjmp (sigjmp_buf env, int savemask) +{ + unw_word_t *wp = (unw_word_t *) env; + + /* This should work on most platforms, but may not be + performance-optimal; check the code! */ + + wp[JB_SP] = (unw_word_t) __builtin_frame_address (0); + wp[JB_RP] = (unw_word_t) __builtin_return_address (0); + wp[JB_MASK_SAVED] = savemask; + + /* Note: we assume here that "wp" has same or better alignment as + sigset_t. */ + if (savemask + && sigprocmask (SIG_BLOCK, NULL, (sigset_t *) (wp + JB_MASK)) < 0) + abort (); + return 0; +} diff --git a/src/libs/libunwind/sh/Gcreate_addr_space.c b/src/libs/libunwind/sh/Gcreate_addr_space.c new file mode 100644 index 0000000000..1907d04672 --- /dev/null +++ b/src/libs/libunwind/sh/Gcreate_addr_space.c @@ -0,0 +1,59 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "unwind_i.h" + +PROTECTED unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* SH supports little-endian and big-endian. */ + if (byte_order != 0 && byte_order != __LITTLE_ENDIAN + && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + /* Default to little-endian for SH. */ + if (byte_order == 0 || byte_order == __LITTLE_ENDIAN) + as->big_endian = 0; + else + as->big_endian = 1; + + return as; +#endif +} diff --git a/src/libs/libunwind/sh/Gget_proc_info.c b/src/libs/libunwind/sh/Gget_proc_info.c new file mode 100644 index 0000000000..de9199f995 --- /dev/null +++ b/src/libs/libunwind/sh/Gget_proc_info.c @@ -0,0 +1,39 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + ret = dwarf_make_proc_info (&c->dwarf); + if (ret < 0) + return ret; + + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/libs/libunwind/sh/Gget_save_loc.c b/src/libs/libunwind/sh/Gget_save_loc.c new file mode 100644 index 0000000000..7690a80871 --- /dev/null +++ b/src/libs/libunwind/sh/Gget_save_loc.c @@ -0,0 +1,83 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + switch (reg) + { + case UNW_SH_R0: + case UNW_SH_R1: + case UNW_SH_R2: + case UNW_SH_R3: + case UNW_SH_R4: + case UNW_SH_R5: + case UNW_SH_R6: + case UNW_SH_R7: + case UNW_SH_R8: + case UNW_SH_R9: + case UNW_SH_R10: + case UNW_SH_R11: + case UNW_SH_R12: + case UNW_SH_R13: + case UNW_SH_R14: + case UNW_SH_R15: + case UNW_SH_PC: + case UNW_SH_PR: + loc = c->dwarf.loc[reg]; + break; + + default: + loc = DWARF_NULL_LOC; /* default to "not saved" */ + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/libs/libunwind/sh/Gglobal.c b/src/libs/libunwind/sh/Gglobal.c new file mode 100644 index 0000000000..ed27333976 --- /dev/null +++ b/src/libs/libunwind/sh/Gglobal.c @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (sh_lock); +HIDDEN int tdep_init_done; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&sh_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + sh_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&sh_lock, saved_mask); +} diff --git a/src/libs/libunwind/sh/Ginit.c b/src/libs/libunwind/sh/Ginit.c new file mode 100644 index 0000000000..b380db1da6 --- /dev/null +++ b/src/libs/libunwind/sh/Ginit.c @@ -0,0 +1,186 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +PROTECTED unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static inline void * +uc_addr (ucontext_t *uc, int reg) +{ + if (reg >= UNW_SH_R0 && reg <= UNW_SH_PR) + return &uc->uc_mcontext.gregs[reg]; + else + return NULL; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (16, "mem[%x] <- %x\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + *val = *(unw_word_t *) addr; + Debug (16, "mem[%x] -> %x\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = arg; + + if (unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %x\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %x\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + unw_fpreg_t *addr; + + if (!unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +sh_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = sh_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/sh/Ginit_local.c b/src/libs/libunwind/sh/Ginit_local.c new file mode 100644 index 0000000000..e1cc30c60f --- /dev/null +++ b/src/libs/libunwind/sh/Ginit_local.c @@ -0,0 +1,55 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = uc; + + return common_init (c, 1); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/sh/Ginit_remote.c b/src/libs/libunwind/sh/Ginit_remote.c new file mode 100644 index 0000000000..f284e994f4 --- /dev/null +++ b/src/libs/libunwind/sh/Ginit_remote.c @@ -0,0 +1,45 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +PROTECTED int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/libs/libunwind/sh/Gis_signal_frame.c b/src/libs/libunwind/sh/Gis_signal_frame.c new file mode 100644 index 0000000000..9719f8e084 --- /dev/null +++ b/src/libs/libunwind/sh/Gis_signal_frame.c @@ -0,0 +1,119 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* Disassembly of the Linux VDSO sigreturn functions: + +00000000 <__kernel_sigreturn>: + 0: 05 93 mov.w e <__kernel_sigreturn+0xe>,r3 ! 77 + 2: 10 c3 trapa #16 + 4: 0b 20 or r0,r0 + 6: 0b 20 or r0,r0 + 8: 0b 20 or r0,r0 + a: 0b 20 or r0,r0 + c: 0b 20 or r0,r0 + e: 77 00 .word 0x0077 + 10: 09 00 nop + 12: 09 00 nop + 14: 09 00 nop + 16: 09 00 nop + 18: 09 00 nop + 1a: 09 00 nop + 1c: 09 00 nop + 1e: 09 00 nop + +00000020 <__kernel_rt_sigreturn>: + 20: 05 93 mov.w 2e <__kernel_rt_sigreturn+0xe>,r3 ! ad + 22: 10 c3 trapa #16 + 24: 0b 20 or r0,r0 + 26: 0b 20 or r0,r0 + 28: 0b 20 or r0,r0 + 2a: 0b 20 or r0,r0 + 2c: 0b 20 or r0,r0 + 2e: ad 00 mov.w @(r0,r10),r0 + 30: 09 00 nop + 32: 09 00 nop + 34: 09 00 nop + 36: 09 00 nop + 38: 09 00 nop + 3a: 09 00 nop + 3c: 09 00 nop + 3e: 09 00 nop +*/ + +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors (as); + arg = c->dwarf.as_arg; + + ip = c->dwarf.ip; + + ret = (*a->access_mem) (as, ip, &w0, 0, arg); + if (ret < 0) + return ret; + + if (w0 != 0xc3109305) + return 0; + + ret = (*a->access_mem) (as, ip+4, &w0, 0, arg); + if (ret < 0) + return ret; + + if (w0 != 0x200b200b) + return 0; + + ret = (*a->access_mem) (as, ip+8, &w0, 0, arg); + if (ret < 0) + return ret; + + if (w0 != 0x200b200b) + return 0; + + ret = (*a->access_mem) (as, ip+12, &w0, 0, arg); + if (ret < 0) + return ret; + + if (w0 == 0x0077200b) + return 1; /* non-RT */ + else if (w0 == 0x00ad200b) + return 2; /* RT */ + + /* does not look like a signal frame */ + return 0; + +#else + return -UNW_ENOINFO; +#endif +} diff --git a/src/libs/libunwind/sh/Gregs.c b/src/libs/libunwind/sh/Gregs.c new file mode 100644 index 0000000000..fb4ca74003 --- /dev/null +++ b/src/libs/libunwind/sh/Gregs.c @@ -0,0 +1,79 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + + switch (reg) + { + case UNW_SH_R0: + case UNW_SH_R1: + case UNW_SH_R2: + case UNW_SH_R3: + case UNW_SH_R4: + case UNW_SH_R5: + case UNW_SH_R6: + case UNW_SH_R7: + case UNW_SH_R8: + case UNW_SH_R9: + case UNW_SH_R10: + case UNW_SH_R11: + case UNW_SH_R12: + case UNW_SH_R13: + case UNW_SH_R14: + case UNW_SH_PC: + case UNW_SH_PR: + loc = c->dwarf.loc[reg]; + break; + + case UNW_SH_R15: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} diff --git a/src/libs/libunwind/sh/Gresume.c b/src/libs/libunwind/sh/Gresume.c new file mode 100644 index 0000000000..b14e419bdd --- /dev/null +++ b/src/libs/libunwind/sh/Gresume.c @@ -0,0 +1,165 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +sh_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_tdep_context_t *uc = c->dwarf.as_arg; + + if (c->sigcontext_format == SH_SCF_NONE) + { + /* Since there are no signals involved here we restore the non scratch + registers only. */ + unsigned long regs[8]; + regs[0] = uc->uc_mcontext.gregs[8]; + regs[1] = uc->uc_mcontext.gregs[9]; + regs[2] = uc->uc_mcontext.gregs[10]; + regs[3] = uc->uc_mcontext.gregs[11]; + regs[4] = uc->uc_mcontext.gregs[12]; + regs[5] = uc->uc_mcontext.gregs[13]; + regs[6] = uc->uc_mcontext.gregs[14]; + regs[7] = uc->uc_mcontext.gregs[15]; + unsigned long pc = uc->uc_mcontext.pr; + + struct regs_overlay { + char x[sizeof(regs)]; + }; + + asm volatile ( + "mov.l @%0+, r8\n" + "mov.l @%0+, r9\n" + "mov.l @%0+, r10\n" + "mov.l @%0+, r11\n" + "mov.l @%0+, r12\n" + "mov.l @%0+, r13\n" + "mov.l @%0+, r14\n" + "mov.l @%0, r15\n" + "lds %1, pr\n" + "rts\n" + "nop\n" + : + : "r" (regs), + "r" (pc), + "m" (*(struct regs_overlay *)regs) + ); + } + else + { + /* In case a signal frame is involved, we're using its trampoline which + calls sigreturn. */ + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + sc->sc_regs[0] = uc->uc_mcontext.gregs[0]; + sc->sc_regs[1] = uc->uc_mcontext.gregs[1]; + sc->sc_regs[2] = uc->uc_mcontext.gregs[2]; + sc->sc_regs[3] = uc->uc_mcontext.gregs[3]; + sc->sc_regs[4] = uc->uc_mcontext.gregs[4]; + sc->sc_regs[5] = uc->uc_mcontext.gregs[5]; + sc->sc_regs[6] = uc->uc_mcontext.gregs[6]; + sc->sc_regs[7] = uc->uc_mcontext.gregs[7]; + sc->sc_regs[8] = uc->uc_mcontext.gregs[8]; + sc->sc_regs[9] = uc->uc_mcontext.gregs[9]; + sc->sc_regs[10] = uc->uc_mcontext.gregs[10]; + sc->sc_regs[11] = uc->uc_mcontext.gregs[11]; + sc->sc_regs[12] = uc->uc_mcontext.gregs[12]; + sc->sc_regs[13] = uc->uc_mcontext.gregs[13]; + sc->sc_regs[14] = uc->uc_mcontext.gregs[14]; + sc->sc_regs[15] = uc->uc_mcontext.gregs[15]; + sc->sc_pc = uc->uc_mcontext.pc; + sc->sc_pr = uc->uc_mcontext.pr; + + /* Set the SP and the PC in order to continue execution at the modified + trampoline which restores the signal mask and the registers. */ + asm __volatile__ ( + "mov %0, r15\n" + "lds %1, pr\n" + "rts\n" + "nop\n" + : + : "r" (c->sigcontext_sp), + "r" (c->sigcontext_pc) + ); + } + unreachable(); +#endif + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +static inline void +establish_machine_state (struct cursor *c) +{ + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + as->acc.access_fpreg (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + as->acc.access_reg (as, reg, &val, 1, arg); + } + } +} + +PROTECTED int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + + Debug (1, "(cursor=%p)\n", c); + + if (!c->dwarf.ip) + { + /* This can happen easily when the frame-chain gets truncated + due to bad or missing unwind-info. */ + Debug (1, "refusing to resume execution at address 0\n"); + return -UNW_EINVAL; + } + + establish_machine_state (c); + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/libs/libunwind/sh/Gstep.c b/src/libs/libunwind/sh/Gstep.c new file mode 100644 index 0000000000..9bbb5ff9ef --- /dev/null +++ b/src/libs/libunwind/sh/Gstep.c @@ -0,0 +1,117 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +PROTECTED int +unw_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; + struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); + + if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) + return -UNW_EUNSPEC; + + ret = unw_is_signal_frame (cursor); + Debug(1, "unw_is_signal_frame()=%d\n", ret); + + /* Save the SP and PC to be able to return execution at this point + later in time (unw_resume). */ + c->sigcontext_sp = c->dwarf.cfa; + c->sigcontext_pc = c->dwarf.ip; + + if (ret == 1) + { + /* Handle non-RT signal frame. */ + c->sigcontext_format = SH_SCF_LINUX_SIGFRAME; + sc_addr = sp_addr; + } + else if (ret == 2) + { + /* Handle RT signal frame. */ + c->sigcontext_format = SH_SCF_LINUX_RT_SIGFRAME; + sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; + } + else + return -UNW_EUNSPEC; + + c->sigcontext_addr = sc_addr; + + /* Update the dwarf cursor. + Set the location of the registers to the corresponding addresses of the + uc_mcontext / sigcontext structure contents. */ + c->dwarf.loc[UNW_SH_R0] = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0); + c->dwarf.loc[UNW_SH_R1] = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0); + c->dwarf.loc[UNW_SH_R2] = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0); + c->dwarf.loc[UNW_SH_R3] = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0); + c->dwarf.loc[UNW_SH_R4] = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0); + c->dwarf.loc[UNW_SH_R5] = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0); + c->dwarf.loc[UNW_SH_R6] = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0); + c->dwarf.loc[UNW_SH_R7] = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0); + c->dwarf.loc[UNW_SH_R8] = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0); + c->dwarf.loc[UNW_SH_R9] = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0); + c->dwarf.loc[UNW_SH_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0); + c->dwarf.loc[UNW_SH_R11] = DWARF_LOC (sc_addr + LINUX_SC_R11_OFF, 0); + c->dwarf.loc[UNW_SH_R12] = DWARF_LOC (sc_addr + LINUX_SC_R12_OFF, 0); + c->dwarf.loc[UNW_SH_R13] = DWARF_LOC (sc_addr + LINUX_SC_R13_OFF, 0); + c->dwarf.loc[UNW_SH_R14] = DWARF_LOC (sc_addr + LINUX_SC_R14_OFF, 0); + c->dwarf.loc[UNW_SH_R15] = DWARF_LOC (sc_addr + LINUX_SC_R15_OFF, 0); + c->dwarf.loc[UNW_SH_PR] = DWARF_LOC (sc_addr + LINUX_SC_PR_OFF, 0); + c->dwarf.loc[UNW_SH_PC] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0); + + /* Set SP/CFA and PC/IP. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_SH_R15], &c->dwarf.cfa); + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_SH_PC], &c->dwarf.ip); + + c->dwarf.pi_valid = 0; + + return 1; +} + +PROTECTED int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if (unw_is_signal_frame (cursor)) + return unw_handle_signal_frame (cursor); + + ret = dwarf_step (&c->dwarf); + + if (unlikely (ret == -UNW_ESTOPUNWIND)) + return ret; + + if (unlikely (ret < 0)) + return 0; + + return (c->dwarf.ip == 0) ? 0 : 1; +} diff --git a/src/libs/libunwind/sh/Lcreate_addr_space.c b/src/libs/libunwind/sh/Lcreate_addr_space.c new file mode 100644 index 0000000000..0f2dc6be90 --- /dev/null +++ b/src/libs/libunwind/sh/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/libs/libunwind/sh/Lget_proc_info.c b/src/libs/libunwind/sh/Lget_proc_info.c new file mode 100644 index 0000000000..69028b019f --- /dev/null +++ b/src/libs/libunwind/sh/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/libs/libunwind/sh/Lget_save_loc.c b/src/libs/libunwind/sh/Lget_save_loc.c new file mode 100644 index 0000000000..9ea048a907 --- /dev/null +++ b/src/libs/libunwind/sh/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/libs/libunwind/sh/Lglobal.c b/src/libs/libunwind/sh/Lglobal.c new file mode 100644 index 0000000000..6d7b489e14 --- /dev/null +++ b/src/libs/libunwind/sh/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/libs/libunwind/sh/Linit.c b/src/libs/libunwind/sh/Linit.c new file mode 100644 index 0000000000..e9abfdd46a --- /dev/null +++ b/src/libs/libunwind/sh/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/libs/libunwind/sh/Linit_local.c b/src/libs/libunwind/sh/Linit_local.c new file mode 100644 index 0000000000..68a1687e85 --- /dev/null +++ b/src/libs/libunwind/sh/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/libs/libunwind/sh/Linit_remote.c b/src/libs/libunwind/sh/Linit_remote.c new file mode 100644 index 0000000000..58cb04ab7c --- /dev/null +++ b/src/libs/libunwind/sh/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/libs/libunwind/sh/Lis_signal_frame.c b/src/libs/libunwind/sh/Lis_signal_frame.c new file mode 100644 index 0000000000..b9a7c4f51a --- /dev/null +++ b/src/libs/libunwind/sh/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/libs/libunwind/sh/Lregs.c b/src/libs/libunwind/sh/Lregs.c new file mode 100644 index 0000000000..2c9c75cd7d --- /dev/null +++ b/src/libs/libunwind/sh/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/libs/libunwind/sh/Lresume.c b/src/libs/libunwind/sh/Lresume.c new file mode 100644 index 0000000000..41a8cf003d --- /dev/null +++ b/src/libs/libunwind/sh/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/libs/libunwind/sh/Lstep.c b/src/libs/libunwind/sh/Lstep.c new file mode 100644 index 0000000000..c1ac3c7547 --- /dev/null +++ b/src/libs/libunwind/sh/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/libs/libunwind/sh/gen-offsets.c b/src/libs/libunwind/sh/gen-offsets.c new file mode 100644 index 0000000000..16695a6489 --- /dev/null +++ b/src/libs/libunwind/sh/gen-offsets.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +#define UC(N,X) \ + printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) + +#define SC(N,X) \ + printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) + +int +main (void) +{ + printf ( +"/* Linux-specific definitions: */\n\n" + +"/* Define various structure offsets to simplify cross-compilation. */\n\n" + +"/* Offsets for SH Linux \"ucontext_t\": */\n\n"); + + UC ("FLAGS", uc_flags); + UC ("LINK", uc_link); + UC ("STACK", uc_stack); + UC ("MCONTEXT", uc_mcontext); + UC ("SIGMASK", uc_sigmask); + + printf ("\n/* Offsets for SH Linux \"struct sigcontext\": */\n\n"); + + SC ("R0", sc_regs[0]); + SC ("R1", sc_regs[1]); + SC ("R2", sc_regs[2]); + SC ("R3", sc_regs[3]); + SC ("R4", sc_regs[4]); + SC ("R5", sc_regs[5]); + SC ("R6", sc_regs[6]); + SC ("R7", sc_regs[7]); + SC ("R8", sc_regs[8]); + SC ("R9", sc_regs[9]); + SC ("R10", sc_regs[10]); + SC ("R11", sc_regs[11]); + SC ("R12", sc_regs[12]); + SC ("R13", sc_regs[13]); + SC ("R14", sc_regs[14]); + SC ("R15", sc_regs[15]); + + SC ("PC", sc_pc); + SC ("PR", sc_pr); + + return 0; +} diff --git a/src/libs/libunwind/sh/init.h b/src/libs/libunwind/sh/init.h new file mode 100644 index 0000000000..a180258e5a --- /dev/null +++ b/src/libs/libunwind/sh/init.h @@ -0,0 +1,74 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret; + + c->dwarf.loc[UNW_SH_R0] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R0); + c->dwarf.loc[UNW_SH_R1] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R1); + c->dwarf.loc[UNW_SH_R2] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R2); + c->dwarf.loc[UNW_SH_R3] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R3); + c->dwarf.loc[UNW_SH_R4] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R4); + c->dwarf.loc[UNW_SH_R5] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R5); + c->dwarf.loc[UNW_SH_R6] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R6); + c->dwarf.loc[UNW_SH_R7] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R7); + c->dwarf.loc[UNW_SH_R8] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R8); + c->dwarf.loc[UNW_SH_R9] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R9); + c->dwarf.loc[UNW_SH_R10] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R10); + c->dwarf.loc[UNW_SH_R11] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R11); + c->dwarf.loc[UNW_SH_R12] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R12); + c->dwarf.loc[UNW_SH_R13] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R13); + c->dwarf.loc[UNW_SH_R14] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R14); + c->dwarf.loc[UNW_SH_R15] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R15); + c->dwarf.loc[UNW_SH_PC] = DWARF_REG_LOC (&c->dwarf, UNW_SH_PC); + c->dwarf.loc[UNW_SH_PR] = DWARF_REG_LOC (&c->dwarf, UNW_SH_PR); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_SH_PC], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_TDEP_SP], &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = SH_SCF_NONE; + c->sigcontext_addr = 0; + c->sigcontext_sp = 0; + c->sigcontext_pc = 0; + + c->dwarf.args_size = 0; + c->dwarf.ret_addr_column = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/libs/libunwind/sh/is_fpreg.c b/src/libs/libunwind/sh/is_fpreg.c new file mode 100644 index 0000000000..c351f81c48 --- /dev/null +++ b/src/libs/libunwind/sh/is_fpreg.c @@ -0,0 +1,32 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED int +unw_is_fpreg (int regnum) +{ + /* FIXME: Support FP. */ + return 0; +} diff --git a/src/libs/libunwind/sh/offsets.h b/src/libs/libunwind/sh/offsets.h new file mode 100644 index 0000000000..b02d8aee1e --- /dev/null +++ b/src/libs/libunwind/sh/offsets.h @@ -0,0 +1,32 @@ +/* Linux-specific definitions: */ + +/* Define various structure offsets to simplify cross-compilation. */ + +/* Offsets for SH Linux "ucontext_t": */ + +#define LINUX_UC_FLAGS_OFF 0x0 +#define LINUX_UC_LINK_OFF 0x4 +#define LINUX_UC_STACK_OFF 0x8 +#define LINUX_UC_MCONTEXT_OFF 0x14 +#define LINUX_UC_SIGMASK_OFF 0xFC + +/* Offsets for SH Linux "struct sigcontext": */ + +#define LINUX_SC_R0_OFF 0x4 +#define LINUX_SC_R1_OFF 0x8 +#define LINUX_SC_R2_OFF 0xC +#define LINUX_SC_R3_OFF 0x10 +#define LINUX_SC_R4_OFF 0x14 +#define LINUX_SC_R5_OFF 0x18 +#define LINUX_SC_R6_OFF 0x1C +#define LINUX_SC_R7_OFF 0x20 +#define LINUX_SC_R8_OFF 0x24 +#define LINUX_SC_R9_OFF 0x28 +#define LINUX_SC_R10_OFF 0x2C +#define LINUX_SC_R11_OFF 0x30 +#define LINUX_SC_R12_OFF 0x34 +#define LINUX_SC_R13_OFF 0x38 +#define LINUX_SC_R14_OFF 0x3C +#define LINUX_SC_R15_OFF 0x40 +#define LINUX_SC_PC_OFF 0x44 +#define LINUX_SC_PR_OFF 0x48 diff --git a/src/libs/libunwind/sh/regname.c b/src/libs/libunwind/sh/regname.c new file mode 100644 index 0000000000..dcab240536 --- /dev/null +++ b/src/libs/libunwind/sh/regname.c @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *const regname[] = + { + [UNW_SH_R0] = "r0", + [UNW_SH_R1] = "r1", + [UNW_SH_R2] = "r2", + [UNW_SH_R3] = "r3", + [UNW_SH_R4] = "r4", + [UNW_SH_R5] = "r5", + [UNW_SH_R6] = "r6", + [UNW_SH_R7] = "r7", + [UNW_SH_R8] = "r8", + [UNW_SH_R9] = "r9", + [UNW_SH_R10] = "r10", + [UNW_SH_R11] = "r11", + [UNW_SH_R12] = "r12", + [UNW_SH_R13] = "r13", + [UNW_SH_R14] = "r14", + [UNW_SH_R15] = "r15", + [UNW_SH_PC] = "pc", + [UNW_SH_PR] = "pr", + }; + +PROTECTED const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname) && regname[reg] != NULL) + return regname[reg]; + else + return "???"; +} diff --git a/src/libs/libunwind/sh/siglongjmp.S b/src/libs/libunwind/sh/siglongjmp.S new file mode 100644 index 0000000000..9ca53d124b --- /dev/null +++ b/src/libs/libunwind/sh/siglongjmp.S @@ -0,0 +1,8 @@ + /* Dummy implementation for now. */ + + .globl _UI_siglongjmp_cont + .globl _UI_longjmp_cont + +_UI_siglongjmp_cont: +_UI_longjmp_cont: + rts diff --git a/src/libs/libunwind/sh/unwind_i.h b/src/libs/libunwind/sh/unwind_i.h new file mode 100644 index 0000000000..3066d84631 --- /dev/null +++ b/src/libs/libunwind/sh/unwind_i.h @@ -0,0 +1,40 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include + +#include "libunwind_i.h" + +#define sh_lock UNW_OBJ(lock) +#define sh_local_resume UNW_OBJ(local_resume) +#define sh_local_addr_space_init UNW_OBJ(local_addr_space_init) + +extern void sh_local_addr_space_init (void); +extern int sh_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); + +#endif /* unwind_i_h */ diff --git a/src/libs/libunwind/tilegx/Gcreate_addr_space.c b/src/libs/libunwind/tilegx/Gcreate_addr_space.c new file mode 100644 index 0000000000..a2821a3d31 --- /dev/null +++ b/src/libs/libunwind/tilegx/Gcreate_addr_space.c @@ -0,0 +1,65 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +PROTECTED unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as = malloc (sizeof (*as)); + + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + /* + * Tilegx supports only big or little-endian, not weird stuff like + * PDP_ENDIAN. + */ + if (byte_order != 0 + && byte_order != __LITTLE_ENDIAN + && byte_order != __BIG_ENDIAN) + return NULL; + + if (byte_order == 0) + /* use host default: */ + as->big_endian = (__BYTE_ORDER == __BIG_ENDIAN); + else + as->big_endian = (byte_order == __BIG_ENDIAN); + + as->abi = UNW_TILEGX_ABI_N64; + as->addr_size = 8; + + return as; +#endif +} diff --git a/src/libs/libunwind/tilegx/Gget_proc_info.c b/src/libs/libunwind/tilegx/Gget_proc_info.c new file mode 100644 index 0000000000..f82700dd3a --- /dev/null +++ b/src/libs/libunwind/tilegx/Gget_proc_info.c @@ -0,0 +1,48 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + ret = dwarf_make_proc_info (&c->dwarf); + + if (ret < 0) + { + /* On Tilegx, some routines i.e. _start() etc has no dwarf info. + Just simply mark the end of the frames. */ + memset (pi, 0, sizeof (*pi)); + pi->start_ip = c->dwarf.ip; + pi->end_ip = c->dwarf.ip + 1; + return 0; + } + + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/libs/libunwind/tilegx/Gget_save_loc.c b/src/libs/libunwind/tilegx/Gget_save_loc.c new file mode 100644 index 0000000000..ec474e1885 --- /dev/null +++ b/src/libs/libunwind/tilegx/Gget_save_loc.c @@ -0,0 +1,62 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + + if (reg <= UNW_TILEGX_R55) + loc = c->dwarf.loc[reg - UNW_TILEGX_R0]; + else + printf("\nInvalid register!"); + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/libs/libunwind/tilegx/Gglobal.c b/src/libs/libunwind/tilegx/Gglobal.c new file mode 100644 index 0000000000..e18f50a50f --- /dev/null +++ b/src/libs/libunwind/tilegx/Gglobal.c @@ -0,0 +1,64 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +__attribute__((weak)) +pthread_mutex_t tilegx_lock = PTHREAD_MUTEX_INITIALIZER; +HIDDEN int tdep_init_done; + +HIDDEN const uint8_t dwarf_to_unw_regnum_map[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55 + }; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&tilegx_lock, saved_mask); + + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + tilegx_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + + out: + lock_release (&tilegx_lock, saved_mask); +} diff --git a/src/libs/libunwind/tilegx/Ginit.c b/src/libs/libunwind/tilegx/Ginit.c new file mode 100644 index 0000000000..df3ffcaa64 --- /dev/null +++ b/src/libs/libunwind/tilegx/Ginit.c @@ -0,0 +1,167 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +PROTECTED unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space; + +/* Return the address of the 64-bit slot in UC for REG (even for o32, + where registers are 32-bit, the slots are still 64-bit). */ + +static inline void * +uc_addr (ucontext_t *uc, int reg) +{ + if (reg >= UNW_TILEGX_R0 && reg < UNW_TILEGX_R0 + 56) + return &uc->uc_mcontext.gregs[reg - UNW_TILEGX_R0]; + else if (reg == UNW_TILEGX_PC) + return &uc->uc_mcontext.pc; + else + return NULL; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + char *addr = uc_addr (uc, reg); + return addr; +} + +# endif /* UNW_LOCAL_ONLY */ + +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ + *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list; + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if ((long long)addr & (sizeof(unw_word_t) - 1)) + return 0; + + if (write) + { + Debug (16, "mem[%llx] <- %llx\n", (long long) addr, (long long) *val); + *(unw_word_t *) (intptr_t) addr = *val; + } + else + { + *val = *(unw_word_t *) (intptr_t) addr; + Debug (16, "mem[%llx] -> %llx\n", (long long) addr, (long long) *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = arg; + + if (unw_is_fpreg (reg)) + goto badreg; + + Debug (16, "reg = %s\n", unw_regname (reg)); + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) (intptr_t) addr = (tilegx_reg_t) *val; + Debug (12, "%s <- %llx\n", unw_regname (reg), (long long) *val); + } + else + { + *val = (tilegx_reg_t) *(unw_word_t *) (intptr_t) addr; + Debug (12, "%s -> %llx\n", unw_regname (reg), (long long) *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return elf_w (get_proc_name) (as, getpid (), ip, buf, buf_len, offp); +} + +__attribute__((weak)) void +tilegx_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); + + local_addr_space.abi = UNW_TILEGX_ABI_N64; + local_addr_space.addr_size = sizeof (void *); + local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = NULL; + local_addr_space.acc.resume = tilegx_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/tilegx/Ginit_local.c b/src/libs/libunwind/tilegx/Ginit_local.c new file mode 100644 index 0000000000..f75c98f439 --- /dev/null +++ b/src/libs/libunwind/tilegx/Ginit_local.c @@ -0,0 +1,57 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + memset(c, 0, sizeof(unw_cursor_t)); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + + c->dwarf.as_arg = uc; + return common_init (c, 1); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/tilegx/Ginit_remote.c b/src/libs/libunwind/tilegx/Ginit_remote.c new file mode 100644 index 0000000000..c55410085d --- /dev/null +++ b/src/libs/libunwind/tilegx/Ginit_remote.c @@ -0,0 +1,47 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +PROTECTED int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/libs/libunwind/tilegx/Gis_signal_frame.c b/src/libs/libunwind/tilegx/Gis_signal_frame.c new file mode 100644 index 0000000000..96bd34adde --- /dev/null +++ b/src/libs/libunwind/tilegx/Gis_signal_frame.c @@ -0,0 +1,115 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include +#include "offsets.h" + +#ifdef __linux__ +#include +#include +#else +# error "Only support Linux!" +#endif + +#define MOVELI_R10_RT_SIGRETURN \ + ( 0x000007e051483000ULL | \ + ((unsigned long)__NR_rt_sigreturn << 43) | \ + ((unsigned long)TREG_SYSCALL_NR << 31) ) +#define SWINT1 0x286b180051485000ULL + +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor*) cursor; + unw_word_t w0, w1, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors (as); + arg = c->dwarf.as_arg; + + ip = c->dwarf.ip; + + if (!ip || !a->access_mem || (ip & (sizeof(unw_word_t) - 1))) + return 0; + + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) + return ret; + + if ((ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0) + return ret; + + /* Return 1 if the IP points to a RT sigreturn sequence. */ + if (w0 == MOVELI_R10_RT_SIGRETURN && + w1 == SWINT1) + { + return 1; + } + return 0; +} + + +PROTECTED int +unw_handle_signal_frame (unw_cursor_t *cursor) +{ + int i; + struct cursor *c = (struct cursor *) cursor; + unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; + struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); + int ret; + + if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) + return -UNW_EUNSPEC; + + /* Save the SP and PC to be able to return execution at this point + later in time (unw_resume). */ + c->sigcontext_sp = c->dwarf.cfa; + c->sigcontext_pc = c->dwarf.ip; + + c->sigcontext_addr = sp_addr + sizeof (siginfo_t) + + C_ABI_SAVE_AREA_SIZE; + sc_addr = c->sigcontext_addr + LINUX_UC_MCONTEXT_OFF; + + /* Update the dwarf cursor. + Set the location of the registers to the corresponding addresses of the + uc_mcontext / sigcontext structure contents. */ + +#define SC_REG_OFFSET(X) (8 * X) + + for (i = UNW_TILEGX_R0; i <= UNW_TILEGX_R55; i++) + { + c->dwarf.loc[i] = DWARF_LOC (sc_addr + SC_REG_OFFSET(i), 0); + } + + /* Set SP/CFA and PC/IP. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_TILEGX_R54], &c->dwarf.cfa); + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_TILEGX_R55], &c->dwarf.ip); + + return 1; +} diff --git a/src/libs/libunwind/tilegx/Gregs.c b/src/libs/libunwind/tilegx/Gregs.c new file mode 100644 index 0000000000..53e7bf4ce8 --- /dev/null +++ b/src/libs/libunwind/tilegx/Gregs.c @@ -0,0 +1,66 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + + if (reg == UNW_TILEGX_R54 && !write) + { + reg = UNW_TILEGX_CFA; + } + + if (reg <= UNW_TILEGX_R55) + loc = c->dwarf.loc[reg - UNW_TILEGX_R0]; + else if (reg == UNW_TILEGX_CFA) + { + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + } + else + { + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} diff --git a/src/libs/libunwind/tilegx/Gresume.c b/src/libs/libunwind/tilegx/Gresume.c new file mode 100644 index 0000000000..f532fd852a --- /dev/null +++ b/src/libs/libunwind/tilegx/Gresume.c @@ -0,0 +1,94 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + +#include "unwind_i.h" +#include "offsets.h" +#include + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +tilegx_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + int i; + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = c->dwarf.as_arg; + + Debug (1, "(cursor=%p\n", c); + + return setcontext(uc); +} + +#endif /* !UNW_REMOTE_ONLY */ + +static inline void +establish_machine_state (struct cursor *c) +{ + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + + if (unw_is_fpreg (reg)) + { + Debug (1, "no fp!"); + abort (); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + as->acc.access_reg (as, reg, &val, 1, arg); + } + } +} + +PROTECTED int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + + Debug (1, "(cursor=%p) ip=0x%lx\n", c, c->dwarf.ip); + + if (!c->dwarf.ip) + { + /* This can happen easily when the frame-chain gets truncated + due to bad or missing unwind-info. */ + Debug (1, "refusing to resume execution at address 0\n"); + return -UNW_EINVAL; + } + + establish_machine_state (c); + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/libs/libunwind/tilegx/Gstep.c b/src/libs/libunwind/tilegx/Gstep.c new file mode 100644 index 0000000000..0d8f8af791 --- /dev/null +++ b/src/libs/libunwind/tilegx/Gstep.c @@ -0,0 +1,53 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +PROTECTED int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p, ip=0x%016lx, sp=0x%016lx)\n", + c, c->dwarf.ip, c->dwarf.cfa); + + /* Special handling the singal frame. */ + if (unw_is_signal_frame (cursor)) + return unw_handle_signal_frame (cursor); + + /* Try DWARF-based unwinding... */ + ret = dwarf_step (&c->dwarf); + + if (unlikely (ret == -UNW_ESTOPUNWIND)) + return ret; + + /* Dwarf unwinding didn't work, stop. */ + if (unlikely (ret < 0)) + return 0; + + return (c->dwarf.ip == 0) ? 0 : 1; +} diff --git a/src/libs/libunwind/tilegx/Lcreate_addr_space.c b/src/libs/libunwind/tilegx/Lcreate_addr_space.c new file mode 100644 index 0000000000..0f2dc6be90 --- /dev/null +++ b/src/libs/libunwind/tilegx/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/libs/libunwind/tilegx/Lget_proc_info.c b/src/libs/libunwind/tilegx/Lget_proc_info.c new file mode 100644 index 0000000000..69028b019f --- /dev/null +++ b/src/libs/libunwind/tilegx/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/libs/libunwind/tilegx/Lget_save_loc.c b/src/libs/libunwind/tilegx/Lget_save_loc.c new file mode 100644 index 0000000000..9ea048a907 --- /dev/null +++ b/src/libs/libunwind/tilegx/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/libs/libunwind/tilegx/Lglobal.c b/src/libs/libunwind/tilegx/Lglobal.c new file mode 100644 index 0000000000..6d7b489e14 --- /dev/null +++ b/src/libs/libunwind/tilegx/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/libs/libunwind/tilegx/Linit.c b/src/libs/libunwind/tilegx/Linit.c new file mode 100644 index 0000000000..e9abfdd46a --- /dev/null +++ b/src/libs/libunwind/tilegx/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/libs/libunwind/tilegx/Linit_local.c b/src/libs/libunwind/tilegx/Linit_local.c new file mode 100644 index 0000000000..68a1687e85 --- /dev/null +++ b/src/libs/libunwind/tilegx/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/libs/libunwind/tilegx/Linit_remote.c b/src/libs/libunwind/tilegx/Linit_remote.c new file mode 100644 index 0000000000..58cb04ab7c --- /dev/null +++ b/src/libs/libunwind/tilegx/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/libs/libunwind/tilegx/Lis_signal_frame.c b/src/libs/libunwind/tilegx/Lis_signal_frame.c new file mode 100644 index 0000000000..b9a7c4f51a --- /dev/null +++ b/src/libs/libunwind/tilegx/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/libs/libunwind/tilegx/Lregs.c b/src/libs/libunwind/tilegx/Lregs.c new file mode 100644 index 0000000000..2c9c75cd7d --- /dev/null +++ b/src/libs/libunwind/tilegx/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/libs/libunwind/tilegx/Lresume.c b/src/libs/libunwind/tilegx/Lresume.c new file mode 100644 index 0000000000..41a8cf003d --- /dev/null +++ b/src/libs/libunwind/tilegx/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/libs/libunwind/tilegx/Lstep.c b/src/libs/libunwind/tilegx/Lstep.c new file mode 100644 index 0000000000..c1ac3c7547 --- /dev/null +++ b/src/libs/libunwind/tilegx/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/libs/libunwind/tilegx/elfxx.c b/src/libs/libunwind/tilegx/elfxx.c new file mode 100644 index 0000000000..07d3d12b94 --- /dev/null +++ b/src/libs/libunwind/tilegx/elfxx.c @@ -0,0 +1,27 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +#include "../src/elfxx.c" diff --git a/src/libs/libunwind/tilegx/gen-offsets.c b/src/libs/libunwind/tilegx/gen-offsets.c new file mode 100644 index 0000000000..8704bb215e --- /dev/null +++ b/src/libs/libunwind/tilegx/gen-offsets.c @@ -0,0 +1,30 @@ +#include +#include +#include + +#define UC(N,X) \ + printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) + +#define SC(N,X) \ + printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) + +int +main (void) +{ + printf ( +"/* Linux-specific definitions: */\n\n" + +"/* Define various structure offsets to simplify cross-compilation. */\n\n" + +"/* Offsets for TILEGX Linux \"ucontext_t\": */\n\n"); + + UC ("FLAGS", uc_flags); + UC ("LINK", uc_link); + UC ("STACK", uc_stack); + UC ("MCONTEXT", uc_mcontext); + UC ("SIGMASK", uc_sigmask); + + UC ("MCONTEXT_GREGS", uc_mcontext.gregs); + + return 0; +} diff --git a/src/libs/libunwind/tilegx/getcontext.S b/src/libs/libunwind/tilegx/getcontext.S new file mode 100644 index 0000000000..fbc8654bc7 --- /dev/null +++ b/src/libs/libunwind/tilegx/getcontext.S @@ -0,0 +1,36 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" +#include + + .text + # define REG(X) LINUX_UC_MCONTEXT_GREGS + 8 * (X) + .global _Utilegx_getcontext + .type _Utilegx_getcontext, %function + # This is a stub version of getcontext() for TILEGX. +_Utilegx_getcontext: + + diff --git a/src/libs/libunwind/tilegx/init.h b/src/libs/libunwind/tilegx/init.h new file mode 100644 index 0000000000..e75e590b12 --- /dev/null +++ b/src/libs/libunwind/tilegx/init.h @@ -0,0 +1,64 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret, i; + + for (i = 0; i < 56; i++) + c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R0 + i); + for (i = 56; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + if (use_prev_instr == 0) + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_PC), + &c->dwarf.ip); + else + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R55), + &c->dwarf.ip); + + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R54), + &c->dwarf.cfa); + + if (ret < 0) + return ret; + + c->dwarf.args_size = 0; + c->dwarf.ret_addr_column = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/libs/libunwind/tilegx/is_fpreg.c b/src/libs/libunwind/tilegx/is_fpreg.c new file mode 100644 index 0000000000..118e055ef2 --- /dev/null +++ b/src/libs/libunwind/tilegx/is_fpreg.c @@ -0,0 +1,33 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +/* TILEGX has no FP. */ + +PROTECTED int +unw_is_fpreg (int regnum) +{ + return 0; +} diff --git a/src/libs/libunwind/tilegx/offsets.h b/src/libs/libunwind/tilegx/offsets.h new file mode 100644 index 0000000000..6d30f1edcf --- /dev/null +++ b/src/libs/libunwind/tilegx/offsets.h @@ -0,0 +1,12 @@ +/* Linux-specific definitions: */ + +/* Define various structure offsets to simplify cross-compilation. */ + +/* Offsets for TILEGX Linux "ucontext_t": */ + +#define LINUX_UC_FLAGS_OFF 0x0 +#define LINUX_UC_LINK_OFF 0x8 +#define LINUX_UC_STACK_OFF 0x10 +#define LINUX_UC_MCONTEXT_OFF 0x28 +#define LINUX_UC_SIGMASK_OFF 0x228 +#define LINUX_UC_MCONTEXT_GREGS 0x28 diff --git a/src/libs/libunwind/tilegx/regname.c b/src/libs/libunwind/tilegx/regname.c new file mode 100644 index 0000000000..fd73804661 --- /dev/null +++ b/src/libs/libunwind/tilegx/regname.c @@ -0,0 +1,55 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + /* 0. */ + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + /* 8. */ + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + /* 16. */ + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + /* 24. */ + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", + /* 32. */ + "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", + /* 40. */ + "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", + /* 48. */ + "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", + /* pc, cfa */ + "pc", "cfa" + }; + +PROTECTED const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/libs/libunwind/tilegx/siglongjmp.S b/src/libs/libunwind/tilegx/siglongjmp.S new file mode 100644 index 0000000000..bccb1c7785 --- /dev/null +++ b/src/libs/libunwind/tilegx/siglongjmp.S @@ -0,0 +1,7 @@ + /* Dummy implementation for now. */ + .globl _UI_siglongjmp_cont + .globl _UI_longjmp_cont + +_UI_siglongjmp_cont: +_UI_longjmp_cont: + jrp lr diff --git a/src/libs/libunwind/tilegx/unwind_i.h b/src/libs/libunwind/tilegx/unwind_i.h new file mode 100644 index 0000000000..aac7be3888 --- /dev/null +++ b/src/libs/libunwind/tilegx/unwind_i.h @@ -0,0 +1,44 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include +#include + +#include + +#include "libunwind_i.h" + +#define tilegx_local_resume UNW_OBJ(local_resume) +#define tilegx_local_addr_space_init UNW_OBJ(local_addr_space_init) + +extern int tilegx_local_resume (unw_addr_space_t as, + unw_cursor_t *cursor, + void *arg); + +extern void tilegx_local_addr_space_init (void); + +#endif /* unwind_i_h */ diff --git a/src/libs/libunwind/unwind/Backtrace.c b/src/libs/libunwind/unwind/Backtrace.c new file mode 100644 index 0000000000..50f1fb613a --- /dev/null +++ b/src/libs/libunwind/unwind/Backtrace.c @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED _Unwind_Reason_Code +_Unwind_Backtrace (_Unwind_Trace_Fn trace, void *trace_parameter) +{ + struct _Unwind_Context context; + unw_context_t uc; + int ret; + + if (_Unwind_InitContext (&context, &uc) < 0) + return _URC_FATAL_PHASE1_ERROR; + + /* Phase 1 (search phase) */ + + while (1) + { + if ((ret = unw_step (&context.cursor)) <= 0) + { + if (ret == 0) + return _URC_END_OF_STACK; + else + return _URC_FATAL_PHASE1_ERROR; + } + + if ((*trace) (&context, trace_parameter) != _URC_NO_REASON) + return _URC_FATAL_PHASE1_ERROR; + } +} + +_Unwind_Reason_Code __libunwind_Unwind_Backtrace (_Unwind_Trace_Fn, void *) + ALIAS (_Unwind_Backtrace); diff --git a/src/libs/libunwind/unwind/DeleteException.c b/src/libs/libunwind/unwind/DeleteException.c new file mode 100644 index 0000000000..79be65e456 --- /dev/null +++ b/src/libs/libunwind/unwind/DeleteException.c @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED void +_Unwind_DeleteException (struct _Unwind_Exception *exception_object) +{ + _Unwind_Exception_Cleanup_Fn cleanup = exception_object->exception_cleanup; + + if (cleanup) + (*cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exception_object); +} + +void __libunwind_Unwind_DeleteException (struct _Unwind_Exception *) + ALIAS (_Unwind_DeleteException); diff --git a/src/libs/libunwind/unwind/FindEnclosingFunction.c b/src/libs/libunwind/unwind/FindEnclosingFunction.c new file mode 100644 index 0000000000..b9873da5f6 --- /dev/null +++ b/src/libs/libunwind/unwind/FindEnclosingFunction.c @@ -0,0 +1,42 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED void * +_Unwind_FindEnclosingFunction (void *ip) +{ + unw_proc_info_t pi; + + if (unw_get_proc_info_by_ip (unw_local_addr_space, + (unw_word_t) (uintptr_t) ip, &pi, 0) + < 0) + return NULL; + + return (void *) (uintptr_t) pi.start_ip; +} + +void *__libunwind_Unwind_FindEnclosingFunction (void *) + ALIAS (_Unwind_FindEnclosingFunction); diff --git a/src/libs/libunwind/unwind/ForcedUnwind.c b/src/libs/libunwind/unwind/ForcedUnwind.c new file mode 100644 index 0000000000..da8a60e226 --- /dev/null +++ b/src/libs/libunwind/unwind/ForcedUnwind.c @@ -0,0 +1,52 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED _Unwind_Reason_Code +_Unwind_ForcedUnwind (struct _Unwind_Exception *exception_object, + _Unwind_Stop_Fn stop, void *stop_parameter) +{ + struct _Unwind_Context context; + unw_context_t uc; + + /* We check "stop" here to tell the compiler's inliner that + exception_object->private_1 isn't NULL when calling + _Unwind_Phase2(). */ + if (!stop) + return _URC_FATAL_PHASE2_ERROR; + + if (_Unwind_InitContext (&context, &uc) < 0) + return _URC_FATAL_PHASE2_ERROR; + + exception_object->private_1 = (unsigned long) stop; + exception_object->private_2 = (unsigned long) stop_parameter; + + return _Unwind_Phase2 (exception_object, &context); +} + +_Unwind_Reason_Code __libunwind_Unwind_ForcedUnwind (struct _Unwind_Exception*, + _Unwind_Stop_Fn, void *) + ALIAS (_Unwind_ForcedUnwind); diff --git a/src/libs/libunwind/unwind/GetBSP.c b/src/libs/libunwind/unwind/GetBSP.c new file mode 100644 index 0000000000..253fde05f4 --- /dev/null +++ b/src/libs/libunwind/unwind/GetBSP.c @@ -0,0 +1,42 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED unsigned long +_Unwind_GetBSP (struct _Unwind_Context *context) +{ +#ifdef UNW_TARGET_IA64 + unw_word_t val; + + unw_get_reg (&context->cursor, UNW_IA64_BSP, &val); + return val; +#else + return 0; +#endif +} + +unsigned long __libunwind_Unwind_GetBSP (struct _Unwind_Context *) + ALIAS (_Unwind_GetBSP); diff --git a/src/libs/libunwind/unwind/GetCFA.c b/src/libs/libunwind/unwind/GetCFA.c new file mode 100644 index 0000000000..7975b1d3e6 --- /dev/null +++ b/src/libs/libunwind/unwind/GetCFA.c @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED unsigned long +_Unwind_GetCFA (struct _Unwind_Context *context) +{ + unw_word_t val; + + unw_get_reg (&context->cursor, UNW_REG_SP, &val); + return val; +} + +unsigned long __libunwind_Unwind_GetCFA (struct _Unwind_Context *) + ALIAS (_Unwind_GetCFA); diff --git a/src/libs/libunwind/unwind/GetDataRelBase.c b/src/libs/libunwind/unwind/GetDataRelBase.c new file mode 100644 index 0000000000..9bdd4cb0c1 --- /dev/null +++ b/src/libs/libunwind/unwind/GetDataRelBase.c @@ -0,0 +1,39 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED unsigned long +_Unwind_GetDataRelBase (struct _Unwind_Context *context) +{ + unw_proc_info_t pi; + + pi.gp = 0; + unw_get_proc_info (&context->cursor, &pi); + return pi.gp; +} + +unsigned long __libunwind_Unwind_GetDataRelBase (struct _Unwind_Context *) + ALIAS (_Unwind_GetDataRelBase); diff --git a/src/libs/libunwind/unwind/GetGR.c b/src/libs/libunwind/unwind/GetGR.c new file mode 100644 index 0000000000..b7ab05c4b6 --- /dev/null +++ b/src/libs/libunwind/unwind/GetGR.c @@ -0,0 +1,43 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED unsigned long +_Unwind_GetGR (struct _Unwind_Context *context, int index) +{ + unw_word_t val; + + if (index == UNW_REG_SP && context->end_of_stack) + /* _Unwind_ForcedUnwind() requires us to return a NULL + stack-pointer after reaching the end of the stack. */ + return 0; + + unw_get_reg (&context->cursor, index, &val); + return val; +} + +unsigned long __libunwind_Unwind_GetGR (struct _Unwind_Context *, int) + ALIAS (_Unwind_GetGR); diff --git a/src/libs/libunwind/unwind/GetIP.c b/src/libs/libunwind/unwind/GetIP.c new file mode 100644 index 0000000000..e93853d080 --- /dev/null +++ b/src/libs/libunwind/unwind/GetIP.c @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED unsigned long +_Unwind_GetIP (struct _Unwind_Context *context) +{ + unw_word_t val; + + unw_get_reg (&context->cursor, UNW_REG_IP, &val); + return val; +} + +unsigned long __libunwind_Unwind_GetIP (struct _Unwind_Context *) + ALIAS (_Unwind_GetIP); diff --git a/src/libs/libunwind/unwind/GetIPInfo.c b/src/libs/libunwind/unwind/GetIPInfo.c new file mode 100644 index 0000000000..9105396a28 --- /dev/null +++ b/src/libs/libunwind/unwind/GetIPInfo.c @@ -0,0 +1,42 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2009 Red Hat + Contributed by Jan Kratochvil + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +/* gcc/unwind-dw2.c: Retrieve the return address and flag whether that IP is + before or after first not yet fully executed instruction. */ + +PROTECTED unsigned long +_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) +{ + unw_word_t val; + + unw_get_reg (&context->cursor, UNW_REG_IP, &val); + *ip_before_insn = unw_is_signal_frame (&context->cursor); + return val; +} + +unsigned long __libunwind_Unwind_GetIPInfo (struct _Unwind_Context *, int *) + ALIAS (_Unwind_GetIPInfo); diff --git a/src/libs/libunwind/unwind/GetLanguageSpecificData.c b/src/libs/libunwind/unwind/GetLanguageSpecificData.c new file mode 100644 index 0000000000..df52c92903 --- /dev/null +++ b/src/libs/libunwind/unwind/GetLanguageSpecificData.c @@ -0,0 +1,40 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED unsigned long +_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context) +{ + unw_proc_info_t pi; + + pi.lsda = 0; + unw_get_proc_info (&context->cursor, &pi); + return pi.lsda; +} + +unsigned long +__libunwind_Unwind_GetLanguageSpecificData (struct _Unwind_Context *) + ALIAS (_Unwind_GetLanguageSpecificData); diff --git a/src/libs/libunwind/unwind/GetRegionStart.c b/src/libs/libunwind/unwind/GetRegionStart.c new file mode 100644 index 0000000000..f0da344985 --- /dev/null +++ b/src/libs/libunwind/unwind/GetRegionStart.c @@ -0,0 +1,39 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED unsigned long +_Unwind_GetRegionStart (struct _Unwind_Context *context) +{ + unw_proc_info_t pi; + + pi.start_ip = 0; + unw_get_proc_info (&context->cursor, &pi); + return pi.start_ip; +} + +unsigned long __libunwind_Unwind_GetRegionStart (struct _Unwind_Context *) + ALIAS (_Unwind_GetRegionStart); diff --git a/src/libs/libunwind/unwind/GetTextRelBase.c b/src/libs/libunwind/unwind/GetTextRelBase.c new file mode 100644 index 0000000000..d0826e7f2a --- /dev/null +++ b/src/libs/libunwind/unwind/GetTextRelBase.c @@ -0,0 +1,35 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED unsigned long +_Unwind_GetTextRelBase (struct _Unwind_Context *context) +{ + return 0; +} + +unsigned long __libunwind_Unwind_GetTextRelBase (struct _Unwind_Context *) + ALIAS (_Unwind_GetTextRelBase); diff --git a/src/libs/libunwind/unwind/RaiseException.c b/src/libs/libunwind/unwind/RaiseException.c new file mode 100644 index 0000000000..cdf134a942 --- /dev/null +++ b/src/libs/libunwind/unwind/RaiseException.c @@ -0,0 +1,103 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED _Unwind_Reason_Code +_Unwind_RaiseException (struct _Unwind_Exception *exception_object) +{ + uint64_t exception_class = exception_object->exception_class; + _Unwind_Personality_Fn personality; + struct _Unwind_Context context; + _Unwind_Reason_Code reason; + unw_proc_info_t pi; + unw_context_t uc; + unw_word_t ip; + int ret; + + Debug (1, "(exception_object=%p)\n", exception_object); + + if (_Unwind_InitContext (&context, &uc) < 0) + return _URC_FATAL_PHASE1_ERROR; + + /* Phase 1 (search phase) */ + + while (1) + { + if ((ret = unw_step (&context.cursor)) <= 0) + { + if (ret == 0) + { + Debug (1, "no handler found\n"); + return _URC_END_OF_STACK; + } + else + return _URC_FATAL_PHASE1_ERROR; + } + + if (unw_get_proc_info (&context.cursor, &pi) < 0) + return _URC_FATAL_PHASE1_ERROR; + + personality = (_Unwind_Personality_Fn) (uintptr_t) pi.handler; + if (personality) + { + reason = (*personality) (_U_VERSION, _UA_SEARCH_PHASE, + exception_class, exception_object, + &context); + if (reason != _URC_CONTINUE_UNWIND) + { + if (reason == _URC_HANDLER_FOUND) + break; + else + { + Debug (1, "personality returned %d\n", reason); + return _URC_FATAL_PHASE1_ERROR; + } + } + } + } + + /* Exceptions are associated with IP-ranges. If a given exception + is handled at a particular IP, it will _always_ be handled at + that IP. If this weren't true, we'd have to track the tuple + (IP,SP,BSP) to uniquely identify the stack frame that's handling + the exception. */ + if (unw_get_reg (&context.cursor, UNW_REG_IP, &ip) < 0) + return _URC_FATAL_PHASE1_ERROR; + exception_object->private_1 = 0; /* clear "stop" pointer */ + exception_object->private_2 = ip; /* save frame marker */ + + Debug (1, "found handler for IP=%lx; entering cleanup phase\n", (long) ip); + + /* Reset the cursor to the first frame: */ + if (unw_init_local (&context.cursor, &uc) < 0) + return _URC_FATAL_PHASE1_ERROR; + + return _Unwind_Phase2 (exception_object, &context); +} + +_Unwind_Reason_Code +__libunwind_Unwind_RaiseException (struct _Unwind_Exception *) + ALIAS (_Unwind_RaiseException); diff --git a/src/libs/libunwind/unwind/Resume.c b/src/libs/libunwind/unwind/Resume.c new file mode 100644 index 0000000000..dd0a44bc86 --- /dev/null +++ b/src/libs/libunwind/unwind/Resume.c @@ -0,0 +1,42 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED void +_Unwind_Resume (struct _Unwind_Exception *exception_object) +{ + struct _Unwind_Context context; + unw_context_t uc; + + if (_Unwind_InitContext (&context, &uc) < 0) + abort (); + + _Unwind_Phase2 (exception_object, &context); + abort (); +} + +void __libunwind_Unwind_Resume (struct _Unwind_Exception *) + ALIAS (_Unwind_Resume); diff --git a/src/libs/libunwind/unwind/Resume_or_Rethrow.c b/src/libs/libunwind/unwind/Resume_or_Rethrow.c new file mode 100644 index 0000000000..d60e038321 --- /dev/null +++ b/src/libs/libunwind/unwind/Resume_or_Rethrow.c @@ -0,0 +1,47 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED _Unwind_Reason_Code +_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exception_object) +{ + struct _Unwind_Context context; + unw_context_t uc; + + if (exception_object->private_1) + { + if (_Unwind_InitContext (&context, &uc) < 0) + return _URC_FATAL_PHASE2_ERROR; + + return _Unwind_Phase2 (exception_object, &context); + } + else + return _Unwind_RaiseException (exception_object); +} + +_Unwind_Reason_Code +__libunwind_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *) + ALIAS (_Unwind_Resume_or_Rethrow); diff --git a/src/libs/libunwind/unwind/SetGR.c b/src/libs/libunwind/unwind/SetGR.c new file mode 100644 index 0000000000..143b354925 --- /dev/null +++ b/src/libs/libunwind/unwind/SetGR.c @@ -0,0 +1,47 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" +#ifdef UNW_TARGET_X86 +#include "dwarf_i.h" +#endif + +PROTECTED void +_Unwind_SetGR (struct _Unwind_Context *context, int index, + unsigned long new_value) +{ +#ifdef UNW_TARGET_X86 + index = dwarf_to_unw_regnum(index); +#endif + unw_set_reg (&context->cursor, index, new_value); +#ifdef UNW_TARGET_IA64 + if (index >= UNW_IA64_GR && index <= UNW_IA64_GR + 127) + /* Clear the NaT bit. */ + unw_set_reg (&context->cursor, UNW_IA64_NAT + (index - UNW_IA64_GR), 0); +#endif +} + +void __libunwind_Unwind_SetGR (struct _Unwind_Context *, int, unsigned long) + ALIAS (_Unwind_SetGR); diff --git a/src/libs/libunwind/unwind/SetIP.c b/src/libs/libunwind/unwind/SetIP.c new file mode 100644 index 0000000000..c55ab9718e --- /dev/null +++ b/src/libs/libunwind/unwind/SetIP.c @@ -0,0 +1,35 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +PROTECTED void +_Unwind_SetIP (struct _Unwind_Context *context, unsigned long new_value) +{ + unw_set_reg (&context->cursor, UNW_REG_IP, new_value); +} + +void __libunwind_Unwind_SetIP (struct _Unwind_Context *, unsigned long) + ALIAS (_Unwind_SetIP); diff --git a/src/libs/libunwind/unwind/unwind-internal.h b/src/libs/libunwind/unwind/unwind-internal.h new file mode 100644 index 0000000000..c68fc3c5ed --- /dev/null +++ b/src/libs/libunwind/unwind/unwind-internal.h @@ -0,0 +1,140 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_internal_h +#define unwind_internal_h + +#define UNW_LOCAL_ONLY + +#include +#include +#include + +#include "libunwind_i.h" + +/* The version of the _Unwind_*() interface implemented by this code. */ +#define _U_VERSION 1 + +typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn) + (int, _Unwind_Action, uint64_t, struct _Unwind_Exception *, + struct _Unwind_Context *); + +struct _Unwind_Context { + unw_cursor_t cursor; + int end_of_stack; /* set to 1 if the end of stack was reached */ +}; + +/* This must be a macro because unw_getcontext() must be invoked from + the callee, even if optimization (and hence inlining) is turned + off. The macro arguments MUST NOT have any side-effects. */ +#define _Unwind_InitContext(context, uc) \ + ((context)->end_of_stack = 0, \ + ((unw_getcontext (uc) < 0 || unw_init_local (&(context)->cursor, uc) < 0) \ + ? -1 : 0)) + +static _Unwind_Reason_Code ALWAYS_INLINE +_Unwind_Phase2 (struct _Unwind_Exception *exception_object, + struct _Unwind_Context *context) +{ + _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) exception_object->private_1; + uint64_t exception_class = exception_object->exception_class; + void *stop_parameter = (void *) exception_object->private_2; + _Unwind_Personality_Fn personality; + _Unwind_Reason_Code reason; + _Unwind_Action actions; + unw_proc_info_t pi; + unw_word_t ip; + int ret; + + actions = _UA_CLEANUP_PHASE; + if (stop) + actions |= _UA_FORCE_UNWIND; + + while (1) + { + ret = unw_step (&context->cursor); + if (ret <= 0) + { + if (ret == 0) + { + actions |= _UA_END_OF_STACK; + context->end_of_stack = 1; + } + else + return _URC_FATAL_PHASE2_ERROR; + } + + if (stop) + { + reason = (*stop) (_U_VERSION, actions, exception_class, + exception_object, context, stop_parameter); + if (reason != _URC_NO_REASON) + /* Stop function may return _URC_FATAL_PHASE2_ERROR if + it's unable to handle end-of-stack condition or + _URC_FATAL_PHASE2_ERROR if something is wrong. Not + that it matters: the resulting state is indeterminate + anyhow so we must return _URC_FATAL_PHASE2_ERROR... */ + return _URC_FATAL_PHASE2_ERROR; + } + + if (context->end_of_stack + || unw_get_proc_info (&context->cursor, &pi) < 0) + return _URC_FATAL_PHASE2_ERROR; + + personality = (_Unwind_Personality_Fn) (uintptr_t) pi.handler; + if (personality) + { + if (!stop) + { + if (unw_get_reg (&context->cursor, UNW_REG_IP, &ip) < 0) + return _URC_FATAL_PHASE2_ERROR; + + if ((unsigned long) stop_parameter == ip) + actions |= _UA_HANDLER_FRAME; + } + + reason = (*personality) (_U_VERSION, actions, exception_class, + exception_object, context); + if (reason != _URC_CONTINUE_UNWIND) + { + if (reason == _URC_INSTALL_CONTEXT) + { + /* we may regain control via _Unwind_Resume() */ + unw_resume (&context->cursor); + abort (); + } + else + return _URC_FATAL_PHASE2_ERROR; + } + if (actions & _UA_HANDLER_FRAME) + /* The personality routine for the handler-frame changed + it's mind; that's a no-no... */ + abort (); + } + } + return _URC_FATAL_PHASE2_ERROR; /* shouldn't be reached */ +} + +#endif /* unwind_internal_h */ diff --git a/src/libs/libunwind/x86/Gcreate_addr_space.c b/src/libs/libunwind/x86/Gcreate_addr_space.c new file mode 100644 index 0000000000..45fec6da8d --- /dev/null +++ b/src/libs/libunwind/x86/Gcreate_addr_space.c @@ -0,0 +1,58 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#if defined(_LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN) +#define __LITTLE_ENDIAN _LITTLE_ENDIAN +#endif + +PROTECTED unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * x86 supports only little-endian. + */ + if (byte_order != 0 && byte_order != __LITTLE_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + return as; +#endif +} diff --git a/src/libs/libunwind/x86/Gget_proc_info.c b/src/libs/libunwind/x86/Gget_proc_info.c new file mode 100644 index 0000000000..45b4cd5bc1 --- /dev/null +++ b/src/libs/libunwind/x86/Gget_proc_info.c @@ -0,0 +1,45 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + + if (dwarf_make_proc_info (&c->dwarf) < 0) + { + /* On x86, it's relatively common to be missing DWARF unwind + info. We don't want to fail in that case, because the + frame-chain still would let us do a backtrace at least. */ + memset (pi, 0, sizeof (*pi)); + pi->start_ip = c->dwarf.ip; + pi->end_ip = c->dwarf.ip + 1; + return 0; + } + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/libs/libunwind/x86/Gget_save_loc.c b/src/libs/libunwind/x86/Gget_save_loc.c new file mode 100644 index 0000000000..d440f9eca5 --- /dev/null +++ b/src/libs/libunwind/x86/Gget_save_loc.c @@ -0,0 +1,133 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + + switch (reg) + { + case UNW_X86_EIP: loc = c->dwarf.loc[EIP]; break; + case UNW_X86_CFA: break; + case UNW_X86_EAX: loc = c->dwarf.loc[EAX]; break; + case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break; + case UNW_X86_EDX: loc = c->dwarf.loc[EDX]; break; + case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break; + case UNW_X86_ESP: loc = c->dwarf.loc[ESP]; break; + case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break; + case UNW_X86_ESI: loc = c->dwarf.loc[ESI]; break; + case UNW_X86_EDI: loc = c->dwarf.loc[EDI]; break; + case UNW_X86_EFLAGS: loc = c->dwarf.loc[EFLAGS]; break; + case UNW_X86_TRAPNO: loc = c->dwarf.loc[TRAPNO]; break; + case UNW_X86_ST0: loc = c->dwarf.loc[ST0]; break; + + case UNW_X86_FCW: + case UNW_X86_FSW: + case UNW_X86_FTW: + case UNW_X86_FOP: + case UNW_X86_FCS: + case UNW_X86_FIP: + case UNW_X86_FEA: + case UNW_X86_FDS: + case UNW_X86_MXCSR: + case UNW_X86_GS: + case UNW_X86_FS: + case UNW_X86_ES: + case UNW_X86_DS: + case UNW_X86_SS: + case UNW_X86_CS: + case UNW_X86_TSS: + case UNW_X86_LDT: + loc = x86_scratch_loc (c, reg); + break; + + /* stacked fp registers */ + case UNW_X86_ST1: + case UNW_X86_ST2: + case UNW_X86_ST3: + case UNW_X86_ST4: + case UNW_X86_ST5: + case UNW_X86_ST6: + case UNW_X86_ST7: + /* SSE fp registers */ + case UNW_X86_XMM0_lo: + case UNW_X86_XMM0_hi: + case UNW_X86_XMM1_lo: + case UNW_X86_XMM1_hi: + case UNW_X86_XMM2_lo: + case UNW_X86_XMM2_hi: + case UNW_X86_XMM3_lo: + case UNW_X86_XMM3_hi: + case UNW_X86_XMM4_lo: + case UNW_X86_XMM4_hi: + case UNW_X86_XMM5_lo: + case UNW_X86_XMM5_hi: + case UNW_X86_XMM6_lo: + case UNW_X86_XMM6_hi: + case UNW_X86_XMM7_lo: + case UNW_X86_XMM7_hi: + case UNW_X86_XMM0: + case UNW_X86_XMM1: + case UNW_X86_XMM2: + case UNW_X86_XMM3: + case UNW_X86_XMM4: + case UNW_X86_XMM5: + case UNW_X86_XMM6: + case UNW_X86_XMM7: + loc = x86_scratch_loc (c, reg); + break; + + default: + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/libs/libunwind/x86/Gglobal.c b/src/libs/libunwind/x86/Gglobal.c new file mode 100644 index 0000000000..132b824994 --- /dev/null +++ b/src/libs/libunwind/x86/Gglobal.c @@ -0,0 +1,67 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (x86_lock); +HIDDEN int tdep_init_done; + +/* See comments for svr4_dbx_register_map[] in gcc/config/i386/i386.c. */ + +HIDDEN const uint8_t dwarf_to_unw_regnum_map[19] = + { + UNW_X86_EAX, UNW_X86_ECX, UNW_X86_EDX, UNW_X86_EBX, + UNW_X86_ESP, UNW_X86_EBP, UNW_X86_ESI, UNW_X86_EDI, + UNW_X86_EIP, UNW_X86_EFLAGS, UNW_X86_TRAPNO, + UNW_X86_ST0, UNW_X86_ST1, UNW_X86_ST2, UNW_X86_ST3, + UNW_X86_ST4, UNW_X86_ST5, UNW_X86_ST6, UNW_X86_ST7 + }; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&x86_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + x86_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&x86_lock, saved_mask); +} diff --git a/src/libs/libunwind/x86/Ginit.c b/src/libs/libunwind/x86/Ginit.c new file mode 100644 index 0000000000..b05a08edba --- /dev/null +++ b/src/libs/libunwind/x86/Ginit.c @@ -0,0 +1,243 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +PROTECTED unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space; + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + return x86_r_uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; + return 0; +} + +#define PAGE_SIZE 4096 +#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) + +/* Cache of already validated addresses */ +#define NLGA 4 +static unw_word_t last_good_addr[NLGA]; +static int lga_victim; + +static int +validate_mem (unw_word_t addr) +{ + int i, victim; +#ifdef HAVE_MINCORE + unsigned char mvec[2]; /* Unaligned access may cross page boundary */ +#endif + size_t len; + + if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) + len = PAGE_SIZE; + else + len = PAGE_SIZE * 2; + + addr = PAGE_START(addr); + + if (addr == 0) + return -1; + + for (i = 0; i < NLGA; i++) + { + if (last_good_addr[i] && (addr == last_good_addr[i])) + return 0; + } + +#ifdef HAVE_MINCORE + if (mincore ((void *) addr, len, mvec) == -1) +#else + if (msync ((void *) addr, len, MS_ASYNC) == -1) +#endif + return -1; + + victim = lga_victim; + for (i = 0; i < NLGA; i++) { + if (!last_good_addr[victim]) { + last_good_addr[victim++] = addr; + return 0; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + last_good_addr[victim] = addr; + victim = (victim + 1) % NLGA; + lga_victim = victim; + + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (16, "mem[%x] <- %x\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + /* validate address */ + const struct cursor *c = (const struct cursor *)arg; + if (c && c->validate && validate_mem(addr)) + return -1; + *val = *(unw_word_t *) addr; + Debug (16, "mem[%x] -> %x\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = ((struct cursor *)arg)->uc; + + if (unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = x86_r_uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %x\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %x\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = ((struct cursor *)arg)->uc; + unw_fpreg_t *addr; + + if (!unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = x86_r_uc_addr (uc, reg))) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +x86_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = x86_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/x86/Ginit_local.c b/src/libs/libunwind/x86/Ginit_local.c new file mode 100644 index 0000000000..02fb994e0b --- /dev/null +++ b/src/libs/libunwind/x86/Ginit_local.c @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = c; + c->uc = uc; + c->validate = 0; + return common_init (c, 1); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/x86/Ginit_remote.c b/src/libs/libunwind/x86/Ginit_remote.c new file mode 100644 index 0000000000..16b6395441 --- /dev/null +++ b/src/libs/libunwind/x86/Ginit_remote.c @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +PROTECTED int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + if (as == unw_local_addr_space) + { + c->dwarf.as_arg = c; + c->uc = as_arg; + } + else + { + c->dwarf.as_arg = as_arg; + c->uc = 0; + } + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/libs/libunwind/x86/Gos-freebsd.c b/src/libs/libunwind/x86/Gos-freebsd.c new file mode 100644 index 0000000000..cf05f0789d --- /dev/null +++ b/src/libs/libunwind/x86/Gos-freebsd.c @@ -0,0 +1,374 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include "unwind_i.h" +#include "offsets.h" + +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, w2, w3, w4, w5, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors (as); + arg = c->dwarf.as_arg; + + /* Check if EIP points at sigreturn() sequence. It can be: +sigcode+4: from amd64 freebsd32 environment +8d 44 24 20 lea 0x20(%esp),%eax +50 push %eax +b8 a1 01 00 00 mov $0x1a1,%eax +50 push %eax +cd 80 int $0x80 + +sigcode+4: from real i386 +8d 44 24 20 lea 0x20(%esp),%eax +50 push %eax +f7 40 54 00 02 00 testl $0x20000,0x54(%eax) +75 03 jne sigcode+21 +8e 68 14 mov 0x14(%eax),%gs +b8 a1 01 00 00 mov $0x1a1,%eax +50 push %eax +cd 80 int $0x80 + +freebsd4_sigcode+4: +XXX +osigcode: +XXX + */ + ip = c->dwarf.ip; + ret = X86_SCF_NONE; + c->sigcontext_format = ret; + if ((*a->access_mem) (as, ip, &w0, 0, arg) < 0 || + (*a->access_mem) (as, ip + 4, &w1, 0, arg) < 0 || + (*a->access_mem) (as, ip + 8, &w2, 0, arg) < 0 || + (*a->access_mem) (as, ip + 12, &w3, 0, arg) < 0) + return ret; + if (w0 == 0x2024448d && w1 == 0x01a1b850 && w2 == 0xcd500000 && + (w3 & 0xff) == 0x80) + ret = X86_SCF_FREEBSD_SIGFRAME; + else { + if ((*a->access_mem) (as, ip + 16, &w4, 0, arg) < 0 || + (*a->access_mem) (as, ip + 20, &w5, 0, arg) < 0) + return ret; + if (w0 == 0x2024448d && w1 == 0x5440f750 && w2 == 0x75000200 && + w3 == 0x14688e03 && w4 == 0x0001a1b8 && w5 == 0x80cd5000) + ret = X86_SCF_FREEBSD_SIGFRAME; + } + + /* Check for syscall */ + if (ret == X86_SCF_NONE && (*a->access_mem) (as, ip - 2, &w0, 0, arg) >= 0 && + (w0 & 0xffff) == 0x80cd) + ret = X86_SCF_FREEBSD_SYSCALL; + Debug (16, "returning %d\n", ret); + c->sigcontext_format = ret; + return (ret); +} + +PROTECTED int +unw_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + if (c->sigcontext_format == X86_SCF_FREEBSD_SIGFRAME) { + struct sigframe *sf; + uintptr_t uc_addr; + struct dwarf_loc esp_loc; + + sf = (struct sigframe *)c->dwarf.cfa; + uc_addr = (uintptr_t)&(sf->sf_uc); + c->sigcontext_addr = c->dwarf.cfa; + + esp_loc = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESP_OFF, 0); + ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa); + if (ret < 0) + { + Debug (2, "returning 0\n"); + return 0; + } + + c->dwarf.loc[EIP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EIP_OFF, 0); + c->dwarf.loc[ESP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESP_OFF, 0); + c->dwarf.loc[EAX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EAX_OFF, 0); + c->dwarf.loc[ECX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ECX_OFF, 0); + c->dwarf.loc[EDX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EDX_OFF, 0); + c->dwarf.loc[EBX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EBX_OFF, 0); + c->dwarf.loc[EBP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EBP_OFF, 0); + c->dwarf.loc[ESI] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESI_OFF, 0); + c->dwarf.loc[EDI] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EDI_OFF, 0); + c->dwarf.loc[EFLAGS] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EFLAGS_OFF, 0); + c->dwarf.loc[TRAPNO] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_TRAPNO_OFF, 0); + c->dwarf.loc[ST0] = DWARF_NULL_LOC; + } else if (c->sigcontext_format == X86_SCF_FREEBSD_SYSCALL) { + c->dwarf.loc[EIP] = DWARF_LOC (c->dwarf.cfa, 0); + c->dwarf.loc[EAX] = DWARF_NULL_LOC; + c->dwarf.cfa += 4; + c->dwarf.use_prev_instr = 1; + } else { + Debug (8, "Gstep: not handling frame format %d\n", c->sigcontext_format); + abort(); + } + return 0; +} + +HIDDEN dwarf_loc_t +x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg) +{ + unw_word_t addr = c->sigcontext_addr, off, xmm_off; + unw_word_t fpstate, fpformat; + int ret, is_fpstate = 0, is_xmmstate = 0; + + switch (c->sigcontext_format) + { + case X86_SCF_NONE: + return DWARF_REG_LOC (&c->dwarf, reg); + + case X86_SCF_FREEBSD_SIGFRAME: + addr += offsetof(struct sigframe, sf_uc) + FREEBSD_UC_MCONTEXT_OFF; + break; + + case X86_SCF_FREEBSD_SIGFRAME4: + abort(); + break; + + case X86_SCF_FREEBSD_OSIGFRAME: + /* XXXKIB */ + abort(); + break; + + case X86_SCF_FREEBSD_SYSCALL: + /* XXXKIB */ + abort(); + break; + + default: + /* XXXKIB */ + abort(); + break; + } + + off = 0; /* shut gcc warning */ + switch (reg) + { + case UNW_X86_GS: off = FREEBSD_UC_MCONTEXT_GS_OFF; break; + case UNW_X86_FS: off = FREEBSD_UC_MCONTEXT_FS_OFF; break; + case UNW_X86_ES: off = FREEBSD_UC_MCONTEXT_ES_OFF; break; + case UNW_X86_DS: off = FREEBSD_UC_MCONTEXT_SS_OFF; break; + case UNW_X86_EDI: off = FREEBSD_UC_MCONTEXT_EDI_OFF; break; + case UNW_X86_ESI: off = FREEBSD_UC_MCONTEXT_ESI_OFF; break; + case UNW_X86_EBP: off = FREEBSD_UC_MCONTEXT_EBP_OFF; break; + case UNW_X86_ESP: off = FREEBSD_UC_MCONTEXT_ESP_OFF; break; + case UNW_X86_EBX: off = FREEBSD_UC_MCONTEXT_EBX_OFF; break; + case UNW_X86_EDX: off = FREEBSD_UC_MCONTEXT_EDX_OFF; break; + case UNW_X86_ECX: off = FREEBSD_UC_MCONTEXT_ECX_OFF; break; + case UNW_X86_EAX: off = FREEBSD_UC_MCONTEXT_EAX_OFF; break; + case UNW_X86_TRAPNO: off = FREEBSD_UC_MCONTEXT_TRAPNO_OFF; break; + case UNW_X86_EIP: off = FREEBSD_UC_MCONTEXT_EIP_OFF; break; + case UNW_X86_CS: off = FREEBSD_UC_MCONTEXT_CS_OFF; break; + case UNW_X86_EFLAGS: off = FREEBSD_UC_MCONTEXT_EFLAGS_OFF; break; + case UNW_X86_SS: off = FREEBSD_UC_MCONTEXT_SS_OFF; break; + + case UNW_X86_FCW: + is_fpstate = 1; + off = FREEBSD_UC_MCONTEXT_CW_OFF; + xmm_off = FREEBSD_UC_MCONTEXT_CW_XMM_OFF; + break; + case UNW_X86_FSW: + is_fpstate = 1; + off = FREEBSD_UC_MCONTEXT_SW_OFF; + xmm_off = FREEBSD_UC_MCONTEXT_SW_XMM_OFF; + break; + case UNW_X86_FTW: + is_fpstate = 1; + xmm_off = FREEBSD_UC_MCONTEXT_TAG_XMM_OFF; + off = FREEBSD_UC_MCONTEXT_TAG_OFF; + break; + case UNW_X86_FCS: + is_fpstate = 1; + off = FREEBSD_UC_MCONTEXT_CSSEL_OFF; + xmm_off = FREEBSD_UC_MCONTEXT_CSSEL_XMM_OFF; + break; + case UNW_X86_FIP: + is_fpstate = 1; + off = FREEBSD_UC_MCONTEXT_IPOFF_OFF; + xmm_off = FREEBSD_UC_MCONTEXT_IPOFF_XMM_OFF; + break; + case UNW_X86_FEA: + is_fpstate = 1; + off = FREEBSD_UC_MCONTEXT_DATAOFF_OFF; + xmm_off = FREEBSD_UC_MCONTEXT_DATAOFF_XMM_OFF; + break; + case UNW_X86_FDS: + is_fpstate = 1; + off = FREEBSD_US_MCONTEXT_DATASEL_OFF; + xmm_off = FREEBSD_US_MCONTEXT_DATASEL_XMM_OFF; + break; + case UNW_X86_MXCSR: + is_fpstate = 1; + is_xmmstate = 1; + xmm_off = FREEBSD_UC_MCONTEXT_MXCSR_XMM_OFF; + break; + + /* stacked fp registers */ + case UNW_X86_ST0: case UNW_X86_ST1: case UNW_X86_ST2: case UNW_X86_ST3: + case UNW_X86_ST4: case UNW_X86_ST5: case UNW_X86_ST6: case UNW_X86_ST7: + is_fpstate = 1; + off = FREEBSD_UC_MCONTEXT_ST0_OFF + 10*(reg - UNW_X86_ST0); + xmm_off = FREEBSD_UC_MCONTEXT_ST0_XMM_OFF + 10*(reg - UNW_X86_ST0); + break; + + /* SSE fp registers */ + case UNW_X86_XMM0_lo: case UNW_X86_XMM0_hi: + case UNW_X86_XMM1_lo: case UNW_X86_XMM1_hi: + case UNW_X86_XMM2_lo: case UNW_X86_XMM2_hi: + case UNW_X86_XMM3_lo: case UNW_X86_XMM3_hi: + case UNW_X86_XMM4_lo: case UNW_X86_XMM4_hi: + case UNW_X86_XMM5_lo: case UNW_X86_XMM5_hi: + case UNW_X86_XMM6_lo: case UNW_X86_XMM6_hi: + case UNW_X86_XMM7_lo: case UNW_X86_XMM7_hi: + is_fpstate = 1; + is_xmmstate = 1; + xmm_off = FREEBSD_UC_MCONTEXT_XMM0_OFF + 8*(reg - UNW_X86_XMM0_lo); + break; + case UNW_X86_XMM0: + case UNW_X86_XMM1: + case UNW_X86_XMM2: + case UNW_X86_XMM3: + case UNW_X86_XMM4: + case UNW_X86_XMM5: + case UNW_X86_XMM6: + case UNW_X86_XMM7: + is_fpstate = 1; + is_xmmstate = 1; + xmm_off = FREEBSD_UC_MCONTEXT_XMM0_OFF + 16*(reg - UNW_X86_XMM0); + break; + + case UNW_X86_FOP: + case UNW_X86_TSS: + case UNW_X86_LDT: + default: + return DWARF_REG_LOC (&c->dwarf, reg); + } + + if (is_fpstate) + { + if ((ret = dwarf_get (&c->dwarf, + DWARF_MEM_LOC (&c->dwarf, addr + FREEBSD_UC_MCONTEXT_FPSTATE_OFF), + &fpstate)) < 0) + return DWARF_NULL_LOC; + if (fpstate == FREEBSD_UC_MCONTEXT_FPOWNED_NONE) + return DWARF_NULL_LOC; + if ((ret = dwarf_get (&c->dwarf, + DWARF_MEM_LOC (&c->dwarf, addr + FREEBSD_UC_MCONTEXT_FPFORMAT_OFF), + &fpformat)) < 0) + return DWARF_NULL_LOC; + if (fpformat == FREEBSD_UC_MCONTEXT_FPFMT_NODEV || + (is_xmmstate && fpformat != FREEBSD_UC_MCONTEXT_FPFMT_XMM)) + return DWARF_NULL_LOC; + if (is_xmmstate) + off = xmm_off; + } + + return DWARF_MEM_LOC (c, addr + off); +} + +#ifndef UNW_REMOTE_ONLY +HIDDEN void * +x86_r_uc_addr (ucontext_t *uc, int reg) +{ + void *addr; + + switch (reg) + { + case UNW_X86_GS: addr = &uc->uc_mcontext.mc_gs; break; + case UNW_X86_FS: addr = &uc->uc_mcontext.mc_fs; break; + case UNW_X86_ES: addr = &uc->uc_mcontext.mc_es; break; + case UNW_X86_DS: addr = &uc->uc_mcontext.mc_ds; break; + case UNW_X86_EAX: addr = &uc->uc_mcontext.mc_eax; break; + case UNW_X86_EBX: addr = &uc->uc_mcontext.mc_ebx; break; + case UNW_X86_ECX: addr = &uc->uc_mcontext.mc_ecx; break; + case UNW_X86_EDX: addr = &uc->uc_mcontext.mc_edx; break; + case UNW_X86_ESI: addr = &uc->uc_mcontext.mc_esi; break; + case UNW_X86_EDI: addr = &uc->uc_mcontext.mc_edi; break; + case UNW_X86_EBP: addr = &uc->uc_mcontext.mc_ebp; break; + case UNW_X86_EIP: addr = &uc->uc_mcontext.mc_eip; break; + case UNW_X86_ESP: addr = &uc->uc_mcontext.mc_esp; break; + case UNW_X86_TRAPNO: addr = &uc->uc_mcontext.mc_trapno; break; + case UNW_X86_CS: addr = &uc->uc_mcontext.mc_cs; break; + case UNW_X86_EFLAGS: addr = &uc->uc_mcontext.mc_eflags; break; + case UNW_X86_SS: addr = &uc->uc_mcontext.mc_ss; break; + + default: + addr = NULL; + } + return addr; +} + +HIDDEN int +x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = c->uc; + + /* Ensure c->pi is up-to-date. On x86, it's relatively common to be + missing DWARF unwind info. We don't want to fail in that case, + because the frame-chain still would let us do a backtrace at + least. */ + dwarf_make_proc_info (&c->dwarf); + + if (c->sigcontext_format == X86_SCF_NONE) { + Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip); + setcontext (uc); + abort(); + } else if (c->sigcontext_format == X86_SCF_FREEBSD_SIGFRAME) { + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + + Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc); + sigreturn((ucontext_t *)((const char *)sc + FREEBSD_SC_UCONTEXT_OFF)); + abort(); + } else { + Debug (8, "resuming at ip=%x for sigcontext format %d not implemented\n", + c->dwarf.ip, c->sigcontext_format); + abort(); + } + return -UNW_EINVAL; +} + +#endif diff --git a/src/libs/libunwind/x86/Gos-linux.c b/src/libs/libunwind/x86/Gos-linux.c new file mode 100644 index 0000000000..17aebc2974 --- /dev/null +++ b/src/libs/libunwind/x86/Gos-linux.c @@ -0,0 +1,308 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors (as); + arg = c->dwarf.as_arg; + + /* Check if EIP points at sigreturn() sequence. On Linux, this is: + + __restore: + 0x58 pop %eax + 0xb8 0x77 0x00 0x00 0x00 movl 0x77,%eax + 0xcd 0x80 int 0x80 + + without SA_SIGINFO, and + + __restore_rt: + 0xb8 0xad 0x00 0x00 0x00 movl 0xad,%eax + 0xcd 0x80 int 0x80 + 0x00 + + if SA_SIGINFO is specified. + */ + ip = c->dwarf.ip; + if ((*a->access_mem) (as, ip, &w0, 0, arg) < 0 + || (*a->access_mem) (as, ip + 4, &w1, 0, arg) < 0) + ret = 0; + else + ret = ((w0 == 0x0077b858 && w1 == 0x80cd0000) + || (w0 == 0x0000adb8 && (w1 & 0xffffff) == 0x80cd00)); + Debug (16, "returning %d\n", ret); + return ret; +} + +PROTECTED int +unw_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + /* c->esp points at the arguments to the handler. Without + SA_SIGINFO, the arguments consist of a signal number + followed by a struct sigcontext. With SA_SIGINFO, the + arguments consist a signal number, a siginfo *, and a + ucontext *. */ + unw_word_t sc_addr; + unw_word_t siginfo_ptr_addr = c->dwarf.cfa + 4; + unw_word_t sigcontext_ptr_addr = c->dwarf.cfa + 8; + unw_word_t siginfo_ptr, sigcontext_ptr; + struct dwarf_loc esp_loc, siginfo_ptr_loc, sigcontext_ptr_loc; + + siginfo_ptr_loc = DWARF_LOC (siginfo_ptr_addr, 0); + sigcontext_ptr_loc = DWARF_LOC (sigcontext_ptr_addr, 0); + ret = (dwarf_get (&c->dwarf, siginfo_ptr_loc, &siginfo_ptr) + | dwarf_get (&c->dwarf, sigcontext_ptr_loc, &sigcontext_ptr)); + if (ret < 0) + { + Debug (2, "returning 0\n"); + return 0; + } + if (siginfo_ptr < c->dwarf.cfa + || siginfo_ptr > c->dwarf.cfa + 256 + || sigcontext_ptr < c->dwarf.cfa + || sigcontext_ptr > c->dwarf.cfa + 256) + { + /* Not plausible for SA_SIGINFO signal */ + c->sigcontext_format = X86_SCF_LINUX_SIGFRAME; + c->sigcontext_addr = sc_addr = c->dwarf.cfa + 4; + } + else + { + /* If SA_SIGINFO were not specified, we actually read + various segment pointers instead. We believe that at + least fs and _fsh are always zero for linux, so it is + not just unlikely, but impossible that we would end + up here. */ + c->sigcontext_format = X86_SCF_LINUX_RT_SIGFRAME; + c->sigcontext_addr = sigcontext_ptr; + sc_addr = sigcontext_ptr + LINUX_UC_MCONTEXT_OFF; + } + esp_loc = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0); + ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa); + if (ret < 0) + { + Debug (2, "returning 0\n"); + return 0; + } + + c->dwarf.loc[EAX] = DWARF_LOC (sc_addr + LINUX_SC_EAX_OFF, 0); + c->dwarf.loc[ECX] = DWARF_LOC (sc_addr + LINUX_SC_ECX_OFF, 0); + c->dwarf.loc[EDX] = DWARF_LOC (sc_addr + LINUX_SC_EDX_OFF, 0); + c->dwarf.loc[EBX] = DWARF_LOC (sc_addr + LINUX_SC_EBX_OFF, 0); + c->dwarf.loc[EBP] = DWARF_LOC (sc_addr + LINUX_SC_EBP_OFF, 0); + c->dwarf.loc[ESI] = DWARF_LOC (sc_addr + LINUX_SC_ESI_OFF, 0); + c->dwarf.loc[EDI] = DWARF_LOC (sc_addr + LINUX_SC_EDI_OFF, 0); + c->dwarf.loc[EFLAGS] = DWARF_NULL_LOC; + c->dwarf.loc[TRAPNO] = DWARF_NULL_LOC; + c->dwarf.loc[ST0] = DWARF_NULL_LOC; + c->dwarf.loc[EIP] = DWARF_LOC (sc_addr + LINUX_SC_EIP_OFF, 0); + c->dwarf.loc[ESP] = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0); + + return 0; +} + +HIDDEN dwarf_loc_t +x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg) +{ + unw_word_t addr = c->sigcontext_addr, fpstate_addr, off; + int ret, is_fpstate = 0; + + switch (c->sigcontext_format) + { + case X86_SCF_NONE: + return DWARF_REG_LOC (&c->dwarf, reg); + + case X86_SCF_LINUX_SIGFRAME: + break; + + case X86_SCF_LINUX_RT_SIGFRAME: + addr += LINUX_UC_MCONTEXT_OFF; + break; + + default: + return DWARF_NULL_LOC; + } + + switch (reg) + { + case UNW_X86_GS: off = LINUX_SC_GS_OFF; break; + case UNW_X86_FS: off = LINUX_SC_FS_OFF; break; + case UNW_X86_ES: off = LINUX_SC_ES_OFF; break; + case UNW_X86_DS: off = LINUX_SC_DS_OFF; break; + case UNW_X86_EDI: off = LINUX_SC_EDI_OFF; break; + case UNW_X86_ESI: off = LINUX_SC_ESI_OFF; break; + case UNW_X86_EBP: off = LINUX_SC_EBP_OFF; break; + case UNW_X86_ESP: off = LINUX_SC_ESP_OFF; break; + case UNW_X86_EBX: off = LINUX_SC_EBX_OFF; break; + case UNW_X86_EDX: off = LINUX_SC_EDX_OFF; break; + case UNW_X86_ECX: off = LINUX_SC_ECX_OFF; break; + case UNW_X86_EAX: off = LINUX_SC_EAX_OFF; break; + case UNW_X86_TRAPNO: off = LINUX_SC_TRAPNO_OFF; break; + case UNW_X86_EIP: off = LINUX_SC_EIP_OFF; break; + case UNW_X86_CS: off = LINUX_SC_CS_OFF; break; + case UNW_X86_EFLAGS: off = LINUX_SC_EFLAGS_OFF; break; + case UNW_X86_SS: off = LINUX_SC_SS_OFF; break; + + /* The following is probably not correct for all possible cases. + Somebody who understands this better should review this for + correctness. */ + + case UNW_X86_FCW: is_fpstate = 1; off = LINUX_FPSTATE_CW_OFF; break; + case UNW_X86_FSW: is_fpstate = 1; off = LINUX_FPSTATE_SW_OFF; break; + case UNW_X86_FTW: is_fpstate = 1; off = LINUX_FPSTATE_TAG_OFF; break; + case UNW_X86_FCS: is_fpstate = 1; off = LINUX_FPSTATE_CSSEL_OFF; break; + case UNW_X86_FIP: is_fpstate = 1; off = LINUX_FPSTATE_IPOFF_OFF; break; + case UNW_X86_FEA: is_fpstate = 1; off = LINUX_FPSTATE_DATAOFF_OFF; break; + case UNW_X86_FDS: is_fpstate = 1; off = LINUX_FPSTATE_DATASEL_OFF; break; + case UNW_X86_MXCSR: is_fpstate = 1; off = LINUX_FPSTATE_MXCSR_OFF; break; + + /* stacked fp registers */ + case UNW_X86_ST0: case UNW_X86_ST1: case UNW_X86_ST2: case UNW_X86_ST3: + case UNW_X86_ST4: case UNW_X86_ST5: case UNW_X86_ST6: case UNW_X86_ST7: + is_fpstate = 1; + off = LINUX_FPSTATE_ST0_OFF + 10*(reg - UNW_X86_ST0); + break; + + /* SSE fp registers */ + case UNW_X86_XMM0_lo: case UNW_X86_XMM0_hi: + case UNW_X86_XMM1_lo: case UNW_X86_XMM1_hi: + case UNW_X86_XMM2_lo: case UNW_X86_XMM2_hi: + case UNW_X86_XMM3_lo: case UNW_X86_XMM3_hi: + case UNW_X86_XMM4_lo: case UNW_X86_XMM4_hi: + case UNW_X86_XMM5_lo: case UNW_X86_XMM5_hi: + case UNW_X86_XMM6_lo: case UNW_X86_XMM6_hi: + case UNW_X86_XMM7_lo: case UNW_X86_XMM7_hi: + is_fpstate = 1; + off = LINUX_FPSTATE_XMM0_OFF + 8*(reg - UNW_X86_XMM0_lo); + break; + case UNW_X86_XMM0: + case UNW_X86_XMM1: + case UNW_X86_XMM2: + case UNW_X86_XMM3: + case UNW_X86_XMM4: + case UNW_X86_XMM5: + case UNW_X86_XMM6: + case UNW_X86_XMM7: + is_fpstate = 1; + off = LINUX_FPSTATE_XMM0_OFF + 16*(reg - UNW_X86_XMM0); + break; + + case UNW_X86_FOP: + case UNW_X86_TSS: + case UNW_X86_LDT: + default: + return DWARF_REG_LOC (&c->dwarf, reg); + } + + if (is_fpstate) + { + if ((ret = dwarf_get (&c->dwarf, + DWARF_MEM_LOC (&c->dwarf, + addr + LINUX_SC_FPSTATE_OFF), + &fpstate_addr)) < 0) + return DWARF_NULL_LOC; + + if (!fpstate_addr) + return DWARF_NULL_LOC; + + return DWARF_MEM_LOC (c, fpstate_addr + off); + } + else + return DWARF_MEM_LOC (c, addr + off); +} + +#ifndef UNW_REMOTE_ONLY +HIDDEN void * +x86_r_uc_addr (ucontext_t *uc, int reg) +{ + void *addr; + + switch (reg) + { + case UNW_X86_GS: addr = &uc->uc_mcontext.gregs[REG_GS]; break; + case UNW_X86_FS: addr = &uc->uc_mcontext.gregs[REG_FS]; break; + case UNW_X86_ES: addr = &uc->uc_mcontext.gregs[REG_ES]; break; + case UNW_X86_DS: addr = &uc->uc_mcontext.gregs[REG_DS]; break; + case UNW_X86_EAX: addr = &uc->uc_mcontext.gregs[REG_EAX]; break; + case UNW_X86_EBX: addr = &uc->uc_mcontext.gregs[REG_EBX]; break; + case UNW_X86_ECX: addr = &uc->uc_mcontext.gregs[REG_ECX]; break; + case UNW_X86_EDX: addr = &uc->uc_mcontext.gregs[REG_EDX]; break; + case UNW_X86_ESI: addr = &uc->uc_mcontext.gregs[REG_ESI]; break; + case UNW_X86_EDI: addr = &uc->uc_mcontext.gregs[REG_EDI]; break; + case UNW_X86_EBP: addr = &uc->uc_mcontext.gregs[REG_EBP]; break; + case UNW_X86_EIP: addr = &uc->uc_mcontext.gregs[REG_EIP]; break; + case UNW_X86_ESP: addr = &uc->uc_mcontext.gregs[REG_ESP]; break; + case UNW_X86_TRAPNO: addr = &uc->uc_mcontext.gregs[REG_TRAPNO]; break; + case UNW_X86_CS: addr = &uc->uc_mcontext.gregs[REG_CS]; break; + case UNW_X86_EFLAGS: addr = &uc->uc_mcontext.gregs[REG_EFL]; break; + case UNW_X86_SS: addr = &uc->uc_mcontext.gregs[REG_SS]; break; + + default: + addr = NULL; + } + return addr; +} + +HIDDEN int +x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = c->uc; + + /* Ensure c->pi is up-to-date. On x86, it's relatively common to be + missing DWARF unwind info. We don't want to fail in that case, + because the frame-chain still would let us do a backtrace at + least. */ + dwarf_make_proc_info (&c->dwarf); + + if (unlikely (c->sigcontext_format != X86_SCF_NONE)) + { + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + + Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc); + sigreturn (sc); + } + else + { + Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip); + setcontext (uc); + } + return -UNW_EINVAL; +} +#endif diff --git a/src/libs/libunwind/x86/Gregs.c b/src/libs/libunwind/x86/Gregs.c new file mode 100644 index 0000000000..4a9592617d --- /dev/null +++ b/src/libs/libunwind/x86/Gregs.c @@ -0,0 +1,178 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" +#include "unwind_i.h" + +HIDDEN dwarf_loc_t +x86_scratch_loc (struct cursor *c, unw_regnum_t reg) +{ + if (c->sigcontext_addr) + return x86_get_scratch_loc (c, reg); + else + return DWARF_REG_LOC (&c->dwarf, reg); +} + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + unsigned int mask; + int arg_num; + + switch (reg) + { + + case UNW_X86_EIP: + if (write) + c->dwarf.ip = *valp; /* also update the EIP cache */ + loc = c->dwarf.loc[EIP]; + break; + + case UNW_X86_CFA: + case UNW_X86_ESP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + case UNW_X86_EAX: + case UNW_X86_EDX: + arg_num = reg - UNW_X86_EAX; + mask = (1 << arg_num); + if (write) + { + c->dwarf.eh_args[arg_num] = *valp; + c->dwarf.eh_valid_mask |= mask; + return 0; + } + else if ((c->dwarf.eh_valid_mask & mask) != 0) + { + *valp = c->dwarf.eh_args[arg_num]; + return 0; + } + else + loc = c->dwarf.loc[(reg == UNW_X86_EAX) ? EAX : EDX]; + break; + + case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break; + case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break; + + case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break; + case UNW_X86_ESI: loc = c->dwarf.loc[ESI]; break; + case UNW_X86_EDI: loc = c->dwarf.loc[EDI]; break; + case UNW_X86_EFLAGS: loc = c->dwarf.loc[EFLAGS]; break; + case UNW_X86_TRAPNO: loc = c->dwarf.loc[TRAPNO]; break; + + case UNW_X86_FCW: + case UNW_X86_FSW: + case UNW_X86_FTW: + case UNW_X86_FOP: + case UNW_X86_FCS: + case UNW_X86_FIP: + case UNW_X86_FEA: + case UNW_X86_FDS: + case UNW_X86_MXCSR: + case UNW_X86_GS: + case UNW_X86_FS: + case UNW_X86_ES: + case UNW_X86_DS: + case UNW_X86_SS: + case UNW_X86_CS: + case UNW_X86_TSS: + case UNW_X86_LDT: + loc = x86_scratch_loc (c, reg); + break; + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + struct dwarf_loc loc = DWARF_NULL_LOC; + + switch (reg) + { + case UNW_X86_ST0: + loc = c->dwarf.loc[ST0]; + break; + + /* stacked fp registers */ + case UNW_X86_ST1: + case UNW_X86_ST2: + case UNW_X86_ST3: + case UNW_X86_ST4: + case UNW_X86_ST5: + case UNW_X86_ST6: + case UNW_X86_ST7: + /* SSE fp registers */ + case UNW_X86_XMM0: + case UNW_X86_XMM1: + case UNW_X86_XMM2: + case UNW_X86_XMM3: + case UNW_X86_XMM4: + case UNW_X86_XMM5: + case UNW_X86_XMM6: + case UNW_X86_XMM7: + case UNW_X86_XMM0_lo: + case UNW_X86_XMM0_hi: + case UNW_X86_XMM1_lo: + case UNW_X86_XMM1_hi: + case UNW_X86_XMM2_lo: + case UNW_X86_XMM2_hi: + case UNW_X86_XMM3_lo: + case UNW_X86_XMM3_hi: + case UNW_X86_XMM4_lo: + case UNW_X86_XMM4_hi: + case UNW_X86_XMM5_lo: + case UNW_X86_XMM5_hi: + case UNW_X86_XMM6_lo: + case UNW_X86_XMM6_hi: + case UNW_X86_XMM7_lo: + case UNW_X86_XMM7_hi: + loc = x86_scratch_loc (c, reg); + break; + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); +} diff --git a/src/libs/libunwind/x86/Gresume.c b/src/libs/libunwind/x86/Gresume.c new file mode 100644 index 0000000000..cb3fb31e20 --- /dev/null +++ b/src/libs/libunwind/x86/Gresume.c @@ -0,0 +1,82 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" +#include "offsets.h" + +/* This routine is responsible for copying the register values in + cursor C and establishing them as the current machine state. */ + +static inline int +establish_machine_state (struct cursor *c) +{ + int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, + int write, void *); + int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, + int write, void *); + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + access_reg = as->acc.access_reg; + access_fpreg = as->acc.access_fpreg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + (*access_fpreg) (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + (*access_reg) (as, reg, &val, 1, arg); + } + } + return 0; +} + +PROTECTED int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if ((ret = establish_machine_state (c)) < 0) + return ret; + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/libs/libunwind/x86/Gstep.c b/src/libs/libunwind/x86/Gstep.c new file mode 100644 index 0000000000..10e2cbc801 --- /dev/null +++ b/src/libs/libunwind/x86/Gstep.c @@ -0,0 +1,116 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +PROTECTED int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret, i; + + Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip); + + /* Try DWARF-based unwinding... */ + ret = dwarf_step (&c->dwarf); + + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + if (unlikely (ret < 0)) + { + /* DWARF failed, let's see if we can follow the frame-chain + or skip over the signal trampoline. */ + struct dwarf_loc ebp_loc, eip_loc; + + /* We could get here because of missing/bad unwind information. + Validate all addresses before dereferencing. */ + c->validate = 1; + + Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); + + if (unw_is_signal_frame (cursor)) + { + ret = unw_handle_signal_frame(cursor); + if (ret < 0) + { + Debug (2, "returning 0\n"); + return 0; + } + } + else + { + ret = dwarf_get (&c->dwarf, c->dwarf.loc[EBP], &c->dwarf.cfa); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + Debug (13, "[EBP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EBP]), + c->dwarf.cfa); + + ebp_loc = DWARF_LOC (c->dwarf.cfa, 0); + eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0); + c->dwarf.cfa += 8; + + /* Mark all registers unsaved, since we don't know where + they are saved (if at all), except for the EBP and + EIP. */ + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + c->dwarf.loc[EBP] = ebp_loc; + c->dwarf.loc[EIP] = eip_loc; + c->dwarf.use_prev_instr = 1; + } + c->dwarf.ret_addr_column = EIP; + + if (!DWARF_IS_NULL_LOC (c->dwarf.loc[EBP])) + { + ret = dwarf_get (&c->dwarf, c->dwarf.loc[EIP], &c->dwarf.ip); + if (ret < 0) + { + Debug (13, "dwarf_get([EIP=0x%x]) failed\n", DWARF_GET_LOC (c->dwarf.loc[EIP])); + Debug (2, "returning %d\n", ret); + return ret; + } + else + { + Debug (13, "[EIP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EIP]), + c->dwarf.ip); + } + } + else + c->dwarf.ip = 0; + } + ret = (c->dwarf.ip == 0) ? 0 : 1; + Debug (2, "returning %d\n", ret); + return ret; +} diff --git a/src/libs/libunwind/x86/Lcreate_addr_space.c b/src/libs/libunwind/x86/Lcreate_addr_space.c new file mode 100644 index 0000000000..0f2dc6be90 --- /dev/null +++ b/src/libs/libunwind/x86/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/libs/libunwind/x86/Lget_proc_info.c b/src/libs/libunwind/x86/Lget_proc_info.c new file mode 100644 index 0000000000..69028b019f --- /dev/null +++ b/src/libs/libunwind/x86/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/libs/libunwind/x86/Lget_save_loc.c b/src/libs/libunwind/x86/Lget_save_loc.c new file mode 100644 index 0000000000..9ea048a907 --- /dev/null +++ b/src/libs/libunwind/x86/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/libs/libunwind/x86/Lglobal.c b/src/libs/libunwind/x86/Lglobal.c new file mode 100644 index 0000000000..6d7b489e14 --- /dev/null +++ b/src/libs/libunwind/x86/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/libs/libunwind/x86/Linit.c b/src/libs/libunwind/x86/Linit.c new file mode 100644 index 0000000000..e9abfdd46a --- /dev/null +++ b/src/libs/libunwind/x86/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/libs/libunwind/x86/Linit_local.c b/src/libs/libunwind/x86/Linit_local.c new file mode 100644 index 0000000000..68a1687e85 --- /dev/null +++ b/src/libs/libunwind/x86/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/libs/libunwind/x86/Linit_remote.c b/src/libs/libunwind/x86/Linit_remote.c new file mode 100644 index 0000000000..58cb04ab7c --- /dev/null +++ b/src/libs/libunwind/x86/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/libs/libunwind/x86/Los-freebsd.c b/src/libs/libunwind/x86/Los-freebsd.c new file mode 100644 index 0000000000..a75a205df1 --- /dev/null +++ b/src/libs/libunwind/x86/Los-freebsd.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-freebsd.c" +#endif diff --git a/src/libs/libunwind/x86/Los-linux.c b/src/libs/libunwind/x86/Los-linux.c new file mode 100644 index 0000000000..3cc18aabcc --- /dev/null +++ b/src/libs/libunwind/x86/Los-linux.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-linux.c" +#endif diff --git a/src/libs/libunwind/x86/Lregs.c b/src/libs/libunwind/x86/Lregs.c new file mode 100644 index 0000000000..2c9c75cd7d --- /dev/null +++ b/src/libs/libunwind/x86/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/libs/libunwind/x86/Lresume.c b/src/libs/libunwind/x86/Lresume.c new file mode 100644 index 0000000000..41a8cf003d --- /dev/null +++ b/src/libs/libunwind/x86/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/libs/libunwind/x86/Lstep.c b/src/libs/libunwind/x86/Lstep.c new file mode 100644 index 0000000000..c1ac3c7547 --- /dev/null +++ b/src/libs/libunwind/x86/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/libs/libunwind/x86/getcontext-freebsd.S b/src/libs/libunwind/x86/getcontext-freebsd.S new file mode 100644 index 0000000000..670eff1ae1 --- /dev/null +++ b/src/libs/libunwind/x86/getcontext-freebsd.S @@ -0,0 +1,112 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" + + .global _Ux86_getcontext + .type _Ux86_getcontext, @function +_Ux86_getcontext: + .cfi_startproc + pushl %eax + .cfi_adjust_cfa_offset 4 + mov 8(%esp),%eax /* ucontext_t* */ + popl FREEBSD_UC_MCONTEXT_EAX_OFF(%eax) + .cfi_adjust_cfa_offset 4 + movl %ebx, FREEBSD_UC_MCONTEXT_EBX_OFF(%eax) + movl %ecx, FREEBSD_UC_MCONTEXT_ECX_OFF(%eax) + movl %edx, FREEBSD_UC_MCONTEXT_EDX_OFF(%eax) + movl %edi, FREEBSD_UC_MCONTEXT_EDI_OFF(%eax) + movl %esi, FREEBSD_UC_MCONTEXT_ESI_OFF(%eax) + movl %ebp, FREEBSD_UC_MCONTEXT_EBP_OFF(%eax) + + movl (%esp), %ecx + movl %ecx, FREEBSD_UC_MCONTEXT_EIP_OFF(%eax) + + leal 4(%esp), %ecx /* Exclude the return address. */ + movl %ecx, FREEBSD_UC_MCONTEXT_ESP_OFF(%eax) + + xorl %ecx, %ecx + movw %fs, %cx + movl %ecx, FREEBSD_UC_MCONTEXT_FS_OFF(%eax) + movw %gs, %cx + movl %ecx, FREEBSD_UC_MCONTEXT_GS_OFF(%eax) + movw %ds, %cx + movl %ecx, FREEBSD_UC_MCONTEXT_DS_OFF(%eax) + movw %es, %cx + movl %ecx, FREEBSD_UC_MCONTEXT_ES_OFF(%eax) + movw %ss, %cx + movl %ecx, FREEBSD_UC_MCONTEXT_SS_OFF(%eax) + movw %cs, %cx + movl %ecx, FREEBSD_UC_MCONTEXT_CS_OFF(%eax) + + pushfl + .cfi_adjust_cfa_offset 4 + popl FREEBSD_UC_MCONTEXT_EFLAGS_OFF(%eax) + .cfi_adjust_cfa_offset -4 + + movl $0, FREEBSD_UC_MCONTEXT_TRAPNO_OFF(%eax) + + movl $FREEBSD_UC_MCONTEXT_FPOWNED_FPU,\ + FREEBSD_UC_MCONTEXT_OWNEDFP_OFF(%eax) + movl $FREEBSD_UC_MCONTEXT_FPFMT_XMM,\ + FREEBSD_UC_MCONTEXT_FPFORMAT_OFF(%eax) + + /* + * Require CPU with fxsave implemented, and enabled by OS. + * + * If passed ucontext is not aligned to 16-byte boundary, + * save fpu context into temporary aligned location on stack + * and then copy. + */ + leal FREEBSD_UC_MCONTEXT_FPSTATE_OFF(%eax), %edx + testl $0xf, %edx + jne 2f + fxsave (%edx) /* fast path, passed ucontext save area was aligned */ +1: movl $FREEBSD_UC_MCONTEXT_MC_LEN_VAL,\ + FREEBSD_UC_MCONTEXT_MC_LEN_OFF(%eax) + + xorl %eax, %eax + ret + +2: movl %edx, %edi /* not aligned, do the dance */ + subl $512 + 16, %esp /* save area and 16 bytes for alignment */ + .cfi_adjust_cfa_offset 512 + 16 + movl %esp, %edx + orl $0xf, %edx /* align *%edx to 16-byte up */ + incl %edx + fxsave (%edx) + movl %edx, %esi /* copy to the final destination */ + movl $512/4,%ecx + rep; movsl + addl $512 + 16, %esp /* restore the stack */ + .cfi_adjust_cfa_offset -512 - 16 + movl FREEBSD_UC_MCONTEXT_ESI_OFF(%eax), %esi + movl FREEBSD_UC_MCONTEXT_EDI_OFF(%eax), %edi + jmp 1b + + .cfi_endproc + .size _Ux86_getcontext, . - _Ux86_getcontext + + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/libs/libunwind/x86/getcontext-linux.S b/src/libs/libunwind/x86/getcontext-linux.S new file mode 100644 index 0000000000..c469dadbac --- /dev/null +++ b/src/libs/libunwind/x86/getcontext-linux.S @@ -0,0 +1,74 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2009 Google, Inc + Contributed by Paul Pluzhnikov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" + +/* int _Ux86_getcontext (ucontext_t *ucp) + + Saves the machine context in UCP necessary for libunwind. + Unlike the libc implementation, we don't save the signal mask + and hence avoid the cost of a system call per unwind. + +*/ + + .global _Ux86_getcontext + .type _Ux86_getcontext, @function +_Ux86_getcontext: + .cfi_startproc + mov 4(%esp),%eax /* ucontext_t* */ + + /* EAX is not preserved. */ + movl $0, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EAX_OFF)(%eax) + + movl %ebx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EBX_OFF)(%eax) + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ECX_OFF)(%eax) + movl %edx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EDX_OFF)(%eax) + movl %edi, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EDI_OFF)(%eax) + movl %esi, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ESI_OFF)(%eax) + movl %ebp, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EBP_OFF)(%eax) + + movl (%esp), %ecx + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EIP_OFF)(%eax) + + leal 4(%esp), %ecx /* Exclude the return address. */ + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ESP_OFF)(%eax) + + /* glibc getcontext saves FS, but not GS */ + xorl %ecx, %ecx + movw %fs, %cx + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FS_OFF)(%eax) + + leal LINUX_UC_FPREGS_MEM_OFF(%eax), %ecx + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FPSTATE_OFF)(%eax) + fnstenv (%ecx) + fldenv (%ecx) + + xor %eax, %eax + ret + .cfi_endproc + .size _Ux86_getcontext, . - _Ux86_getcontext + + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/libs/libunwind/x86/init.h b/src/libs/libunwind/x86/init.h new file mode 100644 index 0000000000..027aedc345 --- /dev/null +++ b/src/libs/libunwind/x86/init.h @@ -0,0 +1,70 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret, i; + + c->dwarf.loc[EAX] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EAX); + c->dwarf.loc[ECX] = DWARF_REG_LOC (&c->dwarf, UNW_X86_ECX); + c->dwarf.loc[EDX] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EDX); + c->dwarf.loc[EBX] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EBX); + c->dwarf.loc[ESP] = DWARF_REG_LOC (&c->dwarf, UNW_X86_ESP); + c->dwarf.loc[EBP] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EBP); + c->dwarf.loc[ESI] = DWARF_REG_LOC (&c->dwarf, UNW_X86_ESI); + c->dwarf.loc[EDI] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EDI); + c->dwarf.loc[EIP] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EIP); + c->dwarf.loc[EFLAGS] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EFLAGS); + c->dwarf.loc[TRAPNO] = DWARF_REG_LOC (&c->dwarf, UNW_X86_TRAPNO); + c->dwarf.loc[ST0] = DWARF_REG_LOC (&c->dwarf, UNW_X86_ST0); + for (i = ST0 + 1; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[EIP], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_X86_ESP), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = X86_SCF_NONE; + c->sigcontext_addr = 0; + + c->dwarf.args_size = 0; + c->dwarf.ret_addr_column = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/libs/libunwind/x86/is_fpreg.c b/src/libs/libunwind/x86/is_fpreg.c new file mode 100644 index 0000000000..addf9bcafc --- /dev/null +++ b/src/libs/libunwind/x86/is_fpreg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED int +unw_is_fpreg (int regnum) +{ + return ((regnum >= UNW_X86_ST0 && regnum <= UNW_X86_ST7) + || (regnum >= UNW_X86_XMM0_lo && regnum <= UNW_X86_XMM7_hi) + || (regnum >= UNW_X86_XMM0 && regnum <= UNW_X86_XMM7)); +} diff --git a/src/libs/libunwind/x86/longjmp.S b/src/libs/libunwind/x86/longjmp.S new file mode 100644 index 0000000000..05173d0c10 --- /dev/null +++ b/src/libs/libunwind/x86/longjmp.S @@ -0,0 +1,39 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + .globl _UI_longjmp_cont + + .type _UI_longjmp_cont, @function +_UI_longjmp_cont: + .cfi_startproc + .cfi_register 8, 0 /* IP saved in EAX */ + push %eax /* push target IP as return address */ + .cfi_restore 8 + mov %edx, %eax /* set up return-value */ + ret + .cfi_endproc + .size _UI_siglongjmp_cont, .-_UI_longjmp_cont + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/libs/libunwind/x86/offsets.h b/src/libs/libunwind/x86/offsets.h new file mode 100644 index 0000000000..e5aec7f588 --- /dev/null +++ b/src/libs/libunwind/x86/offsets.h @@ -0,0 +1,140 @@ +/* Linux-specific definitions: */ + +/* Define various structure offsets to simplify cross-compilation. */ + +/* Offsets for x86 Linux "ucontext_t": */ + +#define LINUX_UC_FLAGS_OFF 0x00 +#define LINUX_UC_LINK_OFF 0x04 +#define LINUX_UC_STACK_OFF 0x08 +#define LINUX_UC_MCONTEXT_OFF 0x14 +#define LINUX_UC_SIGMASK_OFF 0x6c +#define LINUX_UC_FPREGS_MEM_OFF 0xec + +/* The struct sigcontext is located at an offset of 4 + from the stack pointer in the signal frame. */ + +/* Offsets for x86 Linux "struct sigcontext": */ + +#define LINUX_SC_GS_OFF 0x00 +#define LINUX_SC_GSH_OFF 0x02 +#define LINUX_SC_FS_OFF 0x04 +#define LINUX_SC_FSH_OFF 0x06 +#define LINUX_SC_ES_OFF 0x08 +#define LINUX_SC_ESH_OFF 0x0a +#define LINUX_SC_DS_OFF 0x0c +#define LINUX_SC_DSH_OFF 0x0e +#define LINUX_SC_EDI_OFF 0x10 +#define LINUX_SC_ESI_OFF 0x14 +#define LINUX_SC_EBP_OFF 0x18 +#define LINUX_SC_ESP_OFF 0x1c +#define LINUX_SC_EBX_OFF 0x20 +#define LINUX_SC_EDX_OFF 0x24 +#define LINUX_SC_ECX_OFF 0x28 +#define LINUX_SC_EAX_OFF 0x2c +#define LINUX_SC_TRAPNO_OFF 0x30 +#define LINUX_SC_ERR_OFF 0x34 +#define LINUX_SC_EIP_OFF 0x38 +#define LINUX_SC_CS_OFF 0x3c +#define LINUX_SC_CSH_OFF 0x3e +#define LINUX_SC_EFLAGS_OFF 0x40 +#define LINUX_SC_ESP_AT_SIGNAL_OFF 0x44 +#define LINUX_SC_SS_OFF 0x48 +#define LINUX_SC_SSH_OFF 0x4a +#define LINUX_SC_FPSTATE_OFF 0x4c +#define LINUX_SC_OLDMASK_OFF 0x50 +#define LINUX_SC_CR2_OFF 0x54 + +/* Offsets for x86 Linux "struct _fpstate": */ + +#define LINUX_FPSTATE_CW_OFF 0x000 +#define LINUX_FPSTATE_SW_OFF 0x004 +#define LINUX_FPSTATE_TAG_OFF 0x008 +#define LINUX_FPSTATE_IPOFF_OFF 0x00c +#define LINUX_FPSTATE_CSSEL_OFF 0x010 +#define LINUX_FPSTATE_DATAOFF_OFF 0x014 +#define LINUX_FPSTATE_DATASEL_OFF 0x018 +#define LINUX_FPSTATE_ST0_OFF 0x01c +#define LINUX_FPSTATE_ST1_OFF 0x026 +#define LINUX_FPSTATE_ST2_OFF 0x030 +#define LINUX_FPSTATE_ST3_OFF 0x03a +#define LINUX_FPSTATE_ST4_OFF 0x044 +#define LINUX_FPSTATE_ST5_OFF 0x04e +#define LINUX_FPSTATE_ST6_OFF 0x058 +#define LINUX_FPSTATE_ST7_OFF 0x062 +#define LINUX_FPSTATE_STATUS_OFF 0x06c +#define LINUX_FPSTATE_MAGIC_OFF 0x06e +#define LINUX_FPSTATE_FXSR_ENV_OFF 0x070 +#define LINUX_FPSTATE_MXCSR_OFF 0x088 +#define LINUX_FPSTATE_FXSR_ST0_OFF 0x090 +#define LINUX_FPSTATE_FXSR_ST1_OFF 0x0a0 +#define LINUX_FPSTATE_FXSR_ST2_OFF 0x0b0 +#define LINUX_FPSTATE_FXSR_ST3_OFF 0x0c0 +#define LINUX_FPSTATE_FXSR_ST4_OFF 0x0d0 +#define LINUX_FPSTATE_FXSR_ST5_OFF 0x0e0 +#define LINUX_FPSTATE_FXSR_ST6_OFF 0x0f0 +#define LINUX_FPSTATE_FXSR_ST7_OFF 0x100 +#define LINUX_FPSTATE_XMM0_OFF 0x110 +#define LINUX_FPSTATE_XMM1_OFF 0x120 +#define LINUX_FPSTATE_XMM2_OFF 0x130 +#define LINUX_FPSTATE_XMM3_OFF 0x140 +#define LINUX_FPSTATE_XMM4_OFF 0x150 +#define LINUX_FPSTATE_XMM5_OFF 0x160 +#define LINUX_FPSTATE_XMM6_OFF 0x170 +#define LINUX_FPSTATE_XMM7_OFF 0x180 + +/* FreeBSD-specific definitions: */ + +#define FREEBSD_SC_UCONTEXT_OFF 0x20 +#define FREEBSD_UC_MCONTEXT_OFF 0x10 + +#define FREEBSD_UC_MCONTEXT_GS_OFF 0x14 +#define FREEBSD_UC_MCONTEXT_FS_OFF 0x18 +#define FREEBSD_UC_MCONTEXT_ES_OFF 0x1c +#define FREEBSD_UC_MCONTEXT_DS_OFF 0x20 +#define FREEBSD_UC_MCONTEXT_EDI_OFF 0x24 +#define FREEBSD_UC_MCONTEXT_ESI_OFF 0x28 +#define FREEBSD_UC_MCONTEXT_EBP_OFF 0x2c +#define FREEBSD_UC_MCONTEXT_EBX_OFF 0x34 +#define FREEBSD_UC_MCONTEXT_EDX_OFF 0x38 +#define FREEBSD_UC_MCONTEXT_ECX_OFF 0x3c +#define FREEBSD_UC_MCONTEXT_EAX_OFF 0x40 +#define FREEBSD_UC_MCONTEXT_TRAPNO_OFF 0x44 +#define FREEBSD_UC_MCONTEXT_EIP_OFF 0x4c +#define FREEBSD_UC_MCONTEXT_ESP_OFF 0x58 +#define FREEBSD_UC_MCONTEXT_CS_OFF 0x50 +#define FREEBSD_UC_MCONTEXT_EFLAGS_OFF 0x54 +#define FREEBSD_UC_MCONTEXT_SS_OFF 0x5c +#define FREEBSD_UC_MCONTEXT_MC_LEN_OFF 0x60 +#define FREEBSD_UC_MCONTEXT_FPFORMAT_OFF 0x64 +#define FREEBSD_UC_MCONTEXT_OWNEDFP_OFF 0x68 +#define FREEBSD_UC_MCONTEXT_FPSTATE_OFF 0x70 + +#define FREEBSD_UC_MCONTEXT_CW_OFF 0x70 +#define FREEBSD_UC_MCONTEXT_SW_OFF 0x74 +#define FREEBSD_UC_MCONTEXT_TAG_OFF 0x78 +#define FREEBSD_UC_MCONTEXT_IPOFF_OFF 0x7c +#define FREEBSD_UC_MCONTEXT_CSSEL_OFF 0x80 +#define FREEBSD_UC_MCONTEXT_DATAOFF_OFF 0x84 +#define FREEBSD_US_MCONTEXT_DATASEL_OFF 0x88 +#define FREEBSD_UC_MCONTEXT_ST0_OFF 0x8c + +#define FREEBSD_UC_MCONTEXT_CW_XMM_OFF 0x70 +#define FREEBSD_UC_MCONTEXT_SW_XMM_OFF 0x72 +#define FREEBSD_UC_MCONTEXT_TAG_XMM_OFF 0x74 +#define FREEBSD_UC_MCONTEXT_IPOFF_XMM_OFF 0x78 +#define FREEBSD_UC_MCONTEXT_CSSEL_XMM_OFF 0x7c +#define FREEBSD_UC_MCONTEXT_DATAOFF_XMM_OFF 0x80 +#define FREEBSD_US_MCONTEXT_DATASEL_XMM_OFF 0x84 +#define FREEBSD_UC_MCONTEXT_MXCSR_XMM_OFF 0x88 +#define FREEBSD_UC_MCONTEXT_ST0_XMM_OFF 0x90 +#define FREEBSD_UC_MCONTEXT_XMM0_OFF 0x110 + +#define FREEBSD_UC_MCONTEXT_MC_LEN_VAL 0x280 +#define FREEBSD_UC_MCONTEXT_FPFMT_NODEV 0x10000 +#define FREEBSD_UC_MCONTEXT_FPFMT_387 0x10001 +#define FREEBSD_UC_MCONTEXT_FPFMT_XMM 0x10002 +#define FREEBSD_UC_MCONTEXT_FPOWNED_NONE 0x20000 +#define FREEBSD_UC_MCONTEXT_FPOWNED_FPU 0x20001 +#define FREEBSD_UC_MCONTEXT_FPOWNED_PCB 0x20002 + diff --git a/src/libs/libunwind/x86/regname.c b/src/libs/libunwind/x86/regname.c new file mode 100644 index 0000000000..2228510a21 --- /dev/null +++ b/src/libs/libunwind/x86/regname.c @@ -0,0 +1,27 @@ +#include "unwind_i.h" + +static const char *regname[] = + { + "eax", "edx", "ecx", "ebx", "esi", "edi", "ebp", "esp", "eip", + "eflags", "trapno", + "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7", + "fcw", "fsw", "ftw", "fop", "fcs", "fip", "fea", "fds", + "xmm0_lo", "xmm0_hi", "xmm1_lo", "xmm1_hi", + "xmm2_lo", "xmm2_hi", "xmm3_lo", "xmm3_hi", + "xmm4_lo", "xmm4_hi", "xmm5_lo", "xmm5_hi", + "xmm6_lo", "xmm6_hi", "xmm7_lo", "xmm7_hi", + "mxcsr", + "gs", "fs", "es", "ds", "ss", "cs", + "tss", "ldt", + "cfi", + "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", + }; + +PROTECTED const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/libs/libunwind/x86/siglongjmp.S b/src/libs/libunwind/x86/siglongjmp.S new file mode 100644 index 0000000000..32bba3b3b6 --- /dev/null +++ b/src/libs/libunwind/x86/siglongjmp.S @@ -0,0 +1,92 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + Copyright (C) 2011 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + .globl _UI_siglongjmp_cont + +#if defined(__linux__) +#define SIG_SETMASK 2 +#elif defined(__FreeBSD__) +#define SIG_SETMASK 3 +#endif + + /* Stack layout at this point: + + +------------+ <- original $esp (at time of setjmp() call) + | sigmask[1] | + +------------+ + | sigmask[0] | + +------------+ + */ + + .type _UI_siglongjmp_cont, @function +_UI_siglongjmp_cont: + .cfi_startproc +#ifdef __linux__ + .cfi_register 8, 0 /* IP saved in EAX */ + .cfi_def_cfa_offset 8 + mov %esp, %ecx /* pass address of signal mask in 3rd sc arg */ + push %eax /* save target IP */ + .cfi_adjust_cfa_offset 4 + .cfi_offset 8, -12 + push %edx /* save return value */ + .cfi_adjust_cfa_offset 4 + push %ebx /* save %ebx (preserved) */ + .cfi_adjust_cfa_offset 4 + .cfi_offset 3, -20 + mov $SIG_SETMASK, %ebx /* 1st syscall arg (how) */ + xor %edx, %edx /* pass NULL as 3rd syscall arg (old maskp) */ + int $0x80 + pop %ebx /* restore %ebx */ + .cfi_adjust_cfa_offset -4 + .cfi_restore 3 + pop %eax /* fetch return value */ + .cfi_adjust_cfa_offset -4 + pop %edx /* pop target IP */ + .cfi_adjust_cfa_offset -4 + .cfi_register 8, 2 /* saved IP is now n EDX */ + lea 8(%esp), %esp /* pop sigmask */ + .cfi_adjust_cfa_offset -4 + jmp *%edx +#elif defined(__FreeBSD__) + pushl %eax + pushl %edx + pushl $0 + pushl %ecx + pushl $SIG_SETMASK + movl $340,%eax + pushl %eax + int $0x80 + addl $16,%esp + popl %eax + popl %edx + jmp *%edx +#else +#error Port me +#endif + .cfi_endproc + .size _UI_siglongjmp_cont, .-_UI_siglongjmp_cont + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/libs/libunwind/x86/unwind_i.h b/src/libs/libunwind/x86/unwind_i.h new file mode 100644 index 0000000000..cd52824226 --- /dev/null +++ b/src/libs/libunwind/x86/unwind_i.h @@ -0,0 +1,63 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include + +#include + +#include "libunwind_i.h" + +/* DWARF column numbers: */ +#define EAX 0 +#define ECX 1 +#define EDX 2 +#define EBX 3 +#define ESP 4 +#define EBP 5 +#define ESI 6 +#define EDI 7 +#define EIP 8 +#define EFLAGS 9 +#define TRAPNO 10 +#define ST0 11 + +#define x86_lock UNW_OBJ(lock) +#define x86_local_resume UNW_OBJ(local_resume) +#define x86_local_addr_space_init UNW_OBJ(local_addr_space_init) +#define x86_scratch_loc UNW_OBJ(scratch_loc) +#define x86_get_scratch_loc UNW_OBJ(get_scratch_loc) +#define x86_r_uc_addr UNW_OBJ(r_uc_addr) + +extern void x86_local_addr_space_init (void); +extern int x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); +extern dwarf_loc_t x86_scratch_loc (struct cursor *c, unw_regnum_t reg); +extern dwarf_loc_t x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg); +extern void *x86_r_uc_addr (ucontext_t *uc, int reg); + +#endif /* unwind_i_h */ diff --git a/src/libs/libunwind/x86_64/Gcreate_addr_space.c b/src/libs/libunwind/x86_64/Gcreate_addr_space.c new file mode 100644 index 0000000000..38ee5afb20 --- /dev/null +++ b/src/libs/libunwind/x86_64/Gcreate_addr_space.c @@ -0,0 +1,61 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#if defined(_LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN) +#define __LITTLE_ENDIAN _LITTLE_ENDIAN +#endif + +PROTECTED unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * x86_64 supports only little-endian. + */ + if (byte_order != 0 && byte_order != __LITTLE_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + return as; +#endif +} diff --git a/src/libs/libunwind/x86_64/Gget_proc_info.c b/src/libs/libunwind/x86_64/Gget_proc_info.c new file mode 100644 index 0000000000..8def62d2a6 --- /dev/null +++ b/src/libs/libunwind/x86_64/Gget_proc_info.c @@ -0,0 +1,48 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + + if (dwarf_make_proc_info (&c->dwarf) < 0) + { + /* On x86-64, some key routines such as _start() and _dl_start() + are missing DWARF unwind info. We don't want to fail in that + case, because those frames are uninteresting and just mark + the end of the frame-chain anyhow. */ + memset (pi, 0, sizeof (*pi)); + pi->start_ip = c->dwarf.ip; + pi->end_ip = c->dwarf.ip + 1; + return 0; + } + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/libs/libunwind/x86_64/Gget_save_loc.c b/src/libs/libunwind/x86_64/Gget_save_loc.c new file mode 100644 index 0000000000..b48fa91848 --- /dev/null +++ b/src/libs/libunwind/x86_64/Gget_save_loc.c @@ -0,0 +1,73 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + + switch (reg) + { + case UNW_X86_64_RBX: loc = c->dwarf.loc[RBX]; break; + case UNW_X86_64_RSP: loc = c->dwarf.loc[RSP]; break; + case UNW_X86_64_RBP: loc = c->dwarf.loc[RBP]; break; + case UNW_X86_64_R12: loc = c->dwarf.loc[R12]; break; + case UNW_X86_64_R13: loc = c->dwarf.loc[R13]; break; + case UNW_X86_64_R14: loc = c->dwarf.loc[R14]; break; + case UNW_X86_64_R15: loc = c->dwarf.loc[R15]; break; + + default: + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/libs/libunwind/x86_64/Gglobal.c b/src/libs/libunwind/x86_64/Gglobal.c new file mode 100644 index 0000000000..8d1fbb4b0a --- /dev/null +++ b/src/libs/libunwind/x86_64/Gglobal.c @@ -0,0 +1,102 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "config.h" +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (x86_64_lock); +HIDDEN int tdep_init_done; + +/* See comments for svr4_dbx_register_map[] in gcc/config/i386/i386.c. */ + +HIDDEN const uint8_t dwarf_to_unw_regnum_map[DWARF_NUM_PRESERVED_REGS] = + { + UNW_X86_64_RAX, + UNW_X86_64_RDX, + UNW_X86_64_RCX, + UNW_X86_64_RBX, + UNW_X86_64_RSI, + UNW_X86_64_RDI, + UNW_X86_64_RBP, + UNW_X86_64_RSP, + UNW_X86_64_R8, + UNW_X86_64_R9, + UNW_X86_64_R10, + UNW_X86_64_R11, + UNW_X86_64_R12, + UNW_X86_64_R13, + UNW_X86_64_R14, + UNW_X86_64_R15, + UNW_X86_64_RIP, +#ifdef CONFIG_MSABI_SUPPORT + UNW_X86_64_XMM0, + UNW_X86_64_XMM1, + UNW_X86_64_XMM2, + UNW_X86_64_XMM3, + UNW_X86_64_XMM4, + UNW_X86_64_XMM5, + UNW_X86_64_XMM6, + UNW_X86_64_XMM7, + UNW_X86_64_XMM8, + UNW_X86_64_XMM9, + UNW_X86_64_XMM10, + UNW_X86_64_XMM11, + UNW_X86_64_XMM12, + UNW_X86_64_XMM13, + UNW_X86_64_XMM14, + UNW_X86_64_XMM15 +#endif + }; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&x86_64_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + + tdep_init_mem_validate (); + +#ifndef UNW_REMOTE_ONLY + x86_64_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&x86_64_lock, saved_mask); +} diff --git a/src/libs/libunwind/x86_64/Ginit.c b/src/libs/libunwind/x86_64/Ginit.c new file mode 100644 index 0000000000..480d470b2c --- /dev/null +++ b/src/libs/libunwind/x86_64/Ginit.c @@ -0,0 +1,269 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +PROTECTED unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space; + +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; + return 0; +} + +#define PAGE_SIZE 4096 +#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) + +static int (*mem_validate_func) (void *addr, size_t len); +static int msync_validate (void *addr, size_t len) +{ + return msync (addr, len, MS_ASYNC); +} + +#ifdef HAVE_MINCORE +static int mincore_validate (void *addr, size_t len) +{ + unsigned char mvec[2]; /* Unaligned access may cross page boundary */ + return mincore (addr, len, mvec); +} +#endif + +/* Initialise memory validation method. On linux kernels <2.6.21, + mincore() returns incorrect value for MAP_PRIVATE mappings, + such as stacks. If mincore() was available at compile time, + check if we can actually use it. If not, use msync() instead. */ +HIDDEN void +tdep_init_mem_validate (void) +{ +#ifdef HAVE_MINCORE + unsigned char present = 1; + if (mincore (&present, 1, &present) == 0) + { + Debug(1, "using mincore to validate memory\n"); + mem_validate_func = mincore_validate; + } + else +#endif + { + Debug(1, "using msync to validate memory\n"); + mem_validate_func = msync_validate; + } +} + +/* Cache of already validated addresses */ +#define NLGA 4 +static unw_word_t last_good_addr[NLGA]; +static int lga_victim; + +static int +validate_mem (unw_word_t addr) +{ + int i, victim; + size_t len; + + if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) + len = PAGE_SIZE; + else + len = PAGE_SIZE * 2; + + addr = PAGE_START(addr); + + if (addr == 0) + return -1; + + for (i = 0; i < NLGA; i++) + { + if (last_good_addr[i] && (addr == last_good_addr[i])) + return 0; + } + + if (mem_validate_func ((void *) addr, len) == -1) + return -1; + + victim = lga_victim; + for (i = 0; i < NLGA; i++) { + if (!last_good_addr[victim]) { + last_good_addr[victim++] = addr; + return 0; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + last_good_addr[victim] = addr; + victim = (victim + 1) % NLGA; + lga_victim = victim; + + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (unlikely (write)) + { + Debug (16, "mem[%016lx] <- %lx\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + /* validate address */ + const struct cursor *c = (const struct cursor *)arg; + if (likely (c != NULL) && unlikely (c->validate) + && unlikely (validate_mem (addr))) + return -1; + *val = *(unw_word_t *) addr; + Debug (16, "mem[%016lx] -> %lx\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = ((struct cursor *)arg)->uc; + + if (unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = x86_64_r_uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- 0x%016lx\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> 0x%016lx\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = ((struct cursor *)arg)->uc; + unw_fpreg_t *addr; + + if (!unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = x86_64_r_uc_addr (uc, reg))) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +x86_64_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = x86_64_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); + + memset (last_good_addr, 0, sizeof (unw_word_t) * NLGA); + lga_victim = 0; +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/x86_64/Ginit_local.c b/src/libs/libunwind/x86_64/Ginit_local.c new file mode 100644 index 0000000000..079938963e --- /dev/null +++ b/src/libs/libunwind/x86_64/Ginit_local.c @@ -0,0 +1,58 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + struct cursor *c = (struct cursor *) cursor; + + if (unlikely (!tdep_init_done)) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = c; + c->uc = uc; + c->validate = 0; + return common_init (c, 1); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libs/libunwind/x86_64/Ginit_remote.c b/src/libs/libunwind/x86_64/Ginit_remote.c new file mode 100644 index 0000000000..f3b7bb97c9 --- /dev/null +++ b/src/libs/libunwind/x86_64/Ginit_remote.c @@ -0,0 +1,57 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +PROTECTED int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + if (as == unw_local_addr_space) + { + c->dwarf.as_arg = c; + c->uc = as_arg; + } + else + { + c->dwarf.as_arg = as_arg; + c->uc = NULL; + } + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/libs/libunwind/x86_64/Gos-freebsd.c b/src/libs/libunwind/x86_64/Gos-freebsd.c new file mode 100644 index 0000000000..e7e8da137d --- /dev/null +++ b/src/libs/libunwind/x86_64/Gos-freebsd.c @@ -0,0 +1,200 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include "unwind_i.h" +#include "ucontext_i.h" + +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + /* XXXKIB */ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, w2, b0, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors (as); + arg = c->dwarf.as_arg; + + /* Check if RIP points at sigreturn sequence. +48 8d 7c 24 10 lea SIGF_UC(%rsp),%rdi +6a 00 pushq $0 +48 c7 c0 a1 01 00 00 movq $SYS_sigreturn,%rax +0f 05 syscall +f4 0: hlt +eb fd jmp 0b + */ + + ip = c->dwarf.ip; + c->sigcontext_format = X86_64_SCF_NONE; + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 16, &w2, 0, arg)) < 0) + return 0; + w2 &= 0xffffff; + if (w0 == 0x48006a10247c8d48 && + w1 == 0x050f000001a1c0c7 && + w2 == 0x0000000000fdebf4) + { + c->sigcontext_format = X86_64_SCF_FREEBSD_SIGFRAME; + return (c->sigcontext_format); + } + /* Check if RIP points at standard syscall sequence. +49 89 ca mov %rcx,%r10 +0f 05 syscall + */ + if ((ret = (*a->access_mem) (as, ip - 5, &b0, 0, arg)) < 0) + return (0); + Debug (12, "b0 0x%lx\n", b0); + if ((b0 & 0xffffffffffffff) == 0x050fca89490000 || + (b0 & 0xffffffffff) == 0x050fca8949) + { + c->sigcontext_format = X86_64_SCF_FREEBSD_SYSCALL; + return (c->sigcontext_format); + } + return (X86_64_SCF_NONE); +} + +PROTECTED int +unw_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t ucontext; + int ret; + + if (c->sigcontext_format == X86_64_SCF_FREEBSD_SIGFRAME) + { + ucontext = c->dwarf.cfa + offsetof(struct sigframe, sf_uc); + c->sigcontext_addr = c->dwarf.cfa; + Debug(1, "signal frame, skip over trampoline\n"); + + struct dwarf_loc rsp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); + ret = dwarf_get (&c->dwarf, rsp_loc, &c->dwarf.cfa); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + c->dwarf.loc[RAX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RAX, 0); + c->dwarf.loc[RDX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDX, 0); + c->dwarf.loc[RCX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RCX, 0); + c->dwarf.loc[RBX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBX, 0); + c->dwarf.loc[RSI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSI, 0); + c->dwarf.loc[RDI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDI, 0); + c->dwarf.loc[RBP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBP, 0); + c->dwarf.loc[RSP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); + c->dwarf.loc[ R8] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); + c->dwarf.loc[ R9] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); + c->dwarf.loc[R10] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); + c->dwarf.loc[R11] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); + c->dwarf.loc[R12] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); + c->dwarf.loc[R13] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); + c->dwarf.loc[R14] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); + c->dwarf.loc[R15] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); + c->dwarf.loc[RIP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RIP, 0); + + return 0; + } + else if (c->sigcontext_format == X86_64_SCF_FREEBSD_SYSCALL) + { + c->dwarf.loc[RCX] = c->dwarf.loc[R10]; + /* rsp_loc = DWARF_LOC(c->dwarf.cfa - 8, 0); */ + /* rbp_loc = c->dwarf.loc[RBP]; */ + c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); + Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n", + (unsigned long long) DWARF_GET_LOC (c->dwarf.loc[RIP]), + (unsigned long long) c->dwarf.ip); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + c->dwarf.cfa += 8; + c->dwarf.use_prev_instr = 1; + return 1; + } + else + return -UNW_EBADFRAME; + +} + +#ifndef UNW_REMOTE_ONLY +HIDDEN void * +x86_64_r_uc_addr (ucontext_t *uc, int reg) +{ + /* NOTE: common_init() in init.h inlines these for fast path access. */ + void *addr; + + switch (reg) + { + case UNW_X86_64_R8: addr = &uc->uc_mcontext.mc_r8; break; + case UNW_X86_64_R9: addr = &uc->uc_mcontext.mc_r9; break; + case UNW_X86_64_R10: addr = &uc->uc_mcontext.mc_r10; break; + case UNW_X86_64_R11: addr = &uc->uc_mcontext.mc_r11; break; + case UNW_X86_64_R12: addr = &uc->uc_mcontext.mc_r12; break; + case UNW_X86_64_R13: addr = &uc->uc_mcontext.mc_r13; break; + case UNW_X86_64_R14: addr = &uc->uc_mcontext.mc_r14; break; + case UNW_X86_64_R15: addr = &uc->uc_mcontext.mc_r15; break; + case UNW_X86_64_RDI: addr = &uc->uc_mcontext.mc_rdi; break; + case UNW_X86_64_RSI: addr = &uc->uc_mcontext.mc_rsi; break; + case UNW_X86_64_RBP: addr = &uc->uc_mcontext.mc_rbp; break; + case UNW_X86_64_RBX: addr = &uc->uc_mcontext.mc_rbx; break; + case UNW_X86_64_RDX: addr = &uc->uc_mcontext.mc_rdx; break; + case UNW_X86_64_RAX: addr = &uc->uc_mcontext.mc_rax; break; + case UNW_X86_64_RCX: addr = &uc->uc_mcontext.mc_rcx; break; + case UNW_X86_64_RSP: addr = &uc->uc_mcontext.mc_rsp; break; + case UNW_X86_64_RIP: addr = &uc->uc_mcontext.mc_rip; break; + + default: + addr = NULL; + } + return addr; +} + +HIDDEN NORETURN void +x86_64_sigreturn (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = (ucontext_t *)(c->sigcontext_addr + + offsetof(struct sigframe, sf_uc)); + + Debug (8, "resuming at ip=%llx via sigreturn(%p)\n", + (unsigned long long) c->dwarf.ip, uc); + sigreturn(uc); + abort(); +} +#endif diff --git a/src/libs/libunwind/x86_64/Gos-linux.c b/src/libs/libunwind/x86_64/Gos-linux.c new file mode 100644 index 0000000000..9e1acfcffb --- /dev/null +++ b/src/libs/libunwind/x86_64/Gos-linux.c @@ -0,0 +1,154 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "ucontext_i.h" + +#include + +HIDDEN void +tdep_fetch_frame (struct dwarf_cursor *dw, unw_word_t ip, int need_unwind_info) +{ + struct cursor *c = (struct cursor *) dw; + assert(! need_unwind_info || dw->pi_valid); + assert(! need_unwind_info || dw->pi.unwind_info); + if (dw->pi_valid + && dw->pi.unwind_info + && ((struct dwarf_cie_info *) dw->pi.unwind_info)->signal_frame) + c->sigcontext_format = X86_64_SCF_LINUX_RT_SIGFRAME; + else + c->sigcontext_format = X86_64_SCF_NONE; + + Debug(5, "fetch frame ip=0x%lx cfa=0x%lx format=%d\n", + dw->ip, dw->cfa, c->sigcontext_format); +} + +HIDDEN void +tdep_cache_frame (struct dwarf_cursor *dw, struct dwarf_reg_state *rs) +{ + struct cursor *c = (struct cursor *) dw; + rs->signal_frame = c->sigcontext_format; + + Debug(5, "cache frame ip=0x%lx cfa=0x%lx format=%d\n", + dw->ip, dw->cfa, c->sigcontext_format); +} + +HIDDEN void +tdep_reuse_frame (struct dwarf_cursor *dw, struct dwarf_reg_state *rs) +{ + struct cursor *c = (struct cursor *) dw; + c->sigcontext_format = rs->signal_frame; + if (c->sigcontext_format == X86_64_SCF_LINUX_RT_SIGFRAME) + { + c->frame_info.frame_type = UNW_X86_64_FRAME_SIGRETURN; + /* Offset from cfa to ucontext_t in signal frame. */ + c->frame_info.cfa_reg_offset = 0; + c->sigcontext_addr = dw->cfa; + } + else + c->sigcontext_addr = 0; + + Debug(5, "reuse frame ip=0x%lx cfa=0x%lx format=%d addr=0x%lx offset=%+d\n", + dw->ip, dw->cfa, c->sigcontext_format, c->sigcontext_addr, + (c->sigcontext_format == X86_64_SCF_LINUX_RT_SIGFRAME + ? c->frame_info.cfa_reg_offset : 0)); +} + +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + return c->sigcontext_format != X86_64_SCF_NONE; +} + +PROTECTED int +unw_handle_signal_frame (unw_cursor_t *cursor) +{ +#if UNW_DEBUG /* To silence compiler warnings */ + /* Should not get here because we now use kernel-provided dwarf + information for the signal trampoline and dwarf_step() works. + Hence unw_step() should never call this function. Maybe + restore old non-dwarf signal handling here, but then the + gating on unw_is_signal_frame() needs to be removed. */ + struct cursor *c = (struct cursor *) cursor; + Debug(1, "old format signal frame? format=%d addr=0x%lx cfa=0x%lx\n", + c->sigcontext_format, c->sigcontext_addr, c->dwarf.cfa); +#endif + return -UNW_EBADFRAME; +} + +#ifndef UNW_REMOTE_ONLY +HIDDEN void * +x86_64_r_uc_addr (ucontext_t *uc, int reg) +{ + /* NOTE: common_init() in init.h inlines these for fast path access. */ + void *addr; + + switch (reg) + { + case UNW_X86_64_R8: addr = &uc->uc_mcontext.gregs[REG_R8]; break; + case UNW_X86_64_R9: addr = &uc->uc_mcontext.gregs[REG_R9]; break; + case UNW_X86_64_R10: addr = &uc->uc_mcontext.gregs[REG_R10]; break; + case UNW_X86_64_R11: addr = &uc->uc_mcontext.gregs[REG_R11]; break; + case UNW_X86_64_R12: addr = &uc->uc_mcontext.gregs[REG_R12]; break; + case UNW_X86_64_R13: addr = &uc->uc_mcontext.gregs[REG_R13]; break; + case UNW_X86_64_R14: addr = &uc->uc_mcontext.gregs[REG_R14]; break; + case UNW_X86_64_R15: addr = &uc->uc_mcontext.gregs[REG_R15]; break; + case UNW_X86_64_RDI: addr = &uc->uc_mcontext.gregs[REG_RDI]; break; + case UNW_X86_64_RSI: addr = &uc->uc_mcontext.gregs[REG_RSI]; break; + case UNW_X86_64_RBP: addr = &uc->uc_mcontext.gregs[REG_RBP]; break; + case UNW_X86_64_RBX: addr = &uc->uc_mcontext.gregs[REG_RBX]; break; + case UNW_X86_64_RDX: addr = &uc->uc_mcontext.gregs[REG_RDX]; break; + case UNW_X86_64_RAX: addr = &uc->uc_mcontext.gregs[REG_RAX]; break; + case UNW_X86_64_RCX: addr = &uc->uc_mcontext.gregs[REG_RCX]; break; + case UNW_X86_64_RSP: addr = &uc->uc_mcontext.gregs[REG_RSP]; break; + case UNW_X86_64_RIP: addr = &uc->uc_mcontext.gregs[REG_RIP]; break; + + default: + addr = NULL; + } + return addr; +} + +/* sigreturn() is a no-op on x86_64 glibc. */ +HIDDEN NORETURN void +x86_64_sigreturn (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + + Debug (8, "resuming at ip=%llx via sigreturn(%p)\n", + (unsigned long long) c->dwarf.ip, sc); + __asm__ __volatile__ ("mov %0, %%rsp;" + "mov %1, %%rax;" + "syscall" + :: "r"(sc), "i"(SYS_rt_sigreturn) + : "memory"); + abort(); +} + +#endif diff --git a/src/libs/libunwind/x86_64/Gos-solaris.c b/src/libs/libunwind/x86_64/Gos-solaris.c new file mode 100644 index 0000000000..6e76446313 --- /dev/null +++ b/src/libs/libunwind/x86_64/Gos-solaris.c @@ -0,0 +1,156 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "ucontext_i.h" + +#include + +HIDDEN void +tdep_fetch_frame (struct dwarf_cursor *dw, unw_word_t ip, int need_unwind_info) +{ + struct cursor *c = (struct cursor *) dw; + assert(! need_unwind_info || dw->pi_valid); + assert(! need_unwind_info || dw->pi.unwind_info); + if (dw->pi_valid + && dw->pi.unwind_info + && ((struct dwarf_cie_info *) dw->pi.unwind_info)->signal_frame) + c->sigcontext_format = X86_64_SCF_LINUX_RT_SIGFRAME; + else + c->sigcontext_format = X86_64_SCF_NONE; + + Debug(5, "fetch frame ip=0x%lx cfa=0x%lx format=%d\n", + dw->ip, dw->cfa, c->sigcontext_format); +} + +HIDDEN void +tdep_cache_frame (struct dwarf_cursor *dw, struct dwarf_reg_state *rs) +{ + struct cursor *c = (struct cursor *) dw; + rs->signal_frame = c->sigcontext_format; + + Debug(5, "cache frame ip=0x%lx cfa=0x%lx format=%d\n", + dw->ip, dw->cfa, c->sigcontext_format); +} + +HIDDEN void +tdep_reuse_frame (struct dwarf_cursor *dw, struct dwarf_reg_state *rs) +{ + struct cursor *c = (struct cursor *) dw; + c->sigcontext_format = rs->signal_frame; + if (c->sigcontext_format == X86_64_SCF_LINUX_RT_SIGFRAME) + { + c->frame_info.frame_type = UNW_X86_64_FRAME_SIGRETURN; + /* Offset from cfa to ucontext_t in signal frame. */ + c->frame_info.cfa_reg_offset = 0; + c->sigcontext_addr = dw->cfa; + } + else + c->sigcontext_addr = 0; + + Debug(5, "reuse frame ip=0x%lx cfa=0x%lx format=%d addr=0x%lx offset=%+d\n", + dw->ip, dw->cfa, c->sigcontext_format, c->sigcontext_addr, + (c->sigcontext_format == X86_64_SCF_LINUX_RT_SIGFRAME + ? c->frame_info.cfa_reg_offset : 0)); +} + +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + return c->sigcontext_format != X86_64_SCF_NONE; +} + +PROTECTED int +unw_handle_signal_frame (unw_cursor_t *cursor) +{ +#if UNW_DEBUG /* To silence compiler warnings */ + /* Should not get here because we now use kernel-provided dwarf + information for the signal trampoline and dwarf_step() works. + Hence unw_step() should never call this function. Maybe + restore old non-dwarf signal handling here, but then the + gating on unw_is_signal_frame() needs to be removed. */ + struct cursor *c = (struct cursor *) cursor; + Debug(1, "old format signal frame? format=%d addr=0x%lx cfa=0x%lx\n", + c->sigcontext_format, c->sigcontext_addr, c->dwarf.cfa); +#endif + return -UNW_EBADFRAME; +} + +#ifndef UNW_REMOTE_ONLY +HIDDEN void * +x86_64_r_uc_addr (ucontext_t *uc, int reg) +{ + /* NOTE: common_init() in init.h inlines these for fast path access. */ + void *addr; + + switch (reg) + { + case UNW_X86_64_R8: addr = &uc->uc_mcontext.gregs[REG_R8]; break; + case UNW_X86_64_R9: addr = &uc->uc_mcontext.gregs[REG_R9]; break; + case UNW_X86_64_R10: addr = &uc->uc_mcontext.gregs[REG_R10]; break; + case UNW_X86_64_R11: addr = &uc->uc_mcontext.gregs[REG_R11]; break; + case UNW_X86_64_R12: addr = &uc->uc_mcontext.gregs[REG_R12]; break; + case UNW_X86_64_R13: addr = &uc->uc_mcontext.gregs[REG_R13]; break; + case UNW_X86_64_R14: addr = &uc->uc_mcontext.gregs[REG_R14]; break; + case UNW_X86_64_R15: addr = &uc->uc_mcontext.gregs[REG_R15]; break; + case UNW_X86_64_RDI: addr = &uc->uc_mcontext.gregs[REG_RDI]; break; + case UNW_X86_64_RSI: addr = &uc->uc_mcontext.gregs[REG_RSI]; break; + case UNW_X86_64_RBP: addr = &uc->uc_mcontext.gregs[REG_RBP]; break; + case UNW_X86_64_RBX: addr = &uc->uc_mcontext.gregs[REG_RBX]; break; + case UNW_X86_64_RDX: addr = &uc->uc_mcontext.gregs[REG_RDX]; break; + case UNW_X86_64_RAX: addr = &uc->uc_mcontext.gregs[REG_RAX]; break; + case UNW_X86_64_RCX: addr = &uc->uc_mcontext.gregs[REG_RCX]; break; + case UNW_X86_64_RSP: addr = &uc->uc_mcontext.gregs[REG_RSP]; break; + case UNW_X86_64_RIP: addr = &uc->uc_mcontext.gregs[REG_RIP]; break; + + default: + addr = NULL; + } + return addr; +} + +/* sigreturn() is a no-op on x86_64 glibc. */ +HIDDEN NORETURN void +x86_64_sigreturn (unw_cursor_t *cursor) +{ +#if 0 + struct cursor *c = (struct cursor *) cursor; + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + + Debug (8, "resuming at ip=%llx via sigreturn(%p)\n", + (unsigned long long) c->dwarf.ip, sc); + __asm__ __volatile__ ("mov %0, %%rsp;" + "mov %1, %%rax;" + "syscall" + :: "r"(sc), "i"(SYS_rt_sigreturn) + : "memory"); +#endif // 0 + abort(); +} + +#endif diff --git a/src/libs/libunwind/x86_64/Gregs.c b/src/libs/libunwind/x86_64/Gregs.c new file mode 100644 index 0000000000..baf8a24f0b --- /dev/null +++ b/src/libs/libunwind/x86_64/Gregs.c @@ -0,0 +1,138 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +#if 0 +static inline dwarf_loc_t +linux_scratch_loc (struct cursor *c, unw_regnum_t reg) +{ + unw_word_t addr = c->sigcontext_addr; + + switch (c->sigcontext_format) + { + case X86_64_SCF_NONE: + return DWARF_REG_LOC (&c->dwarf, reg); + + case X86_64_SCF_LINUX_RT_SIGFRAME: + addr += LINUX_UC_MCONTEXT_OFF; + break; + + case X86_64_SCF_FREEBSD_SIGFRAME: + addr += FREEBSD_UC_MCONTEXT_OFF; + break; + } + + return DWARF_REG_LOC (&c->dwarf, reg); + +} + +HIDDEN dwarf_loc_t +x86_64_scratch_loc (struct cursor *c, unw_regnum_t reg) +{ + if (c->sigcontext_addr) + return linux_scratch_loc (c, reg); + else + return DWARF_REG_LOC (&c->dwarf, reg); +} +#endif + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + unsigned int mask; + int arg_num; + + switch (reg) + { + + case UNW_X86_64_RIP: + if (write) + c->dwarf.ip = *valp; /* also update the RIP cache */ + loc = c->dwarf.loc[RIP]; + break; + + case UNW_X86_64_CFA: + case UNW_X86_64_RSP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + case UNW_X86_64_RAX: + case UNW_X86_64_RDX: + arg_num = reg - UNW_X86_64_RAX; + mask = (1 << arg_num); + if (write) + { + c->dwarf.eh_args[arg_num] = *valp; + c->dwarf.eh_valid_mask |= mask; + return 0; + } + else if ((c->dwarf.eh_valid_mask & mask) != 0) + { + *valp = c->dwarf.eh_args[arg_num]; + return 0; + } + else + loc = c->dwarf.loc[(reg == UNW_X86_64_RAX) ? RAX : RDX]; + break; + + case UNW_X86_64_RCX: loc = c->dwarf.loc[RCX]; break; + case UNW_X86_64_RBX: loc = c->dwarf.loc[RBX]; break; + + case UNW_X86_64_RBP: loc = c->dwarf.loc[RBP]; break; + case UNW_X86_64_RSI: loc = c->dwarf.loc[RSI]; break; + case UNW_X86_64_RDI: loc = c->dwarf.loc[RDI]; break; + case UNW_X86_64_R8: loc = c->dwarf.loc[R8]; break; + case UNW_X86_64_R9: loc = c->dwarf.loc[R9]; break; + case UNW_X86_64_R10: loc = c->dwarf.loc[R10]; break; + case UNW_X86_64_R11: loc = c->dwarf.loc[R11]; break; + case UNW_X86_64_R12: loc = c->dwarf.loc[R12]; break; + case UNW_X86_64_R13: loc = c->dwarf.loc[R13]; break; + case UNW_X86_64_R14: loc = c->dwarf.loc[R14]; break; + case UNW_X86_64_R15: loc = c->dwarf.loc[R15]; break; + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + return -UNW_EBADREG; +} diff --git a/src/libs/libunwind/x86_64/Gresume.c b/src/libs/libunwind/x86_64/Gresume.c new file mode 100644 index 0000000000..6880d94a20 --- /dev/null +++ b/src/libs/libunwind/x86_64/Gresume.c @@ -0,0 +1,114 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "offsets.h" +#include "unwind_i.h" + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +x86_64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = c->uc; + + /* Ensure c->pi is up-to-date. On x86-64, it's relatively common to + be missing DWARF unwind info. We don't want to fail in that + case, because the frame-chain still would let us do a backtrace + at least. */ + dwarf_make_proc_info (&c->dwarf); + + if (unlikely (c->sigcontext_format != X86_64_SCF_NONE)) + { + x86_64_sigreturn(cursor); + abort(); + } + else + { + Debug (8, "resuming at ip=%llx via setcontext()\n", + (unsigned long long) c->dwarf.ip); + setcontext (uc); + } + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +/* This routine is responsible for copying the register values in + cursor C and establishing them as the current machine state. */ + +static inline int +establish_machine_state (struct cursor *c) +{ + int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, + int write, void *); + int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, + int write, void *); + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + access_reg = as->acc.access_reg; + access_fpreg = as->acc.access_fpreg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + (*access_fpreg) (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + (*access_reg) (as, reg, &val, 1, arg); + } + } + return 0; +} + +PROTECTED int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if ((ret = establish_machine_state (c)) < 0) + return ret; + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/libs/libunwind/x86_64/Gstash_frame.c b/src/libs/libunwind/x86_64/Gstash_frame.c new file mode 100644 index 0000000000..dc6c7c8777 --- /dev/null +++ b/src/libs/libunwind/x86_64/Gstash_frame.c @@ -0,0 +1,98 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "ucontext_i.h" + +HIDDEN void +tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) +{ + struct cursor *c = (struct cursor *) dwarf_to_cursor (d); + unw_tdep_frame_t *f = &c->frame_info; + + Debug (4, "ip=0x%lx cfa=0x%lx type %d cfa [where=%d val=%ld] cfaoff=%ld" + " ra=0x%lx rbp [where=%d val=%ld @0x%lx] rsp [where=%d val=%ld @0x%lx]\n", + d->ip, d->cfa, f->frame_type, + rs->reg[DWARF_CFA_REG_COLUMN].where, + rs->reg[DWARF_CFA_REG_COLUMN].val, + rs->reg[DWARF_CFA_OFF_COLUMN].val, + DWARF_GET_LOC(d->loc[d->ret_addr_column]), + rs->reg[RBP].where, rs->reg[RBP].val, DWARF_GET_LOC(d->loc[RBP]), + rs->reg[RSP].where, rs->reg[RSP].val, DWARF_GET_LOC(d->loc[RSP])); + + /* A standard frame is defined as: + - CFA is register-relative offset off RBP or RSP; + - Return address is saved at CFA-8; + - RBP is unsaved or saved at CFA+offset, offset != -1; + - RSP is unsaved or saved at CFA+offset, offset != -1. */ + if (f->frame_type == UNW_X86_64_FRAME_OTHER + && (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_REG) + && (rs->reg[DWARF_CFA_REG_COLUMN].val == RBP + || rs->reg[DWARF_CFA_REG_COLUMN].val == RSP) + && labs((long) rs->reg[DWARF_CFA_OFF_COLUMN].val) < (1 << 29) + && DWARF_GET_LOC(d->loc[d->ret_addr_column]) == d->cfa-8 + && (rs->reg[RBP].where == DWARF_WHERE_UNDEF + || rs->reg[RBP].where == DWARF_WHERE_SAME + || (rs->reg[RBP].where == DWARF_WHERE_CFAREL + && labs((long) rs->reg[RBP].val) < (1 << 14) + && rs->reg[RBP].val+1 != 0)) + && (rs->reg[RSP].where == DWARF_WHERE_UNDEF + || rs->reg[RSP].where == DWARF_WHERE_SAME + || (rs->reg[RSP].where == DWARF_WHERE_CFAREL + && labs((long) rs->reg[RSP].val) < (1 << 14) + && rs->reg[RSP].val+1 != 0))) + { + /* Save information for a standard frame. */ + f->frame_type = UNW_X86_64_FRAME_STANDARD; + f->cfa_reg_rsp = (rs->reg[DWARF_CFA_REG_COLUMN].val == RSP); + f->cfa_reg_offset = rs->reg[DWARF_CFA_OFF_COLUMN].val; + if (rs->reg[RBP].where == DWARF_WHERE_CFAREL) + f->rbp_cfa_offset = rs->reg[RBP].val; + if (rs->reg[RSP].where == DWARF_WHERE_CFAREL) + f->rsp_cfa_offset = rs->reg[RSP].val; + Debug (4, " standard frame\n"); + } + + /* Signal frame was detected via augmentation in tdep_fetch_frame() */ + else if (f->frame_type == UNW_X86_64_FRAME_SIGRETURN) + { + /* Later we are going to fish out {RBP,RSP,RIP} from sigcontext via + their ucontext_t offsets. Confirm DWARF info agrees with the + offsets we expect. */ + +#ifndef NDEBUG + const unw_word_t uc = c->sigcontext_addr; + + assert (DWARF_GET_LOC(d->loc[RIP]) - uc == UC_MCONTEXT_GREGS_RIP); + assert (DWARF_GET_LOC(d->loc[RBP]) - uc == UC_MCONTEXT_GREGS_RBP); + assert (DWARF_GET_LOC(d->loc[RSP]) - uc == UC_MCONTEXT_GREGS_RSP); +#endif + + Debug (4, " sigreturn frame\n"); + } + + /* PLT and guessed RBP-walked frames are handled in unw_step(). */ + else + Debug (4, " unusual frame\n"); +} diff --git a/src/libs/libunwind/x86_64/Gstep.c b/src/libs/libunwind/x86_64/Gstep.c new file mode 100644 index 0000000000..84b37280e5 --- /dev/null +++ b/src/libs/libunwind/x86_64/Gstep.c @@ -0,0 +1,230 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include + +/* Recognise PLT entries such as: + 3bdf0: ff 25 e2 49 13 00 jmpq *0x1349e2(%rip) + 3bdf6: 68 ae 03 00 00 pushq $0x3ae + 3bdfb: e9 00 c5 ff ff jmpq 38300 <_init+0x18> */ +static int +is_plt_entry (struct dwarf_cursor *c) +{ + unw_word_t w0, w1; + unw_accessors_t *a; + int ret; + + a = unw_get_accessors (c->as); + if ((ret = (*a->access_mem) (c->as, c->ip, &w0, 0, c->as_arg)) < 0 + || (ret = (*a->access_mem) (c->as, c->ip + 8, &w1, 0, c->as_arg)) < 0) + return 0; + + ret = (((w0 & 0xffff) == 0x25ff) + && (((w0 >> 48) & 0xff) == 0x68) + && (((w1 >> 24) & 0xff) == 0xe9)); + + Debug (14, "ip=0x%lx => 0x%016lx 0x%016lx, ret = %d\n", c->ip, w0, w1, ret); + return ret; +} + +PROTECTED int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret, i; + +#if CONSERVATIVE_CHECKS + int val = c->validate; + c->validate = 1; +#endif + + Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx)\n", + c, c->dwarf.ip, c->dwarf.cfa); + + /* Try DWARF-based unwinding... */ + c->sigcontext_format = X86_64_SCF_NONE; + ret = dwarf_step (&c->dwarf); + +#if CONSERVATIVE_CHECKS + c->validate = val; +#endif + + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + if (likely (ret >= 0)) + { + /* x86_64 ABI specifies that end of call-chain is marked with a + NULL RBP or undefined return address */ + if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP]) + || DWARF_IS_NULL_LOC(c->dwarf.loc[c->dwarf.ret_addr_column])) + { + c->dwarf.ip = 0; + ret = 0; + } + } + else + { + /* DWARF failed. There isn't much of a usable frame-chain on x86-64, + but we do need to handle two special-cases: + + (i) signal trampoline: Old kernels and older libcs don't + export the vDSO needed to get proper unwind info for the + trampoline. Recognize that case by looking at the code + and filling in things by hand. + + (ii) PLT (shared-library) call-stubs: PLT stubs are invoked + via CALLQ. Try this for all non-signal trampoline + code. */ + + unw_word_t prev_ip = c->dwarf.ip, prev_cfa = c->dwarf.cfa; + struct dwarf_loc rbp_loc, rsp_loc, rip_loc; + + /* We could get here because of missing/bad unwind information. + Validate all addresses before dereferencing. */ + c->validate = 1; + + Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); + + if (unw_is_signal_frame (cursor)) + { + ret = unw_handle_signal_frame(cursor); + if (ret < 0) + { + Debug (2, "returning 0\n"); + return 0; + } + } + else if (is_plt_entry (&c->dwarf)) + { + /* Like regular frame, CFA = RSP+8, RA = [CFA-8], no regs saved. */ + Debug (2, "found plt entry\n"); + c->frame_info.cfa_reg_offset = 8; + c->frame_info.cfa_reg_rsp = -1; + c->frame_info.frame_type = UNW_X86_64_FRAME_STANDARD; + c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); + c->dwarf.cfa += 8; + } + else if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])) + { + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + } + else + { + unw_word_t rbp; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RBP], &rbp); + if (ret < 0) + { + Debug (2, "returning %d [RBP=0x%lx]\n", ret, + DWARF_GET_LOC (c->dwarf.loc[RBP])); + return ret; + } + + if (!rbp) + { + /* Looks like we may have reached the end of the call-chain. */ + rbp_loc = DWARF_NULL_LOC; + rsp_loc = DWARF_NULL_LOC; + rip_loc = DWARF_NULL_LOC; + } + else + { + unw_word_t rbp1 = 0; + rbp_loc = DWARF_LOC(rbp, 0); + rsp_loc = DWARF_NULL_LOC; + rip_loc = DWARF_LOC (rbp + 8, 0); + ret = dwarf_get (&c->dwarf, rbp_loc, &rbp1); + Debug (1, "[RBP=0x%lx] = 0x%lx (cfa = 0x%lx) -> 0x%lx\n", + (unsigned long) DWARF_GET_LOC (c->dwarf.loc[RBP]), + rbp, c->dwarf.cfa, rbp1); + + /* Heuristic to determine incorrect guess. For RBP to be a + valid frame it needs to be above current CFA, but don't + let it go more than a little. Note that we can't deduce + anything about new RBP (rbp1) since it may not be a frame + pointer in the frame above. Just check we get the value. */ + if (ret < 0 + || rbp < c->dwarf.cfa + || (rbp - c->dwarf.cfa) > 0x4000) + { + rip_loc = DWARF_NULL_LOC; + rbp_loc = DWARF_NULL_LOC; + } + + c->frame_info.frame_type = UNW_X86_64_FRAME_GUESSED; + c->frame_info.cfa_reg_rsp = 0; + c->frame_info.cfa_reg_offset = 16; + c->frame_info.rbp_cfa_offset = -16; + c->dwarf.cfa += 16; + } + + /* Mark all registers unsaved */ + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + c->dwarf.loc[RBP] = rbp_loc; + c->dwarf.loc[RSP] = rsp_loc; + c->dwarf.loc[RIP] = rip_loc; + c->dwarf.use_prev_instr = 1; + } + + c->dwarf.ret_addr_column = RIP; + + if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])) + { + ret = 0; + Debug (2, "NULL %%rbp loc, returning %d\n", ret); + return ret; + } + if (!DWARF_IS_NULL_LOC (c->dwarf.loc[RIP])) + { + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); + Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n", + (unsigned long long) DWARF_GET_LOC (c->dwarf.loc[RIP]), + (unsigned long long) c->dwarf.ip); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + ret = 1; + } + else + c->dwarf.ip = 0; + + if (c->dwarf.ip == prev_ip && c->dwarf.cfa == prev_cfa) + return -UNW_EBADFRAME; + } + Debug (2, "returning %d\n", ret); + return ret; +} diff --git a/src/libs/libunwind/x86_64/Gtrace.c b/src/libs/libunwind/x86_64/Gtrace.c new file mode 100644 index 0000000000..833d7a789a --- /dev/null +++ b/src/libs/libunwind/x86_64/Gtrace.c @@ -0,0 +1,533 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "ucontext_i.h" +#include +#include + +#pragma weak pthread_once +#pragma weak pthread_key_create +#pragma weak pthread_getspecific +#pragma weak pthread_setspecific + +/* Initial hash table size. Table expands by 2 bits (times four). */ +#define HASH_MIN_BITS 14 + +typedef struct +{ + unw_tdep_frame_t *frames; + size_t log_size; + size_t used; + size_t dtor_count; /* Counts how many times our destructor has already + been called. */ +} unw_trace_cache_t; + +static const unw_tdep_frame_t empty_frame = { 0, UNW_X86_64_FRAME_OTHER, -1, -1, 0, -1, -1 }; +static define_lock (trace_init_lock); +static pthread_once_t trace_cache_once = PTHREAD_ONCE_INIT; +static sig_atomic_t trace_cache_once_happen; +static pthread_key_t trace_cache_key; +static struct mempool trace_cache_pool; +static __thread unw_trace_cache_t *tls_cache; +static __thread int tls_cache_destroyed; + +/* Free memory for a thread's trace cache. */ +static void +trace_cache_free (void *arg) +{ + unw_trace_cache_t *cache = arg; + if (++cache->dtor_count < PTHREAD_DESTRUCTOR_ITERATIONS) + { + /* Not yet our turn to get destroyed. Re-install ourselves into the key. */ + pthread_setspecific(trace_cache_key, cache); + Debug(5, "delayed freeing cache %p (%zx to go)\n", cache, + PTHREAD_DESTRUCTOR_ITERATIONS - cache->dtor_count); + return; + } + tls_cache_destroyed = 1; + tls_cache = NULL; + munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); + mempool_free (&trace_cache_pool, cache); + Debug(5, "freed cache %p\n", cache); +} + +/* Initialise frame tracing for threaded use. */ +static void +trace_cache_init_once (void) +{ + pthread_key_create (&trace_cache_key, &trace_cache_free); + mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); + trace_cache_once_happen = 1; +} + +static unw_tdep_frame_t * +trace_cache_buckets (size_t n) +{ + unw_tdep_frame_t *frames; + size_t i; + + GET_MEMORY(frames, n * sizeof (unw_tdep_frame_t)); + if (likely(frames != NULL)) + for (i = 0; i < n; ++i) + frames[i] = empty_frame; + + return frames; +} + +/* Allocate and initialise hash table for frame cache lookups. + Returns the cache initialised with (1u << HASH_LOW_BITS) hash + buckets, or NULL if there was a memory allocation problem. */ +static unw_trace_cache_t * +trace_cache_create (void) +{ + unw_trace_cache_t *cache; + + if (tls_cache_destroyed) + { + /* The current thread is in the process of exiting. Don't recreate + cache, as we wouldn't have another chance to free it. */ + Debug(5, "refusing to reallocate cache: " + "thread-locals are being deallocated\n"); + return NULL; + } + + if (! (cache = mempool_alloc(&trace_cache_pool))) + { + Debug(5, "failed to allocate cache\n"); + return NULL; + } + + if (! (cache->frames = trace_cache_buckets(1u << HASH_MIN_BITS))) + { + Debug(5, "failed to allocate buckets\n"); + mempool_free(&trace_cache_pool, cache); + return NULL; + } + + cache->log_size = HASH_MIN_BITS; + cache->used = 0; + cache->dtor_count = 0; + tls_cache_destroyed = 0; /* Paranoia: should already be 0. */ + Debug(5, "allocated cache %p\n", cache); + return cache; +} + +/* Expand the hash table in the frame cache if possible. This always + quadruples the hash size, and clears all previous frame entries. */ +static int +trace_cache_expand (unw_trace_cache_t *cache) +{ + size_t old_size = (1u << cache->log_size); + size_t new_log_size = cache->log_size + 2; + unw_tdep_frame_t *new_frames = trace_cache_buckets (1u << new_log_size); + + if (unlikely(! new_frames)) + { + Debug(5, "failed to expand cache to 2^%lu buckets\n", new_log_size); + return -UNW_ENOMEM; + } + + Debug(5, "expanded cache from 2^%lu to 2^%lu buckets\n", cache->log_size, new_log_size); + munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); + cache->frames = new_frames; + cache->log_size = new_log_size; + cache->used = 0; + return 0; +} + +static unw_trace_cache_t * +trace_cache_get_unthreaded (void) +{ + unw_trace_cache_t *cache; + intrmask_t saved_mask; + static unw_trace_cache_t *global_cache = NULL; + lock_acquire (&trace_init_lock, saved_mask); + if (! global_cache) + { + mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); + global_cache = trace_cache_create (); + } + cache = global_cache; + lock_release (&trace_init_lock, saved_mask); + Debug(5, "using cache %p\n", cache); + return cache; +} + +/* Get the frame cache for the current thread. Create it if there is none. */ +static unw_trace_cache_t * +trace_cache_get (void) +{ + unw_trace_cache_t *cache; + if (likely (pthread_once != NULL)) + { + pthread_once(&trace_cache_once, &trace_cache_init_once); + if (!trace_cache_once_happen) + { + return trace_cache_get_unthreaded(); + } + if (! (cache = tls_cache)) + { + cache = trace_cache_create(); + pthread_setspecific(trace_cache_key, cache); + tls_cache = cache; + } + Debug(5, "using cache %p\n", cache); + return cache; + } + else + { + return trace_cache_get_unthreaded(); + } +} + +/* Initialise frame properties for address cache slot F at address + RIP using current CFA, RBP and RSP values. Modifies CURSOR to + that location, performs one unw_step(), and fills F with what + was discovered about the location. Returns F. + + FIXME: This probably should tell DWARF handling to never evaluate + or use registers other than RBP, RSP and RIP in case there is + highly unusual unwind info which uses these creatively. */ +static unw_tdep_frame_t * +trace_init_addr (unw_tdep_frame_t *f, + unw_cursor_t *cursor, + unw_word_t cfa, + unw_word_t rip, + unw_word_t rbp, + unw_word_t rsp) +{ + struct cursor *c = (struct cursor *) cursor; + struct dwarf_cursor *d = &c->dwarf; + int ret = -UNW_EINVAL; + + /* Initialise frame properties: unknown, not last. */ + f->virtual_address = rip; + f->frame_type = UNW_X86_64_FRAME_OTHER; + f->last_frame = 0; + f->cfa_reg_rsp = -1; + f->cfa_reg_offset = 0; + f->rbp_cfa_offset = -1; + f->rsp_cfa_offset = -1; + + /* Reinitialise cursor to this instruction - but undo next/prev RIP + adjustment because unw_step will redo it - and force RIP, RBP + RSP into register locations (=~ ucontext we keep), then set + their desired values. Then perform the step. */ + d->ip = rip + d->use_prev_instr; + d->cfa = cfa; + d->loc[UNW_X86_64_RIP] = DWARF_REG_LOC (d, UNW_X86_64_RIP); + d->loc[UNW_X86_64_RBP] = DWARF_REG_LOC (d, UNW_X86_64_RBP); + d->loc[UNW_X86_64_RSP] = DWARF_REG_LOC (d, UNW_X86_64_RSP); + c->frame_info = *f; + + if (likely(dwarf_put (d, d->loc[UNW_X86_64_RIP], rip) >= 0) + && likely(dwarf_put (d, d->loc[UNW_X86_64_RBP], rbp) >= 0) + && likely(dwarf_put (d, d->loc[UNW_X86_64_RSP], rsp) >= 0) + && likely((ret = unw_step (cursor)) >= 0)) + *f = c->frame_info; + + /* If unw_step() stopped voluntarily, remember that, even if it + otherwise could not determine anything useful. This avoids + failing trace if we hit frames without unwind info, which is + common for the outermost frame (CRT stuff) on many systems. + This avoids failing trace in very common circumstances; failing + to unw_step() loop wouldn't produce any better result. */ + if (ret == 0) + f->last_frame = -1; + + Debug (3, "frame va %lx type %d last %d cfa %s+%d rbp @ cfa%+d rsp @ cfa%+d\n", + f->virtual_address, f->frame_type, f->last_frame, + f->cfa_reg_rsp ? "rsp" : "rbp", f->cfa_reg_offset, + f->rbp_cfa_offset, f->rsp_cfa_offset); + + return f; +} + +/* Look up and if necessary fill in frame attributes for address RIP + in CACHE using current CFA, RBP and RSP values. Uses CURSOR to + perform any unwind steps necessary to fill the cache. Returns the + frame cache slot which describes RIP. */ +static unw_tdep_frame_t * +trace_lookup (unw_cursor_t *cursor, + unw_trace_cache_t *cache, + unw_word_t cfa, + unw_word_t rip, + unw_word_t rbp, + unw_word_t rsp) +{ + /* First look up for previously cached information using cache as + linear probing hash table with probe step of 1. Majority of + lookups should be completed within few steps, but it is very + important the hash table does not fill up, or performance falls + off the cliff. */ + uint64_t i, addr; + uint64_t cache_size = 1u << cache->log_size; + uint64_t slot = ((rip * 0x9e3779b97f4a7c16) >> 43) & (cache_size-1); + unw_tdep_frame_t *frame; + + for (i = 0; i < 16; ++i) + { + frame = &cache->frames[slot]; + addr = frame->virtual_address; + + /* Return if we found the address. */ + if (likely(addr == rip)) + { + Debug (4, "found address after %ld steps\n", i); + return frame; + } + + /* If slot is empty, reuse it. */ + if (likely(! addr)) + break; + + /* Linear probe to next slot candidate, step = 1. */ + if (++slot >= cache_size) + slot -= cache_size; + } + + /* If we collided after 16 steps, or if the hash is more than half + full, force the hash to expand. Fill the selected slot, whether + it's free or collides. Note that hash expansion drops previous + contents; further lookups will refill the hash. */ + Debug (4, "updating slot %lu after %ld steps, replacing 0x%lx\n", slot, i, addr); + if (unlikely(addr || cache->used >= cache_size / 2)) + { + if (unlikely(trace_cache_expand (cache) < 0)) + return NULL; + + cache_size = 1u << cache->log_size; + slot = ((rip * 0x9e3779b97f4a7c16) >> 43) & (cache_size-1); + frame = &cache->frames[slot]; + addr = frame->virtual_address; + } + + if (! addr) + ++cache->used; + + return trace_init_addr (frame, cursor, cfa, rip, rbp, rsp); +} + +/* Fast stack backtrace for x86-64. + + This is used by backtrace() implementation to accelerate frequent + queries for current stack, without any desire to unwind. It fills + BUFFER with the call tree from CURSOR upwards for at most SIZE + stack levels. The first frame, backtrace itself, is omitted. When + called, SIZE should give the maximum number of entries that can be + stored into BUFFER. Uses an internal thread-specific cache to + accelerate queries. + + The caller should fall back to a unw_step() loop if this function + fails by returning -UNW_ESTOPUNWIND, meaning the routine hit a + stack frame that is too complex to be traced in the fast path. + + This function is tuned for clients which only need to walk the + stack to get the call tree as fast as possible but without any + other details, for example profilers sampling the stack thousands + to millions of times per second. The routine handles the most + common x86-64 ABI stack layouts: CFA is RBP or RSP plus/minus + constant offset, return address is at CFA-8, and RBP and RSP are + either unchanged or saved on stack at constant offset from the CFA; + the signal return frame; and frames without unwind info provided + they are at the outermost (final) frame or can conservatively be + assumed to be frame-pointer based. + + Any other stack layout will cause the routine to give up. There + are only a handful of relatively rarely used functions which do + not have a stack in the standard form: vfork, longjmp, setcontext + and _dl_runtime_profile on common linux systems for example. + + On success BUFFER and *SIZE reflect the trace progress up to *SIZE + stack levels or the outermost frame, which ever is less. It may + stop short of outermost frame if unw_step() loop would also do so, + e.g. if there is no more unwind information; this is not reported + as an error. + + The function returns a negative value for errors, -UNW_ESTOPUNWIND + if tracing stopped because of an unusual frame unwind info. The + BUFFER and *SIZE reflect tracing progress up to the error frame. + + Callers of this function would normally look like this: + + unw_cursor_t cur; + unw_context_t ctx; + void addrs[128]; + int depth = 128; + int ret; + + unw_getcontext(&ctx); + unw_init_local(&cur, &ctx); + if ((ret = unw_tdep_trace(&cur, addrs, &depth)) < 0) + { + depth = 0; + unw_getcontext(&ctx); + unw_init_local(&cur, &ctx); + while ((ret = unw_step(&cur)) > 0 && depth < 128) + { + unw_word_t ip; + unw_get_reg(&cur, UNW_REG_IP, &ip); + addresses[depth++] = (void *) ip; + } + } +*/ +HIDDEN int +tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) +{ + struct cursor *c = (struct cursor *) cursor; + struct dwarf_cursor *d = &c->dwarf; + unw_trace_cache_t *cache; + unw_word_t rbp, rsp, rip, cfa; + int maxdepth = 0; + int depth = 0; + int ret; + + /* Check input parametres. */ + if (unlikely(! cursor || ! buffer || ! size || (maxdepth = *size) <= 0)) + return -UNW_EINVAL; + + Debug (1, "begin ip 0x%lx cfa 0x%lx\n", d->ip, d->cfa); + + /* Tell core dwarf routines to call back to us. */ + d->stash_frames = 1; + + /* Determine initial register values. These are direct access safe + because we know they come from the initial machine context. */ + rip = d->ip; + rsp = cfa = d->cfa; + ACCESS_MEM_FAST(ret, 0, d, DWARF_GET_LOC(d->loc[UNW_X86_64_RBP]), rbp); + assert(ret == 0); + + /* Get frame cache. */ + if (unlikely(! (cache = trace_cache_get()))) + { + Debug (1, "returning %d, cannot get trace cache\n", -UNW_ENOMEM); + *size = 0; + d->stash_frames = 0; + return -UNW_ENOMEM; + } + + /* Trace the stack upwards, starting from current RIP. Adjust + the RIP address for previous/next instruction as the main + unwinding logic would also do. We undo this before calling + back into unw_step(). */ + while (depth < maxdepth) + { + rip -= d->use_prev_instr; + Debug (2, "depth %d cfa 0x%lx rip 0x%lx rsp 0x%lx rbp 0x%lx\n", + depth, cfa, rip, rsp, rbp); + + /* See if we have this address cached. If not, evaluate enough of + the dwarf unwind information to fill the cache line data, or to + decide this frame cannot be handled in fast trace mode. We + cache negative results too to prevent unnecessary dwarf parsing + for common failures. */ + unw_tdep_frame_t *f = trace_lookup (cursor, cache, cfa, rip, rbp, rsp); + + /* If we don't have information for this frame, give up. */ + if (unlikely(! f)) + { + ret = -UNW_ENOINFO; + break; + } + + Debug (3, "frame va %lx type %d last %d cfa %s+%d rbp @ cfa%+d rsp @ cfa%+d\n", + f->virtual_address, f->frame_type, f->last_frame, + f->cfa_reg_rsp ? "rsp" : "rbp", f->cfa_reg_offset, + f->rbp_cfa_offset, f->rsp_cfa_offset); + + assert (f->virtual_address == rip); + + /* Stop if this was the last frame. In particular don't evaluate + new register values as it may not be safe - we don't normally + run with full validation on, and do not want to - and there's + enough bad unwind info floating around that we need to trust + what unw_step() previously said, in potentially bogus frames. */ + if (f->last_frame) + break; + + /* Evaluate CFA and registers for the next frame. */ + switch (f->frame_type) + { + case UNW_X86_64_FRAME_GUESSED: + /* Fall thru to standard processing after forcing validation. */ + c->validate = 1; + + case UNW_X86_64_FRAME_STANDARD: + /* Advance standard traceable frame. */ + cfa = (f->cfa_reg_rsp ? rsp : rbp) + f->cfa_reg_offset; + ACCESS_MEM_FAST(ret, c->validate, d, cfa - 8, rip); + if (likely(ret >= 0) && likely(f->rbp_cfa_offset != -1)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->rbp_cfa_offset, rbp); + + /* Don't bother reading RSP from DWARF, CFA becomes new RSP. */ + rsp = cfa; + + /* Next frame needs to back up for unwind info lookup. */ + d->use_prev_instr = 1; + break; + + case UNW_X86_64_FRAME_SIGRETURN: + cfa = cfa + f->cfa_reg_offset; /* cfa now points to ucontext_t. */ + + ACCESS_MEM_FAST(ret, c->validate, d, cfa + UC_MCONTEXT_GREGS_RIP, rip); + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + UC_MCONTEXT_GREGS_RBP, rbp); + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + UC_MCONTEXT_GREGS_RSP, rsp); + + /* Resume stack at signal restoration point. The stack is not + necessarily continuous here, especially with sigaltstack(). */ + cfa = rsp; + + /* Next frame should not back up. */ + d->use_prev_instr = 0; + break; + + default: + /* We cannot trace through this frame, give up and tell the + caller we had to stop. Data collected so far may still be + useful to the caller, so let it know how far we got. */ + ret = -UNW_ESTOPUNWIND; + break; + } + + Debug (4, "new cfa 0x%lx rip 0x%lx rsp 0x%lx rbp 0x%lx\n", + cfa, rip, rsp, rbp); + + /* If we failed or ended up somewhere bogus, stop. */ + if (unlikely(ret < 0 || rip < 0x4000)) + break; + + /* Record this address in stack trace. We skipped the first address. */ + buffer[depth++] = (void *) (rip - d->use_prev_instr); + } + +#if UNW_DEBUG + Debug (1, "returning %d, depth %d\n", ret, depth); +#endif + *size = depth; + return ret; +} diff --git a/src/libs/libunwind/x86_64/Lcreate_addr_space.c b/src/libs/libunwind/x86_64/Lcreate_addr_space.c new file mode 100644 index 0000000000..0f2dc6be90 --- /dev/null +++ b/src/libs/libunwind/x86_64/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/libs/libunwind/x86_64/Lget_proc_info.c b/src/libs/libunwind/x86_64/Lget_proc_info.c new file mode 100644 index 0000000000..69028b019f --- /dev/null +++ b/src/libs/libunwind/x86_64/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/libs/libunwind/x86_64/Lget_save_loc.c b/src/libs/libunwind/x86_64/Lget_save_loc.c new file mode 100644 index 0000000000..9ea048a907 --- /dev/null +++ b/src/libs/libunwind/x86_64/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/libs/libunwind/x86_64/Lglobal.c b/src/libs/libunwind/x86_64/Lglobal.c new file mode 100644 index 0000000000..8c43a67c0f --- /dev/null +++ b/src/libs/libunwind/x86_64/Lglobal.c @@ -0,0 +1,6 @@ +#define UNW_LOCAL_ONLY +#include "config.h" +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/libs/libunwind/x86_64/Linit.c b/src/libs/libunwind/x86_64/Linit.c new file mode 100644 index 0000000000..e9abfdd46a --- /dev/null +++ b/src/libs/libunwind/x86_64/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/libs/libunwind/x86_64/Linit_local.c b/src/libs/libunwind/x86_64/Linit_local.c new file mode 100644 index 0000000000..68a1687e85 --- /dev/null +++ b/src/libs/libunwind/x86_64/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/libs/libunwind/x86_64/Linit_remote.c b/src/libs/libunwind/x86_64/Linit_remote.c new file mode 100644 index 0000000000..58cb04ab7c --- /dev/null +++ b/src/libs/libunwind/x86_64/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/libs/libunwind/x86_64/Los-freebsd.c b/src/libs/libunwind/x86_64/Los-freebsd.c new file mode 100644 index 0000000000..a75a205df1 --- /dev/null +++ b/src/libs/libunwind/x86_64/Los-freebsd.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-freebsd.c" +#endif diff --git a/src/libs/libunwind/x86_64/Los-linux.c b/src/libs/libunwind/x86_64/Los-linux.c new file mode 100644 index 0000000000..3cc18aabcc --- /dev/null +++ b/src/libs/libunwind/x86_64/Los-linux.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-linux.c" +#endif diff --git a/src/libs/libunwind/x86_64/Los-solaris.c b/src/libs/libunwind/x86_64/Los-solaris.c new file mode 100644 index 0000000000..be64b2c695 --- /dev/null +++ b/src/libs/libunwind/x86_64/Los-solaris.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-solaris.c" +#endif diff --git a/src/libs/libunwind/x86_64/Lregs.c b/src/libs/libunwind/x86_64/Lregs.c new file mode 100644 index 0000000000..2c9c75cd7d --- /dev/null +++ b/src/libs/libunwind/x86_64/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/libs/libunwind/x86_64/Lresume.c b/src/libs/libunwind/x86_64/Lresume.c new file mode 100644 index 0000000000..41a8cf003d --- /dev/null +++ b/src/libs/libunwind/x86_64/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/libs/libunwind/x86_64/Lstash_frame.c b/src/libs/libunwind/x86_64/Lstash_frame.c new file mode 100644 index 0000000000..77587803d0 --- /dev/null +++ b/src/libs/libunwind/x86_64/Lstash_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstash_frame.c" +#endif diff --git a/src/libs/libunwind/x86_64/Lstep.c b/src/libs/libunwind/x86_64/Lstep.c new file mode 100644 index 0000000000..c1ac3c7547 --- /dev/null +++ b/src/libs/libunwind/x86_64/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/libs/libunwind/x86_64/Ltrace.c b/src/libs/libunwind/x86_64/Ltrace.c new file mode 100644 index 0000000000..fcd3f239c9 --- /dev/null +++ b/src/libs/libunwind/x86_64/Ltrace.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gtrace.c" +#endif diff --git a/src/libs/libunwind/x86_64/getcontext.S b/src/libs/libunwind/x86_64/getcontext.S new file mode 100644 index 0000000000..6f5d0a1408 --- /dev/null +++ b/src/libs/libunwind/x86_64/getcontext.S @@ -0,0 +1,136 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 Google, Inc + Contributed by Paul Pluzhnikov + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "ucontext_i.h" + +/* int _Ux86_64_getcontext (ucontext_t *ucp) + + Saves the machine context in UCP necessary for libunwind. + Unlike the libc implementation, we don't save the signal mask + and hence avoid the cost of a system call per unwind. + +*/ + + .global _Ux86_64_getcontext + .type _Ux86_64_getcontext, @function +_Ux86_64_getcontext: + .cfi_startproc + + /* Callee saved: RBX, RBP, R12-R15 */ + movq %r12, UC_MCONTEXT_GREGS_R12(%rdi) + movq %r13, UC_MCONTEXT_GREGS_R13(%rdi) + movq %r14, UC_MCONTEXT_GREGS_R14(%rdi) + movq %r15, UC_MCONTEXT_GREGS_R15(%rdi) + movq %rbp, UC_MCONTEXT_GREGS_RBP(%rdi) + movq %rbx, UC_MCONTEXT_GREGS_RBX(%rdi) + + /* Save argument registers (not strictly needed, but setcontext + restores them, so don't restore garbage). */ + movq %r8, UC_MCONTEXT_GREGS_R8(%rdi) + movq %r9, UC_MCONTEXT_GREGS_R9(%rdi) + movq %rdi, UC_MCONTEXT_GREGS_RDI(%rdi) + movq %rsi, UC_MCONTEXT_GREGS_RSI(%rdi) + movq %rdx, UC_MCONTEXT_GREGS_RDX(%rdi) + movq %rax, UC_MCONTEXT_GREGS_RAX(%rdi) + movq %rcx, UC_MCONTEXT_GREGS_RCX(%rdi) + +#if defined(__linux__) || defined(__sun__) + /* Save fp state (not needed, except for setcontext not + restoring garbage). */ + leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8 +#ifdef UC_MCONTEXT_FPREGS_PTR + movq %r8, UC_MCONTEXT_FPREGS_PTR(%rdi) +#endif // UC_MCONTEXT_FPREGS_PTR + fnstenv (%r8) + stmxcsr FPREGS_OFFSET_MXCSR(%r8) +#elif defined __FreeBSD__ + fxsave UC_MCONTEXT_FPSTATE(%rdi) + movq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi) + movq $UC_MCONTEXT_FPFMT_XMM,UC_MCONTEXT_FPFORMAT(%rdi) + /* Save rflags and segment registers, so that sigreturn(2) + does not complain. */ + pushfq + .cfi_adjust_cfa_offset 8 + popq UC_MCONTEXT_RFLAGS(%rdi) + .cfi_adjust_cfa_offset -8 + movl $0, UC_MCONTEXT_FLAGS(%rdi) + movw %cs, UC_MCONTEXT_CS(%rdi) + movw %ss, UC_MCONTEXT_SS(%rdi) +#if 0 + /* Setting the flags to 0 above disables restore of segment + registers from the context */ + movw %ds, UC_MCONTEXT_DS(%rdi) + movw %es, UC_MCONTEXT_ES(%rdi) + movw %fs, UC_MCONTEXT_FS(%rdi) + movw %gs, UC_MCONTEXT_GS(%rdi) +#endif + movq $UC_MCONTEXT_MC_LEN_VAL, UC_MCONTEXT_MC_LEN(%rdi) +#else +#error Port me +#endif + + leaq 8(%rsp), %rax /* exclude this call. */ + movq %rax, UC_MCONTEXT_GREGS_RSP(%rdi) + + movq 0(%rsp), %rax + movq %rax, UC_MCONTEXT_GREGS_RIP(%rdi) + + xorq %rax, %rax + retq + .cfi_endproc + .size _Ux86_64_getcontext, . - _Ux86_64_getcontext + +/* int _Ux86_64_getcontext_trace (ucontext_t *ucp) + + Saves limited machine context in UCP necessary for libunwind. + Unlike _Ux86_64_getcontext, saves only the parts needed for + fast trace. If fast trace fails, caller will have to get the + full context. +*/ + + .global _Ux86_64_getcontext_trace + .hidden _Ux86_64_getcontext_trace + .type _Ux86_64_getcontext_trace, @function +_Ux86_64_getcontext_trace: + .cfi_startproc + + /* Save only RBP, RBX, RSP, RIP - exclude this call. */ + movq %rbp, UC_MCONTEXT_GREGS_RBP(%rdi) + movq %rbx, UC_MCONTEXT_GREGS_RBX(%rdi) + + leaq 8(%rsp), %rax + movq %rax, UC_MCONTEXT_GREGS_RSP(%rdi) + + movq 0(%rsp), %rax + movq %rax, UC_MCONTEXT_GREGS_RIP(%rdi) + + xorq %rax, %rax + retq + .cfi_endproc + .size _Ux86_64_getcontext_trace, . - _Ux86_64_getcontext_trace + + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/libs/libunwind/x86_64/init.h b/src/libs/libunwind/x86_64/init.h new file mode 100644 index 0000000000..442b2bf711 --- /dev/null +++ b/src/libs/libunwind/x86_64/init.h @@ -0,0 +1,89 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* Avoid a trip to x86_64_r_uc_addr() for purely local initialisation. */ +#if defined UNW_LOCAL_ONLY && defined __linux +# define REG_INIT_LOC(c, rlc, ruc) \ + DWARF_LOC ((unw_word_t) &c->uc->uc_mcontext.gregs[REG_ ## ruc], 0) + +#elif defined UNW_LOCAL_ONLY && defined __FreeBSD__ +# define REG_INIT_LOC(c, rlc, ruc) \ + DWARF_LOC ((unw_word_t) &c->uc->uc_mcontext.mc_ ## rlc, 0) + +#else +# define REG_INIT_LOC(c, rlc, ruc) \ + DWARF_REG_LOC (&c->dwarf, UNW_X86_64_ ## ruc) +#endif + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret; + + c->dwarf.loc[RAX] = REG_INIT_LOC(c, rax, RAX); + c->dwarf.loc[RDX] = REG_INIT_LOC(c, rdx, RDX); + c->dwarf.loc[RCX] = REG_INIT_LOC(c, rcx, RCX); + c->dwarf.loc[RBX] = REG_INIT_LOC(c, rbx, RBX); + c->dwarf.loc[RSI] = REG_INIT_LOC(c, rsi, RSI); + c->dwarf.loc[RDI] = REG_INIT_LOC(c, rdi, RDI); + c->dwarf.loc[RBP] = REG_INIT_LOC(c, rbp, RBP); + c->dwarf.loc[RSP] = REG_INIT_LOC(c, rsp, RSP); + c->dwarf.loc[R8] = REG_INIT_LOC(c, r8, R8); + c->dwarf.loc[R9] = REG_INIT_LOC(c, r9, R9); + c->dwarf.loc[R10] = REG_INIT_LOC(c, r10, R10); + c->dwarf.loc[R11] = REG_INIT_LOC(c, r11, R11); + c->dwarf.loc[R12] = REG_INIT_LOC(c, r12, R12); + c->dwarf.loc[R13] = REG_INIT_LOC(c, r13, R13); + c->dwarf.loc[R14] = REG_INIT_LOC(c, r14, R14); + c->dwarf.loc[R15] = REG_INIT_LOC(c, r15, R15); + c->dwarf.loc[RIP] = REG_INIT_LOC(c, rip, RIP); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_X86_64_RSP), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = X86_64_SCF_NONE; + c->sigcontext_addr = 0; + + c->dwarf.args_size = 0; + c->dwarf.ret_addr_column = RIP; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/libs/libunwind/x86_64/is_fpreg.c b/src/libs/libunwind/x86_64/is_fpreg.c new file mode 100644 index 0000000000..1188a616f0 --- /dev/null +++ b/src/libs/libunwind/x86_64/is_fpreg.c @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED int +unw_is_fpreg (int regnum) +{ +#if 0 + return ((regnum >= UNW_X86_ST0 && regnum <= UNW_X86_ST7) + || (regnum >= UNW_X86_XMM0_lo && regnum <= UNW_X86_XMM7_hi)); +#endif + return 0; +} diff --git a/src/libs/libunwind/x86_64/longjmp.S b/src/libs/libunwind/x86_64/longjmp.S new file mode 100644 index 0000000000..274778fd80 --- /dev/null +++ b/src/libs/libunwind/x86_64/longjmp.S @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + .globl _UI_longjmp_cont + .type _UI_longjmp_cont, @function +_UI_longjmp_cont: + push %rax /* push target IP as return address */ + mov %rdx, %rax /* set up return-value */ + retq + .size _UI_longjmp_cont, .-_UI_longjmp_cont + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/libs/libunwind/x86_64/offsets.h b/src/libs/libunwind/x86_64/offsets.h new file mode 100644 index 0000000000..0807960f30 --- /dev/null +++ b/src/libs/libunwind/x86_64/offsets.h @@ -0,0 +1,3 @@ +/* FreeBSD specific definitions */ + +#define FREEBSD_UC_MCONTEXT_OFF 0x10 diff --git a/src/libs/libunwind/x86_64/regname.c b/src/libs/libunwind/x86_64/regname.c new file mode 100644 index 0000000000..6c0e2f35e4 --- /dev/null +++ b/src/libs/libunwind/x86_64/regname.c @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + + Contributed by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + "RAX", + "RDX", + "RCX", + "RBX", + "RSI", + "RDI", + "RBP", + "RSP", + "R8", + "R9", + "R10", + "R11", + "R12", + "R13", + "R14", + "R15", + "RIP", + }; + +PROTECTED const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/libs/libunwind/x86_64/setcontext.S b/src/libs/libunwind/x86_64/setcontext.S new file mode 100644 index 0000000000..a534803c33 --- /dev/null +++ b/src/libs/libunwind/x86_64/setcontext.S @@ -0,0 +1,124 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2007 Google, Inc + Contributed by Arun Sharma + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "ucontext_i.h" +#if defined __linux__ +#include +#define SIG_SETMASK 2 +#elif defined __sun__ +#define SYS_sigprocmask 95 +#define SIG_SETMASK 3 +#elif defined __FreeBSD__ +#include +#endif + +#define SIGSET_BYTE_SIZE (64/8) + + +/* int _Ux86_64_setcontext (const ucontext_t *ucp) + + Restores the machine context provided. + Unlike the libc implementation, doesn't clobber %rax + +*/ + .global _Ux86_64_setcontext + .type _Ux86_64_setcontext, @function + +_Ux86_64_setcontext: + +#if defined(__linux__) || defined(__sun__) + /* restore signal mask + sigprocmask(SIG_SETMASK, ucp->uc_sigmask, NULL, sizeof(sigset_t)) */ + push %rdi +#if defined(__sun__) + mov $SYS_sigprocmask, %rax +#else + mov $__NR_rt_sigprocmask, %rax +#endif + lea UC_SIGMASK(%rdi), %rsi + mov $SIG_SETMASK, %rdi + xor %rdx, %rdx + mov $SIGSET_BYTE_SIZE, %r10 + syscall + pop %rdi + + /* restore fp state */ +#ifdef UC_MCONTEXT_FPREGS_PTR + mov UC_MCONTEXT_FPREGS_PTR(%rdi),%r8 +#else // UC_MCONTEXT_FPREGS_PTR + leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8 +#endif // UC_MCONTEXT_FPREGS_PTR + fldenv (%r8) + ldmxcsr FPREGS_OFFSET_MXCSR(%r8) +#elif defined __FreeBSD__ + /* restore signal mask */ + pushq %rdi + xorl %edx,%edx + leaq UC_SIGMASK(%rdi),%rsi + movl $3,%edi/* SIG_SETMASK */ + movl $SYS_sigprocmask,%eax + movq %rcx,%r10 + syscall + popq %rdi + + /* restore fp state */ + cmpq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi) + jne 1f + cmpq $UC_MCONTEXT_FPFMT_XMM,UC_MCONTEXT_FPFORMAT(%rdi) + jne 1f + fxrstor UC_MCONTEXT_FPSTATE(%rdi) +1: +#else +#error Port me +#endif + + /* restore the rest of the state */ + mov UC_MCONTEXT_GREGS_R8(%rdi),%r8 + mov UC_MCONTEXT_GREGS_R9(%rdi),%r9 + mov UC_MCONTEXT_GREGS_RBX(%rdi),%rbx + mov UC_MCONTEXT_GREGS_RBP(%rdi),%rbp + mov UC_MCONTEXT_GREGS_R12(%rdi),%r12 + mov UC_MCONTEXT_GREGS_R13(%rdi),%r13 + mov UC_MCONTEXT_GREGS_R14(%rdi),%r14 + mov UC_MCONTEXT_GREGS_R15(%rdi),%r15 + mov UC_MCONTEXT_GREGS_RSI(%rdi),%rsi + mov UC_MCONTEXT_GREGS_RDX(%rdi),%rdx + mov UC_MCONTEXT_GREGS_RAX(%rdi),%rax + mov UC_MCONTEXT_GREGS_RCX(%rdi),%rcx + mov UC_MCONTEXT_GREGS_RSP(%rdi),%rsp + + /* push the return address on the stack */ + mov UC_MCONTEXT_GREGS_RIP(%rdi),%rcx + push %rcx + + mov UC_MCONTEXT_GREGS_RCX(%rdi),%rcx + mov UC_MCONTEXT_GREGS_RDI(%rdi),%rdi + retq + + .size _Ux86_64_setcontext, . - _Ux86_64_setcontext + + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/libs/libunwind/x86_64/siglongjmp.S b/src/libs/libunwind/x86_64/siglongjmp.S new file mode 100644 index 0000000000..32489e53a9 --- /dev/null +++ b/src/libs/libunwind/x86_64/siglongjmp.S @@ -0,0 +1,32 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + .globl _UI_siglongjmp_cont + .type _UI_siglongjmp_cont, @function +_UI_siglongjmp_cont: + retq + .size _UI_siglongjmp_cont, . - _UI_siglongjmp_cont + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/libs/libunwind/x86_64/ucontext_i.h b/src/libs/libunwind/x86_64/ucontext_i.h new file mode 100644 index 0000000000..e41e562927 --- /dev/null +++ b/src/libs/libunwind/x86_64/ucontext_i.h @@ -0,0 +1,102 @@ +/* Copyright (C) 2004 Hewlett-Packard Co. + Contributed by David Mosberger-Tang . + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#if defined __linux__ +#define UC_MCONTEXT_GREGS_R8 0x28 +#define UC_MCONTEXT_GREGS_R9 0x30 +#define UC_MCONTEXT_GREGS_R10 0x38 +#define UC_MCONTEXT_GREGS_R11 0x40 +#define UC_MCONTEXT_GREGS_R12 0x48 +#define UC_MCONTEXT_GREGS_R13 0x50 +#define UC_MCONTEXT_GREGS_R14 0x58 +#define UC_MCONTEXT_GREGS_R15 0x60 +#define UC_MCONTEXT_GREGS_RDI 0x68 +#define UC_MCONTEXT_GREGS_RSI 0x70 +#define UC_MCONTEXT_GREGS_RBP 0x78 +#define UC_MCONTEXT_GREGS_RBX 0x80 +#define UC_MCONTEXT_GREGS_RDX 0x88 +#define UC_MCONTEXT_GREGS_RAX 0x90 +#define UC_MCONTEXT_GREGS_RCX 0x98 +#define UC_MCONTEXT_GREGS_RSP 0xa0 +#define UC_MCONTEXT_GREGS_RIP 0xa8 +#define UC_MCONTEXT_FPREGS_PTR 0x1a8 +#define UC_MCONTEXT_FPREGS_MEM 0xe0 +#define UC_SIGMASK 0x128 +#define FPREGS_OFFSET_MXCSR 0x18 +#elif defined __FreeBSD__ +#define UC_SIGMASK 0x0 +#define UC_MCONTEXT_GREGS_RDI 0x18 +#define UC_MCONTEXT_GREGS_RSI 0x20 +#define UC_MCONTEXT_GREGS_RDX 0x28 +#define UC_MCONTEXT_GREGS_RCX 0x30 +#define UC_MCONTEXT_GREGS_R8 0x38 +#define UC_MCONTEXT_GREGS_R9 0x40 +#define UC_MCONTEXT_GREGS_RAX 0x48 +#define UC_MCONTEXT_GREGS_RBX 0x50 +#define UC_MCONTEXT_GREGS_RBP 0x58 +#define UC_MCONTEXT_GREGS_R10 0x60 +#define UC_MCONTEXT_GREGS_R11 0x68 +#define UC_MCONTEXT_GREGS_R12 0x70 +#define UC_MCONTEXT_GREGS_R13 0x78 +#define UC_MCONTEXT_GREGS_R14 0x80 +#define UC_MCONTEXT_GREGS_R15 0x88 +#define UC_MCONTEXT_FS 0x94 +#define UC_MCONTEXT_GS 0x96 +#define UC_MCONTEXT_FLAGS 0xa0 +#define UC_MCONTEXT_ES 0xa4 +#define UC_MCONTEXT_DS 0xa6 +#define UC_MCONTEXT_GREGS_RIP 0xb0 +#define UC_MCONTEXT_CS 0xb8 +#define UC_MCONTEXT_RFLAGS 0xc0 +#define UC_MCONTEXT_GREGS_RSP 0xc8 +#define UC_MCONTEXT_SS 0xd0 +#define UC_MCONTEXT_MC_LEN 0xd8 +#define UC_MCONTEXT_FPFORMAT 0xe0 +#define UC_MCONTEXT_OWNEDFP 0xe8 +#define UC_MCONTEXT_FPSTATE 0xf0 +#define UC_MCONTEXT_FPOWNED_FPU 0x20001 +#define UC_MCONTEXT_FPFMT_XMM 0x10002 +#define UC_MCONTEXT_MC_LEN_VAL 0x320 +#elif defined(__sun) +#define UC_MCONTEXT_GREGS_R8 0x78 +#define UC_MCONTEXT_GREGS_R9 0x70 +#define UC_MCONTEXT_GREGS_R10 0x68 +#define UC_MCONTEXT_GREGS_R11 0x60 +#define UC_MCONTEXT_GREGS_R12 0x58 +#define UC_MCONTEXT_GREGS_R13 0x50 +#define UC_MCONTEXT_GREGS_R14 0x48 +#define UC_MCONTEXT_GREGS_R15 0x40 +#define UC_MCONTEXT_GREGS_RDI 0x80 +#define UC_MCONTEXT_GREGS_RSI 0x88 +#define UC_MCONTEXT_GREGS_RBP 0x90 +#define UC_MCONTEXT_GREGS_RBX 0x98 +#define UC_MCONTEXT_GREGS_RDX 0xa0 +#define UC_MCONTEXT_GREGS_RAX 0xb0 +#define UC_MCONTEXT_GREGS_RCX 0xa8 +#define UC_MCONTEXT_GREGS_RSP 0xe0 +#define UC_MCONTEXT_GREGS_RIP 0xc8 +#define UC_MCONTEXT_FPREGS_MEM 0x120 +#define FPREGS_OFFSET_MXCSR 0x18 +#define UC_SIGMASK 0x128 +#endif diff --git a/src/libs/libunwind/x86_64/unwind_i.h b/src/libs/libunwind/x86_64/unwind_i.h new file mode 100644 index 0000000000..4f81566ad0 --- /dev/null +++ b/src/libs/libunwind/x86_64/unwind_i.h @@ -0,0 +1,91 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include + +#include + +#include "libunwind_i.h" +#include + +/* DWARF column numbers for x86_64: */ +#define RAX 0 +#define RDX 1 +#define RCX 2 +#define RBX 3 +#define RSI 4 +#define RDI 5 +#define RBP 6 +#define RSP 7 +#define R8 8 +#define R9 9 +#define R10 10 +#define R11 11 +#define R12 12 +#define R13 13 +#define R14 14 +#define R15 15 +#define RIP 16 + +#define x86_64_lock UNW_OBJ(lock) +#define x86_64_local_resume UNW_OBJ(local_resume) +#define x86_64_local_addr_space_init UNW_OBJ(local_addr_space_init) +#define setcontext UNW_ARCH_OBJ (setcontext) +#if 0 +#define x86_64_scratch_loc UNW_OBJ(scratch_loc) +#endif +#define x86_64_r_uc_addr UNW_OBJ(r_uc_addr) +#define x86_64_sigreturn UNW_OBJ(sigreturn) + +/* By-pass calls to access_mem() when known to be safe. */ +#ifdef UNW_LOCAL_ONLY +# undef ACCESS_MEM_FAST +# define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \ + do { \ + if (unlikely(validate)) \ + (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); \ + else \ + (ret) = 0, (to) = *(unw_word_t *)(addr); \ + } while (0) +#endif + +extern void x86_64_local_addr_space_init (void); +extern int x86_64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); +extern int setcontext (const ucontext_t *ucp); + +#if 0 +extern dwarf_loc_t x86_64_scratch_loc (struct cursor *c, unw_regnum_t reg); +#endif + +extern void *x86_64_r_uc_addr (ucontext_t *uc, int reg); +extern NORETURN void x86_64_sigreturn (unw_cursor_t *cursor); + +#endif /* unwind_i_h */ From f2c0917eea6fd7e328fb5cbe1001585da1ffc29a Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Mon, 9 Nov 2015 14:14:33 +0100 Subject: [PATCH 152/370] Import libcxxrt --- headers/libs/libcxxrt/abi_namespace.h | 5 + headers/libs/libcxxrt/atomic.h | 30 + headers/libs/libcxxrt/cxxabi.h | 244 ++ headers/libs/libcxxrt/dwarf_eh.h | 477 +++ headers/libs/libcxxrt/stdexcept.h | 96 + headers/libs/libcxxrt/typeinfo.h | 313 ++ headers/libs/libcxxrt/unwind-arm.h | 223 ++ headers/libs/libcxxrt/unwind-itanium.h | 170 ++ headers/libs/libcxxrt/unwind.h | 40 + src/libs/libcxxrt/AUTHORS | 2 + src/libs/libcxxrt/COPYRIGHT | 3 + src/libs/libcxxrt/LICENSE | 14 + src/libs/libcxxrt/README | 50 + src/libs/libcxxrt/auxhelper.cc | 82 + src/libs/libcxxrt/cxa_atexit.c | 69 + src/libs/libcxxrt/cxa_finalize.c | 32 + src/libs/libcxxrt/dynamic_cast.cc | 210 ++ src/libs/libcxxrt/exception.cc | 1542 ++++++++++ src/libs/libcxxrt/guard.cc | 193 ++ src/libs/libcxxrt/libelftc_dem_gnu3.c | 3893 ++++++++++++++++++++++++ src/libs/libcxxrt/memory.cc | 154 + src/libs/libcxxrt/stdexcept.cc | 99 + src/libs/libcxxrt/terminate.cc | 40 + src/libs/libcxxrt/typeinfo.cc | 132 + 24 files changed, 8113 insertions(+) create mode 100644 headers/libs/libcxxrt/abi_namespace.h create mode 100644 headers/libs/libcxxrt/atomic.h create mode 100644 headers/libs/libcxxrt/cxxabi.h create mode 100644 headers/libs/libcxxrt/dwarf_eh.h create mode 100644 headers/libs/libcxxrt/stdexcept.h create mode 100644 headers/libs/libcxxrt/typeinfo.h create mode 100644 headers/libs/libcxxrt/unwind-arm.h create mode 100644 headers/libs/libcxxrt/unwind-itanium.h create mode 100644 headers/libs/libcxxrt/unwind.h create mode 100644 src/libs/libcxxrt/AUTHORS create mode 100644 src/libs/libcxxrt/COPYRIGHT create mode 100644 src/libs/libcxxrt/LICENSE create mode 100644 src/libs/libcxxrt/README create mode 100644 src/libs/libcxxrt/auxhelper.cc create mode 100644 src/libs/libcxxrt/cxa_atexit.c create mode 100644 src/libs/libcxxrt/cxa_finalize.c create mode 100644 src/libs/libcxxrt/dynamic_cast.cc create mode 100644 src/libs/libcxxrt/exception.cc create mode 100644 src/libs/libcxxrt/guard.cc create mode 100644 src/libs/libcxxrt/libelftc_dem_gnu3.c create mode 100644 src/libs/libcxxrt/memory.cc create mode 100644 src/libs/libcxxrt/stdexcept.cc create mode 100644 src/libs/libcxxrt/terminate.cc create mode 100644 src/libs/libcxxrt/typeinfo.cc diff --git a/headers/libs/libcxxrt/abi_namespace.h b/headers/libs/libcxxrt/abi_namespace.h new file mode 100644 index 0000000000..dda788da19 --- /dev/null +++ b/headers/libs/libcxxrt/abi_namespace.h @@ -0,0 +1,5 @@ +/** + * The namespace used for the ABI declarations. This is currently defined to + * be the same as GNU libsupc++, however this may change in the future. + */ +#define ABI_NAMESPACE __cxxabiv1 diff --git a/headers/libs/libcxxrt/atomic.h b/headers/libs/libcxxrt/atomic.h new file mode 100644 index 0000000000..131ca9f577 --- /dev/null +++ b/headers/libs/libcxxrt/atomic.h @@ -0,0 +1,30 @@ + +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif +#ifndef __has_feature +#define __has_feature(x) 0 +#endif +/** + * Swap macro that enforces a happens-before relationship with a corresponding + * ATOMIC_LOAD. + */ +#if __has_builtin(__c11_atomic_exchange) +#define ATOMIC_SWAP(addr, val)\ + __c11_atomic_exchange(reinterpret_cast<_Atomic(__typeof__(val))*>(addr), val, __ATOMIC_ACQ_REL) +#elif __has_builtin(__sync_swap) +#define ATOMIC_SWAP(addr, val)\ + __sync_swap(addr, val) +#else +#define ATOMIC_SWAP(addr, val)\ + __sync_lock_test_and_set(addr, val) +#endif + +#if __has_builtin(__c11_atomic_load) +#define ATOMIC_LOAD(addr)\ + __c11_atomic_load(reinterpret_cast<_Atomic(__typeof__(*addr))*>(addr), __ATOMIC_ACQUIRE) +#else +#define ATOMIC_LOAD(addr)\ + (__sync_synchronize(), *addr) +#endif + diff --git a/headers/libs/libcxxrt/cxxabi.h b/headers/libs/libcxxrt/cxxabi.h new file mode 100644 index 0000000000..411c4c749c --- /dev/null +++ b/headers/libs/libcxxrt/cxxabi.h @@ -0,0 +1,244 @@ +/* + * Copyright 2012 David Chisnall. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __CXXABI_H_ +#define __CXXABI_H_ +#include +#include +#include "unwind.h" +namespace std +{ + class type_info; +} +/* + * The cxxabi.h header provides a set of public definitions for types and + * functions defined by the Itanium C++ ABI specification. For reference, see + * the ABI specification here: + * + * http://sourcery.mentor.com/public/cxx-abi/abi.html + * + * All deviations from this specification, unless otherwise noted, are + * accidental. + */ + +#ifdef __cplusplus +namespace __cxxabiv1 { +extern "C" { +#endif +/** + * Function type to call when an unexpected exception is encountered. + */ +typedef void (*unexpected_handler)(); +/** + * Function type to call when an unrecoverable condition is encountered. + */ +typedef void (*terminate_handler)(); + + +/** + * Structure used as a header on thrown exceptions. This is the same layout as + * defined by the Itanium ABI spec, so should be interoperable with any other + * implementation of this spec, such as GNU libsupc++. + * + * This structure is allocated when an exception is thrown. Unwinding happens + * in two phases, the first looks for a handler and the second installs the + * context. This structure stores a cache of the handler location between + * phase 1 and phase 2. Unfortunately, cleanup information is not cached, so + * must be looked up in both phases. This happens for two reasons. The first + * is that we don't know how many frames containing cleanups there will be, and + * we should avoid dynamic allocation during unwinding (the exception may be + * reporting that we've run out of memory). The second is that finding + * cleanups is much cheaper than finding handlers, because we don't have to + * look at the type table at all. + * + * Note: Several fields of this structure have not-very-informative names. + * These are taken from the ABI spec and have not been changed to make it + * easier for people referring to to the spec while reading this code. + */ +struct __cxa_exception +{ +#if __LP64__ + /** + * Reference count. Used to support the C++11 exception_ptr class. This + * is prepended to the structure in 64-bit mode and squeezed in to the + * padding left before the 64-bit aligned _Unwind_Exception at the end in + * 32-bit mode. + * + * Note that it is safe to extend this structure at the beginning, rather + * than the end, because the public API for creating it returns the address + * of the end (where the exception object can be stored). + */ + uintptr_t referenceCount; +#endif + /** Type info for the thrown object. */ + std::type_info *exceptionType; + /** Destructor for the object, if one exists. */ + void (*exceptionDestructor) (void *); + /** Handler called when an exception specification is violated. */ + unexpected_handler unexpectedHandler; + /** Hander called to terminate. */ + terminate_handler terminateHandler; + /** + * Next exception in the list. If an exception is thrown inside a catch + * block and caught in a nested catch, this points to the exception that + * will be handled after the inner catch block completes. + */ + __cxa_exception *nextException; + /** + * The number of handlers that currently have references to this + * exception. The top (non-sign) bit of this is used as a flag to indicate + * that the exception is being rethrown, so should not be deleted when its + * handler count reaches 0 (which it doesn't with the top bit set). + */ + int handlerCount; +#if defined(__arm__) && !defined(__ARM_DWARF_EH__) + /** + * The ARM EH ABI requires the unwind library to keep track of exceptions + * during cleanups. These support nesting, so we need to keep a list of + * them. + */ + _Unwind_Exception *nextCleanup; + /** + * The number of cleanups that are currently being run on this exception. + */ + int cleanupCount; +#endif + /** + * The selector value to be returned when installing the catch handler. + * Used at the call site to determine which catch() block should execute. + * This is found in phase 1 of unwinding then installed in phase 2. + */ + int handlerSwitchValue; + /** + * The action record for the catch. This is cached during phase 1 + * unwinding. + */ + const char *actionRecord; + /** + * Pointer to the language-specific data area (LSDA) for the handler + * frame. This is unused in this implementation, but set for ABI + * compatibility in case we want to mix code in very weird ways. + */ + const char *languageSpecificData; + /** The cached landing pad for the catch handler.*/ + void *catchTemp; + /** + * The pointer that will be returned as the pointer to the object. When + * throwing a class and catching a virtual superclass (for example), we + * need to adjust the thrown pointer to make it all work correctly. + */ + void *adjustedPtr; +#if !__LP64__ + /** + * Reference count. Used to support the C++11 exception_ptr class. This + * is prepended to the structure in 64-bit mode and squeezed in to the + * padding left before the 64-bit aligned _Unwind_Exception at the end in + * 32-bit mode. + * + * Note that it is safe to extend this structure at the beginning, rather + * than the end, because the public API for creating it returns the address + * of the end (where the exception object can be stored) + */ + uintptr_t referenceCount; +#endif + /** The language-agnostic part of the exception header. */ + _Unwind_Exception unwindHeader; +}; + +/** + * ABI-specified globals structure. Returned by the __cxa_get_globals() + * function and its fast variant. This is a per-thread structure - every + * thread will have one lazily allocated. + * + * This structure is defined by the ABI, so may be used outside of this + * library. + */ +struct __cxa_eh_globals +{ + /** + * A linked list of exceptions that are currently caught. There may be + * several of these in nested catch() blocks. + */ + __cxa_exception *caughtExceptions; + /** + * The number of uncaught exceptions. + */ + unsigned int uncaughtExceptions; +}; +/** + * ABI function returning the __cxa_eh_globals structure. + */ +__cxa_eh_globals *__cxa_get_globals(void); +/** + * Version of __cxa_get_globals() assuming that __cxa_get_globals() has already + * been called at least once by this thread. + */ +__cxa_eh_globals *__cxa_get_globals_fast(void); + +std::type_info * __cxa_current_exception_type(); + +/** + * Throws an exception returned by __cxa_current_primary_exception(). This + * exception may have been caught in another thread. + */ +void __cxa_rethrow_primary_exception(void* thrown_exception); +/** + * Returns the current exception in a form that can be stored in an + * exception_ptr object and then rethrown by a call to + * __cxa_rethrow_primary_exception(). + */ +void *__cxa_current_primary_exception(void); +/** + * Increments the reference count of an exception. Called when an + * exception_ptr is copied. + */ +void __cxa_increment_exception_refcount(void* thrown_exception); +/** + * Decrements the reference count of an exception. Called when an + * exception_ptr is deleted. + */ +void __cxa_decrement_exception_refcount(void* thrown_exception); +/** + * Demangles a C++ symbol or type name. The buffer, if non-NULL, must be + * allocated with malloc() and must be *n bytes or more long. This function + * may call realloc() on the value pointed to by buf, and will return the + * length of the string via *n. + * + * The value pointed to by status is set to one of the following: + * + * 0: success + * -1: memory allocation failure + * -2: invalid mangled name + * -3: invalid arguments + */ +char* __cxa_demangle(const char* mangled_name, + char* buf, + size_t* n, + int* status); +#ifdef __cplusplus +} // extern "C" +} // namespace + +namespace abi = __cxxabiv1; + +#endif /* __cplusplus */ +#endif /* __CXXABI_H_ */ diff --git a/headers/libs/libcxxrt/dwarf_eh.h b/headers/libs/libcxxrt/dwarf_eh.h new file mode 100644 index 0000000000..da86846abf --- /dev/null +++ b/headers/libs/libcxxrt/dwarf_eh.h @@ -0,0 +1,477 @@ +/* + * Copyright 2010-2011 PathScale, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/** + * dwarf_eh.h - Defines some helper functions for parsing DWARF exception + * handling tables. + * + * This file contains various helper functions that are independent of the + * language-specific code. It can be used in any personality function for the + * Itanium ABI. + */ +#include + +// TODO: Factor out Itanium / ARM differences. We probably want an itanium.h +// and arm.h that can be included by this file depending on the target ABI. + +// _GNU_SOURCE must be defined for unwind.h to expose some of the functions +// that we want. If it isn't, then we define it and undefine it to make sure +// that it doesn't impact the rest of the program. +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +# include "unwind.h" +# undef _GNU_SOURCE +#else +# include "unwind.h" +#endif + +#include + +/// Type used for pointers into DWARF data +typedef unsigned char *dw_eh_ptr_t; + +// Flag indicating a signed quantity +#define DW_EH_PE_signed 0x08 +/// DWARF data encoding types. +enum dwarf_data_encoding +{ + /// Absolute pointer value + DW_EH_PE_absptr = 0x00, + /// Unsigned, little-endian, base 128-encoded (variable length). + DW_EH_PE_uleb128 = 0x01, + /// Unsigned 16-bit integer. + DW_EH_PE_udata2 = 0x02, + /// Unsigned 32-bit integer. + DW_EH_PE_udata4 = 0x03, + /// Unsigned 64-bit integer. + DW_EH_PE_udata8 = 0x04, + /// Signed, little-endian, base 128-encoded (variable length) + DW_EH_PE_sleb128 = DW_EH_PE_uleb128 | DW_EH_PE_signed, + /// Signed 16-bit integer. + DW_EH_PE_sdata2 = DW_EH_PE_udata2 | DW_EH_PE_signed, + /// Signed 32-bit integer. + DW_EH_PE_sdata4 = DW_EH_PE_udata4 | DW_EH_PE_signed, + /// Signed 32-bit integer. + DW_EH_PE_sdata8 = DW_EH_PE_udata8 | DW_EH_PE_signed +}; + +/** + * Returns the encoding for a DWARF EH table entry. The encoding is stored in + * the low four of an octet. The high four bits store the addressing mode. + */ +static inline enum dwarf_data_encoding get_encoding(unsigned char x) +{ + return static_cast(x & 0xf); +} + +/** + * DWARF addressing mode constants. When reading a pointer value from a DWARF + * exception table, you must know how it is stored and what the addressing mode + * is. The low four bits tell you the encoding, allowing you to decode a + * number. The high four bits tell you the addressing mode, allowing you to + * turn that number into an address in memory. + */ +enum dwarf_data_relative +{ + /// Value is omitted + DW_EH_PE_omit = 0xff, + /// Value relative to program counter + DW_EH_PE_pcrel = 0x10, + /// Value relative to the text segment + DW_EH_PE_textrel = 0x20, + /// Value relative to the data segment + DW_EH_PE_datarel = 0x30, + /// Value relative to the start of the function + DW_EH_PE_funcrel = 0x40, + /// Aligned pointer (Not supported yet - are they actually used?) + DW_EH_PE_aligned = 0x50, + /// Pointer points to address of real value + DW_EH_PE_indirect = 0x80 +}; +/** + * Returns the addressing mode component of this encoding. + */ +static inline enum dwarf_data_relative get_base(unsigned char x) +{ + return static_cast(x & 0x70); +} +/** + * Returns whether an encoding represents an indirect address. + */ +static int is_indirect(unsigned char x) +{ + return ((x & DW_EH_PE_indirect) == DW_EH_PE_indirect); +} + +/** + * Returns the size of a fixed-size encoding. This function will abort if + * called with a value that is not a fixed-size encoding. + */ +static inline int dwarf_size_of_fixed_size_field(unsigned char type) +{ + switch (get_encoding(type)) + { + default: abort(); + case DW_EH_PE_sdata2: + case DW_EH_PE_udata2: return 2; + case DW_EH_PE_sdata4: + case DW_EH_PE_udata4: return 4; + case DW_EH_PE_sdata8: + case DW_EH_PE_udata8: return 8; + case DW_EH_PE_absptr: return sizeof(void*); + } +} + +/** + * Read an unsigned, little-endian, base-128, DWARF value. Updates *data to + * point to the end of the value. Stores the number of bits read in the value + * pointed to by b, allowing you to determine the value of the highest bit, and + * therefore the sign of a signed value. + * + * This function is not intended to be called directly. Use read_sleb128() or + * read_uleb128() for reading signed and unsigned versions, respectively. + */ +static uint64_t read_leb128(dw_eh_ptr_t *data, int *b) +{ + uint64_t uleb = 0; + unsigned int bit = 0; + unsigned char digit = 0; + // We have to read at least one octet, and keep reading until we get to one + // with the high bit unset + do + { + // This check is a bit too strict - we should also check the highest + // bit of the digit. + assert(bit < sizeof(uint64_t) * 8); + // Get the base 128 digit + digit = (**data) & 0x7f; + // Add it to the current value + uleb += digit << bit; + // Increase the shift value + bit += 7; + // Proceed to the next octet + (*data)++; + // Terminate when we reach a value that does not have the high bit set + // (i.e. which was not modified when we mask it with 0x7f) + } while ((*(*data - 1)) != digit); + *b = bit; + + return uleb; +} + +/** + * Reads an unsigned little-endian base-128 value starting at the address + * pointed to by *data. Updates *data to point to the next byte after the end + * of the variable-length value. + */ +static int64_t read_uleb128(dw_eh_ptr_t *data) +{ + int b; + return read_leb128(data, &b); +} + +/** + * Reads a signed little-endian base-128 value starting at the address pointed + * to by *data. Updates *data to point to the next byte after the end of the + * variable-length value. + */ +static int64_t read_sleb128(dw_eh_ptr_t *data) +{ + int bits; + // Read as if it's signed + uint64_t uleb = read_leb128(data, &bits); + // If the most significant bit read is 1, then we need to sign extend it + if ((uleb >> (bits-1)) == 1) + { + // Sign extend by setting all bits in front of it to 1 + uleb |= static_cast(-1) << bits; + } + return static_cast(uleb); +} +/** + * Reads a value using the specified encoding from the address pointed to by + * *data. Updates the value of *data to point to the next byte after the end + * of the data. + */ +static uint64_t read_value(char encoding, dw_eh_ptr_t *data) +{ + enum dwarf_data_encoding type = get_encoding(encoding); + switch (type) + { + // Read fixed-length types +#define READ(dwarf, type) \ + case dwarf:\ + {\ + type t;\ + memcpy(&t, *data, sizeof t);\ + *data += sizeof t;\ + return static_cast(t);\ + } + READ(DW_EH_PE_udata2, uint16_t) + READ(DW_EH_PE_udata4, uint32_t) + READ(DW_EH_PE_udata8, uint64_t) + READ(DW_EH_PE_sdata2, int16_t) + READ(DW_EH_PE_sdata4, int32_t) + READ(DW_EH_PE_sdata8, int64_t) + READ(DW_EH_PE_absptr, intptr_t) +#undef READ + // Read variable-length types + case DW_EH_PE_sleb128: + return read_sleb128(data); + case DW_EH_PE_uleb128: + return read_uleb128(data); + default: abort(); + } +} + +/** + * Resolves an indirect value. This expects an unwind context, an encoding, a + * decoded value, and the start of the region as arguments. The returned value + * is a pointer to the address identified by the encoded value. + * + * If the encoding does not specify an indirect value, then this returns v. + */ +static uint64_t resolve_indirect_value(_Unwind_Context *c, + unsigned char encoding, + int64_t v, + dw_eh_ptr_t start) +{ + switch (get_base(encoding)) + { + case DW_EH_PE_pcrel: + v += reinterpret_cast(start); + break; + case DW_EH_PE_textrel: + v += static_cast(static_cast(_Unwind_GetTextRelBase(c))); + break; + case DW_EH_PE_datarel: + v += static_cast(static_cast(_Unwind_GetDataRelBase(c))); + break; + case DW_EH_PE_funcrel: + v += static_cast(static_cast(_Unwind_GetRegionStart(c))); + default: + break; + } + // If this is an indirect value, then it is really the address of the real + // value + // TODO: Check whether this should really always be a pointer - it seems to + // be a GCC extensions, so not properly documented... + if (is_indirect(encoding)) + { + v = static_cast(reinterpret_cast(*reinterpret_cast(v))); + } + return v; +} + + +/** + * Reads an encoding and a value, updating *data to point to the next byte. + */ +static inline void read_value_with_encoding(_Unwind_Context *context, + dw_eh_ptr_t *data, + uint64_t *out) +{ + dw_eh_ptr_t start = *data; + unsigned char encoding = *((*data)++); + // If this value is omitted, skip it and don't touch the output value + if (encoding == DW_EH_PE_omit) { return; } + + *out = read_value(encoding, data); + *out = resolve_indirect_value(context, encoding, *out, start); +} + +/** + * Structure storing a decoded language-specific data area. Use parse_lsda() + * to generate an instance of this structure from the address returned by the + * generic unwind library. + * + * You should not need to inspect the fields of this structure directly if you + * are just using this header. The structure stores the locations of the + * various tables used for unwinding exceptions and is used by the functions + * for reading values from these tables. + */ +struct dwarf_eh_lsda +{ + /// The start of the region. This is a cache of the value returned by + /// _Unwind_GetRegionStart(). + dw_eh_ptr_t region_start; + /// The start of the landing pads table. + dw_eh_ptr_t landing_pads; + /// The start of the type table. + dw_eh_ptr_t type_table; + /// The encoding used for entries in the type tables. + unsigned char type_table_encoding; + /// The location of the call-site table. + dw_eh_ptr_t call_site_table; + /// The location of the action table. + dw_eh_ptr_t action_table; + /// The encoding used for entries in the call-site table. + unsigned char callsite_encoding; +}; + +/** + * Parse the header on the language-specific data area and return a structure + * containing the addresses and encodings of the various tables. + */ +static inline struct dwarf_eh_lsda parse_lsda(_Unwind_Context *context, + unsigned char *data) +{ + struct dwarf_eh_lsda lsda; + + lsda.region_start = reinterpret_cast(_Unwind_GetRegionStart(context)); + + // If the landing pads are relative to anything other than the start of + // this region, find out where. This is @LPStart in the spec, although the + // encoding that GCC uses does not quite match the spec. + uint64_t v = static_cast(reinterpret_cast(lsda.region_start)); + read_value_with_encoding(context, &data, &v); + lsda.landing_pads = reinterpret_cast(static_cast(v)); + + // If there is a type table, find out where it is. This is @TTBase in the + // spec. Note: we find whether there is a type table pointer by checking + // whether the leading byte is DW_EH_PE_omit (0xff), which is not what the + // spec says, but does seem to be how G++ indicates this. + lsda.type_table = 0; + lsda.type_table_encoding = *data++; + if (lsda.type_table_encoding != DW_EH_PE_omit) + { + v = read_uleb128(&data); + dw_eh_ptr_t type_table = data; + type_table += v; + lsda.type_table = type_table; + //lsda.type_table = (uintptr_t*)(data + v); + } +#if defined(__arm__) && !defined(__ARM_DWARF_EH__) + lsda.type_table_encoding = (DW_EH_PE_pcrel | DW_EH_PE_indirect); +#endif + + lsda.callsite_encoding = static_cast(*(data++)); + + // Action table is immediately after the call site table + lsda.action_table = data; + uintptr_t callsite_size = static_cast(read_uleb128(&data)); + lsda.action_table = data + callsite_size; + // Call site table is immediately after the header + lsda.call_site_table = static_cast(data); + + + return lsda; +} + +/** + * Structure representing an action to be performed while unwinding. This + * contains the address that should be unwound to and the action record that + * provoked this action. + */ +struct dwarf_eh_action +{ + /** + * The address that this action directs should be the new program counter + * value after unwinding. + */ + dw_eh_ptr_t landing_pad; + /// The address of the action record. + dw_eh_ptr_t action_record; +}; + +/** + * Look up the landing pad that corresponds to the current invoke. + * Returns true if record exists. The context is provided by the generic + * unwind library and the lsda should be the result of a call to parse_lsda(). + * + * The action record is returned via the result parameter. + */ +static bool dwarf_eh_find_callsite(struct _Unwind_Context *context, + struct dwarf_eh_lsda *lsda, + struct dwarf_eh_action *result) +{ + result->action_record = 0; + result->landing_pad = 0; + // The current instruction pointer offset within the region + uint64_t ip = _Unwind_GetIP(context) - _Unwind_GetRegionStart(context); + unsigned char *callsite_table = static_cast(lsda->call_site_table); + + while (callsite_table <= lsda->action_table) + { + // Once again, the layout deviates from the spec. + uint64_t call_site_start, call_site_size, landing_pad, action; + call_site_start = read_value(lsda->callsite_encoding, &callsite_table); + call_site_size = read_value(lsda->callsite_encoding, &callsite_table); + + // Call site entries are sorted, so if we find a call site that's after + // the current instruction pointer then there is no action associated + // with this call and we should unwind straight through this frame + // without doing anything. + if (call_site_start > ip) { break; } + + // Read the address of the landing pad and the action from the call + // site table. + landing_pad = read_value(lsda->callsite_encoding, &callsite_table); + action = read_uleb128(&callsite_table); + + // We should not include the call_site_start (beginning of the region) + // address in the ip range. For each call site: + // + // address1: call proc + // address2: next instruction + // + // The call stack contains address2 and not address1, address1 can be + // at the end of another EH region. + if (call_site_start < ip && ip <= call_site_start + call_site_size) + { + if (action) + { + // Action records are 1-biased so both no-record and zeroth + // record can be stored. + result->action_record = lsda->action_table + action - 1; + } + // No landing pad means keep unwinding. + if (landing_pad) + { + // Landing pad is the offset from the value in the header + result->landing_pad = lsda->landing_pads + landing_pad; + } + return true; + } + } + return false; +} + +/// Defines an exception class from 8 bytes (endian independent) +#define EXCEPTION_CLASS(a,b,c,d,e,f,g,h) \ + ((static_cast(a) << 56) +\ + (static_cast(b) << 48) +\ + (static_cast(c) << 40) +\ + (static_cast(d) << 32) +\ + (static_cast(e) << 24) +\ + (static_cast(f) << 16) +\ + (static_cast(g) << 8) +\ + (static_cast(h))) + +#define GENERIC_EXCEPTION_CLASS(e,f,g,h) \ + (static_cast(e) << 24) +\ + (static_cast(f) << 16) +\ + (static_cast(g) << 8) +\ + (static_cast(h)) diff --git a/headers/libs/libcxxrt/stdexcept.h b/headers/libs/libcxxrt/stdexcept.h new file mode 100644 index 0000000000..8920393575 --- /dev/null +++ b/headers/libs/libcxxrt/stdexcept.h @@ -0,0 +1,96 @@ +/* + * Copyright 2010-2011 PathScale, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * stdexcept.h - provides a stub version of , which defines enough + * of the exceptions for the runtime to use. + */ + +namespace std +{ + + class exception + { + public: + exception() throw(); + exception(const exception&) throw(); + exception& operator=(const exception&) throw(); + virtual ~exception(); + virtual const char* what() const throw(); + }; + + + /** + * Bad allocation exception. Thrown by ::operator new() if it fails. + */ + class bad_alloc: public exception + { + public: + bad_alloc() throw(); + bad_alloc(const bad_alloc&) throw(); + bad_alloc& operator=(const bad_alloc&) throw(); + ~bad_alloc(); + virtual const char* what() const throw(); + }; + + /** + * Bad cast exception. Thrown by the __cxa_bad_cast() helper function. + */ + class bad_cast: public exception { + public: + bad_cast() throw(); + bad_cast(const bad_cast&) throw(); + bad_cast& operator=(const bad_cast&) throw(); + virtual ~bad_cast(); + virtual const char* what() const throw(); + }; + + /** + * Bad typeidexception. Thrown by the __cxa_bad_typeid() helper function. + */ + class bad_typeid: public exception + { + public: + bad_typeid() throw(); + bad_typeid(const bad_typeid &__rhs) throw(); + virtual ~bad_typeid(); + bad_typeid& operator=(const bad_typeid &__rhs) throw(); + virtual const char* what() const throw(); + }; + + class bad_array_new_length: public bad_alloc + { + public: + bad_array_new_length() throw(); + bad_array_new_length(const bad_array_new_length&) throw(); + bad_array_new_length& operator=(const bad_array_new_length&) throw(); + virtual ~bad_array_new_length(); + virtual const char *what() const throw(); + }; + + +} // namespace std + diff --git a/headers/libs/libcxxrt/typeinfo.h b/headers/libs/libcxxrt/typeinfo.h new file mode 100644 index 0000000000..a8a1a980e9 --- /dev/null +++ b/headers/libs/libcxxrt/typeinfo.h @@ -0,0 +1,313 @@ +/* + * Copyright 2010-2011 PathScale, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "abi_namespace.h" + +namespace ABI_NAMESPACE +{ + struct __class_type_info; +} +namespace std +{ + /** + * Standard type info class. The layout of this class is specified by the + * ABI. The layout of the vtable is not, but is intended to be + * compatible with the GNU ABI. + * + * Unlike the GNU version, the vtable layout is considered semi-private. + */ + class type_info + { + public: + /** + * Virtual destructor. This class must have one virtual function to + * ensure that it has a vtable. + */ + virtual ~type_info(); + bool operator==(const type_info &) const; + bool operator!=(const type_info &) const; + bool before(const type_info &) const; + const char* name() const; + type_info(); + private: + type_info(const type_info& rhs); + type_info& operator= (const type_info& rhs); + const char *__type_name; + /* + * The following functions are in this order to match the + * vtable layout of libsupc++. This allows libcxxrt to be used + * with libraries that depend on this. + * + * These functions are in the public headers for libstdc++, so + * we have to assume that someone will probably call them and + * expect them to work. Their names must also match the names used in + * libsupc++, so that code linking against this library can subclass + * type_info and correctly fill in the values in the vtables. + */ + public: + /** + * Returns true if this is some pointer type, false otherwise. + */ + virtual bool __is_pointer_p() const { return false; } + /** + * Returns true if this is some function type, false otherwise. + */ + virtual bool __is_function_p() const { return false; } + /** + * Catch function. Allows external libraries to implement + * their own basic types. This is used, for example, in the + * GNUstep Objective-C runtime to allow Objective-C types to be + * caught in G++ catch blocks. + * + * The outer parameter indicates the number of outer pointers + * in the high bits. The low bit indicates whether the + * pointers are const qualified. + */ + virtual bool __do_catch(const type_info *thrown_type, + void **thrown_object, + unsigned outer) const; + /** + * Performs an upcast. This is used in exception handling to + * cast from subclasses to superclasses. If the upcast is + * possible, it returns true and adjusts the pointer. If the + * upcast is not possible, it returns false and does not adjust + * the pointer. + */ + virtual bool __do_upcast( + const ABI_NAMESPACE::__class_type_info *target, + void **thrown_object) const + { + return false; + } + }; +} + + +namespace ABI_NAMESPACE +{ + /** + * Primitive type info, for intrinsic types. + */ + struct __fundamental_type_info : public std::type_info + { + virtual ~__fundamental_type_info(); + }; + /** + * Type info for arrays. + */ + struct __array_type_info : public std::type_info + { + virtual ~__array_type_info(); + }; + /** + * Type info for functions. + */ + struct __function_type_info : public std::type_info + { + virtual ~__function_type_info(); + virtual bool __is_function_p() const { return true; } + }; + /** + * Type info for enums. + */ + struct __enum_type_info : public std::type_info + { + virtual ~__enum_type_info(); + }; + + /** + * Base class for class type info. Used only for tentative definitions. + */ + struct __class_type_info : public std::type_info + { + virtual ~__class_type_info(); + /** + * Function implementing dynamic casts. + */ + virtual void *cast_to(void *obj, const struct __class_type_info *other) const; + virtual bool __do_upcast(const __class_type_info *target, + void **thrown_object) const + { + return this == target; + } + }; + + /** + * Single-inheritance class type info. This is used for classes containing + * a single non-virtual base class at offset 0. + */ + struct __si_class_type_info : public __class_type_info + { + virtual ~__si_class_type_info(); + const __class_type_info *__base_type; + virtual bool __do_upcast( + const ABI_NAMESPACE::__class_type_info *target, + void **thrown_object) const; + virtual void *cast_to(void *obj, const struct __class_type_info *other) const; + }; + + /** + * Type info for base classes. Classes with multiple bases store an array + * of these, one for each superclass. + */ + struct __base_class_type_info + { + const __class_type_info *__base_type; + private: + /** + * The high __offset_shift bits of this store the (signed) offset + * of the base class. The low bits store flags from + * __offset_flags_masks. + */ + long __offset_flags; + /** + * Flags used in the low bits of __offset_flags. + */ + enum __offset_flags_masks + { + /** This base class is virtual. */ + __virtual_mask = 0x1, + /** This base class is public. */ + __public_mask = 0x2, + /** The number of bits reserved for flags. */ + __offset_shift = 8 + }; + public: + /** + * Returns the offset of the base class. + */ + long offset() const + { + return __offset_flags >> __offset_shift; + } + /** + * Returns the flags. + */ + long flags() const + { + return __offset_flags & ((1 << __offset_shift) - 1); + } + /** + * Returns whether this is a public base class. + */ + bool isPublic() const { return flags() & __public_mask; } + /** + * Returns whether this is a virtual base class. + */ + bool isVirtual() const { return flags() & __virtual_mask; } + }; + + /** + * Type info for classes with virtual bases or multiple superclasses. + */ + struct __vmi_class_type_info : public __class_type_info + { + virtual ~__vmi_class_type_info(); + /** Flags describing this class. Contains values from __flags_masks. */ + unsigned int __flags; + /** The number of base classes. */ + unsigned int __base_count; + /** + * Array of base classes - this actually has __base_count elements, not + * 1. + */ + __base_class_type_info __base_info[1]; + + /** + * Flags used in the __flags field. + */ + enum __flags_masks + { + /** The class has non-diamond repeated inheritance. */ + __non_diamond_repeat_mask = 0x1, + /** The class is diamond shaped. */ + __diamond_shaped_mask = 0x2 + }; + virtual bool __do_upcast( + const ABI_NAMESPACE::__class_type_info *target, + void **thrown_object) const; + virtual void *cast_to(void *obj, const struct __class_type_info *other) const; + }; + + /** + * Base class used for both pointer and pointer-to-member type info. + */ + struct __pbase_type_info : public std::type_info + { + virtual ~__pbase_type_info(); + /** + * Flags. Values from __masks. + */ + unsigned int __flags; + /** + * The type info for the pointee. + */ + const std::type_info *__pointee; + + /** + * Masks used for qualifiers on the pointer. + */ + enum __masks + { + /** Pointer has const qualifier. */ + __const_mask = 0x1, + /** Pointer has volatile qualifier. */ + __volatile_mask = 0x2, + /** Pointer has restrict qualifier. */ + __restrict_mask = 0x4, + /** Pointer points to an incomplete type. */ + __incomplete_mask = 0x8, + /** Pointer is a pointer to a member of an incomplete class. */ + __incomplete_class_mask = 0x10 + }; + virtual bool __do_catch(const type_info *thrown_type, + void **thrown_object, + unsigned outer) const; + }; + + /** + * Pointer type info. + */ + struct __pointer_type_info : public __pbase_type_info + { + virtual ~__pointer_type_info(); + virtual bool __is_pointer_p() const { return true; } + }; + + /** + * Pointer to member type info. + */ + struct __pointer_to_member_type_info : public __pbase_type_info + { + virtual ~__pointer_to_member_type_info(); + /** + * Pointer to the class containing this member. + */ + const __class_type_info *__context; + }; + +} diff --git a/headers/libs/libcxxrt/unwind-arm.h b/headers/libs/libcxxrt/unwind-arm.h new file mode 100644 index 0000000000..52e563e41b --- /dev/null +++ b/headers/libs/libcxxrt/unwind-arm.h @@ -0,0 +1,223 @@ +/* + * Copyright 2012 David Chisnall. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * ARM-specific unwind definitions. These are taken from the ARM EHABI + * specification. + */ + typedef enum +{ + _URC_OK = 0, /* operation completed successfully */ + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + _URC_END_OF_STACK = 5, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8, + _URC_FAILURE = 9, /* unspecified failure of some kind */ + _URC_FATAL_PHASE1_ERROR = _URC_FAILURE +} _Unwind_Reason_Code; + +typedef uint32_t _Unwind_State; +#ifdef __clang__ +static const _Unwind_State _US_VIRTUAL_UNWIND_FRAME = 0; +static const _Unwind_State _US_UNWIND_FRAME_STARTING = 1; +static const _Unwind_State _US_UNWIND_FRAME_RESUME = 2; +#else // GCC fails at knowing what a constant expression is +# define _US_VIRTUAL_UNWIND_FRAME 0 +# define _US_UNWIND_FRAME_STARTING 1 +# define _US_UNWIND_FRAME_RESUME 2 +#endif + +typedef struct _Unwind_Context _Unwind_Context; + +typedef uint32_t _Unwind_EHT_Header; + +struct _Unwind_Exception +{ + uint64_t exception_class; + void (*exception_cleanup)(_Unwind_Reason_Code, struct _Unwind_Exception *); + /* Unwinder cache, private fields for the unwinder's use */ + struct + { + uint32_t reserved1; + uint32_t reserved2; + uint32_t reserved3; + uint32_t reserved4; + uint32_t reserved5; + /* init reserved1 to 0, then don't touch */ + } unwinder_cache; + /* Propagation barrier cache (valid after phase 1): */ + struct + { + uint32_t sp; + uint32_t bitpattern[5]; + } barrier_cache; + /* Cleanup cache (preserved over cleanup): */ + struct + { + uint32_t bitpattern[4]; + } cleanup_cache; + /* Pr cache (for pr's benefit): */ + struct + { + /** function start address */ + uint32_t fnstart; + /** pointer to EHT entry header word */ + _Unwind_EHT_Header *ehtp; + /** additional data */ + uint32_t additional; + uint32_t reserved1; + } pr_cache; + /** Force alignment of next item to 8-byte boundary */ + long long int :0; +}; + +/* Unwinding functions */ +_Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *ucbp); +void _Unwind_Resume(struct _Unwind_Exception *ucbp); +void _Unwind_Complete(struct _Unwind_Exception *ucbp); +void _Unwind_DeleteException(struct _Unwind_Exception *ucbp); +void *_Unwind_GetLanguageSpecificData(struct _Unwind_Context*); + +typedef enum +{ + _UVRSR_OK = 0, + _UVRSR_NOT_IMPLEMENTED = 1, + _UVRSR_FAILED = 2 +} _Unwind_VRS_Result; +typedef enum +{ + _UVRSC_CORE = 0, + _UVRSC_VFP = 1, + _UVRSC_WMMXD = 3, + _UVRSC_WMMXC = 4 +} _Unwind_VRS_RegClass; +typedef enum +{ + _UVRSD_UINT32 = 0, + _UVRSD_VFPX = 1, + _UVRSD_UINT64 = 3, + _UVRSD_FLOAT = 4, + _UVRSD_DOUBLE = 5 +} _Unwind_VRS_DataRepresentation; + +_Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context *context, + _Unwind_VRS_RegClass regclass, + uint32_t regno, + _Unwind_VRS_DataRepresentation representation, + void *valuep); +_Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *context, + _Unwind_VRS_RegClass regclass, + uint32_t regno, + _Unwind_VRS_DataRepresentation representation, + void *valuep); + +/* Return the base-address for data references. */ +extern unsigned long _Unwind_GetDataRelBase(struct _Unwind_Context *); + +/* Return the base-address for text references. */ +extern unsigned long _Unwind_GetTextRelBase(struct _Unwind_Context *); +extern unsigned long _Unwind_GetRegionStart(struct _Unwind_Context *); + +typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (struct _Unwind_Context *, + void *); +extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *); +extern _Unwind_Reason_Code + _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *); + +/** + * The next set of functions are compatibility extensions, implementing Itanium + * ABI functions on top of ARM ones. + */ + +#define _UA_SEARCH_PHASE 1 +#define _UA_CLEANUP_PHASE 2 +#define _UA_HANDLER_FRAME 4 +#define _UA_FORCE_UNWIND 8 + +static inline unsigned long _Unwind_GetGR(struct _Unwind_Context *context, int reg) +{ + unsigned long val; + _Unwind_VRS_Get(context, _UVRSC_CORE, reg, _UVRSD_UINT32, &val); + return val; +} +static inline void _Unwind_SetGR(struct _Unwind_Context *context, int reg, unsigned long val) +{ + _Unwind_VRS_Set(context, _UVRSC_CORE, reg, _UVRSD_UINT32, &val); +} +static inline unsigned long _Unwind_GetIP(_Unwind_Context *context) +{ + // Low bit store the thumb state - discard it + return _Unwind_GetGR(context, 15) & ~1; +} +static inline void _Unwind_SetIP(_Unwind_Context *context, unsigned long val) +{ + // The lowest bit of the instruction pointer indicates whether we're in + // thumb or ARM mode. This is assumed to be fixed throughout a function, + // so must be propagated when setting the program counter. + unsigned long thumbState = _Unwind_GetGR(context, 15) & 1; + _Unwind_SetGR(context, 15, (val | thumbState)); +} + +/** GNU API function that unwinds the frame */ +_Unwind_Reason_Code __gnu_unwind_frame(struct _Unwind_Exception*, struct _Unwind_Context*); + + +#define DECLARE_PERSONALITY_FUNCTION(name) \ +_Unwind_Reason_Code name(_Unwind_State state,\ + struct _Unwind_Exception *exceptionObject,\ + struct _Unwind_Context *context); + +#define BEGIN_PERSONALITY_FUNCTION(name) \ +_Unwind_Reason_Code name(_Unwind_State state,\ + struct _Unwind_Exception *exceptionObject,\ + struct _Unwind_Context *context)\ +{\ + int version = 1;\ + uint64_t exceptionClass = exceptionObject->exception_class;\ + int actions;\ + switch (state)\ + {\ + default: return _URC_FAILURE;\ + case _US_VIRTUAL_UNWIND_FRAME:\ + {\ + actions = _UA_SEARCH_PHASE;\ + break;\ + }\ + case _US_UNWIND_FRAME_STARTING:\ + {\ + actions = _UA_CLEANUP_PHASE;\ + if (exceptionObject->barrier_cache.sp == _Unwind_GetGR(context, 13))\ + {\ + actions |= _UA_HANDLER_FRAME;\ + }\ + break;\ + }\ + case _US_UNWIND_FRAME_RESUME:\ + {\ + return continueUnwinding(exceptionObject, context);\ + break;\ + }\ + }\ + _Unwind_SetGR (context, 12, reinterpret_cast(exceptionObject));\ + +#define CALL_PERSONALITY_FUNCTION(name) name(state,exceptionObject,context) diff --git a/headers/libs/libcxxrt/unwind-itanium.h b/headers/libs/libcxxrt/unwind-itanium.h new file mode 100644 index 0000000000..0ca9488605 --- /dev/null +++ b/headers/libs/libcxxrt/unwind-itanium.h @@ -0,0 +1,170 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _UNWIND_H +#define _UNWIND_H + +/* For uint64_t */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Minimal interface as per C++ ABI draft standard: + + http://www.codesourcery.com/cxx-abi/abi-eh.html */ + +typedef enum + { + _URC_NO_REASON = 0, + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + _URC_FATAL_PHASE2_ERROR = 2, + _URC_FATAL_PHASE1_ERROR = 3, + _URC_NORMAL_STOP = 4, + _URC_END_OF_STACK = 5, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8 + } +_Unwind_Reason_Code; + +typedef int _Unwind_Action; + +#define _UA_SEARCH_PHASE 1 +#define _UA_CLEANUP_PHASE 2 +#define _UA_HANDLER_FRAME 4 +#define _UA_FORCE_UNWIND 8 + +struct _Unwind_Context; /* opaque data-structure */ +struct _Unwind_Exception; /* forward-declaration */ + +typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, + struct _Unwind_Exception *); + +typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) (int, _Unwind_Action, + uint64_t, + struct _Unwind_Exception *, + struct _Unwind_Context *, + void *); + +/* The C++ ABI requires exception_class, private_1, and private_2 to + be of type uint64 and the entire structure to be + double-word-aligned. Please note that exception_class stays 64-bit + even on 32-bit machines for gcc compatibility. */ +struct _Unwind_Exception + { + uint64_t exception_class; + _Unwind_Exception_Cleanup_Fn exception_cleanup; + unsigned long private_1; + unsigned long private_2; + } ; + +extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *); +extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *, + _Unwind_Stop_Fn, void *); +extern void _Unwind_Resume (struct _Unwind_Exception *); +extern void _Unwind_DeleteException (struct _Unwind_Exception *); +extern unsigned long _Unwind_GetGR (struct _Unwind_Context *, int); +extern void _Unwind_SetGR (struct _Unwind_Context *, int, unsigned long); +extern unsigned long _Unwind_GetIP (struct _Unwind_Context *); +extern unsigned long _Unwind_GetIPInfo (struct _Unwind_Context *, int *); +extern void _Unwind_SetIP (struct _Unwind_Context *, unsigned long); +extern unsigned long _Unwind_GetLanguageSpecificData (struct _Unwind_Context*); +extern unsigned long _Unwind_GetRegionStart (struct _Unwind_Context *); + +#ifdef _GNU_SOURCE + +/* Callback for _Unwind_Backtrace(). The backtrace stops immediately + if the callback returns any value other than _URC_NO_REASON. */ +typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (struct _Unwind_Context *, + void *); + +/* See http://gcc.gnu.org/ml/gcc-patches/2001-09/msg00082.html for why + _UA_END_OF_STACK exists. */ +# define _UA_END_OF_STACK 16 + +/* If the unwind was initiated due to a forced unwind, resume that + operation, else re-raise the exception. This is used by + __cxa_rethrow(). */ +extern _Unwind_Reason_Code + _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *); + +/* See http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00154.html for why + _Unwind_GetBSP() exists. */ +extern unsigned long _Unwind_GetBSP (struct _Unwind_Context *); + +/* Return the "canonical frame address" for the given context. + This is used by NPTL... */ +extern unsigned long _Unwind_GetCFA (struct _Unwind_Context *); + +/* Return the base-address for data references. */ +extern unsigned long _Unwind_GetDataRelBase (struct _Unwind_Context *); + +/* Return the base-address for text references. */ +extern unsigned long _Unwind_GetTextRelBase (struct _Unwind_Context *); + +/* Call _Unwind_Trace_Fn once for each stack-frame, without doing any + cleanup. The first frame for which the callback is invoked is the + one for the caller of _Unwind_Backtrace(). _Unwind_Backtrace() + returns _URC_END_OF_STACK when the backtrace stopped due to + reaching the end of the call-chain or _URC_FATAL_PHASE1_ERROR if it + stops for any other reason. */ +extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *); + +/* Find the start-address of the procedure containing the specified IP + or NULL if it cannot be found (e.g., because the function has no + unwind info). Note: there is not necessarily a one-to-one + correspondence between source-level functions and procedures: some + functions don't have unwind-info and others are split into multiple + procedures. */ +extern void *_Unwind_FindEnclosingFunction (void *); + +/* See also Linux Standard Base Spec: + http://www.linuxbase.org/spec/refspecs/LSB_1.3.0/gLSB/gLSB/libgcc-s.html */ + +#endif /* _GNU_SOURCE */ + +#define DECLARE_PERSONALITY_FUNCTION(name) \ +_Unwind_Reason_Code name(int version,\ + _Unwind_Action actions,\ + uint64_t exceptionClass,\ + struct _Unwind_Exception *exceptionObject,\ + struct _Unwind_Context *context); +#define BEGIN_PERSONALITY_FUNCTION(name) \ +_Unwind_Reason_Code name(int version,\ + _Unwind_Action actions,\ + uint64_t exceptionClass,\ + struct _Unwind_Exception *exceptionObject,\ + struct _Unwind_Context *context)\ +{ + +#define CALL_PERSONALITY_FUNCTION(name) name(version, actions, exceptionClass, exceptionObject, context) + +#ifdef __cplusplus +} +#endif + +#endif /* _UNWIND_H */ diff --git a/headers/libs/libcxxrt/unwind.h b/headers/libs/libcxxrt/unwind.h new file mode 100644 index 0000000000..130dd6d82f --- /dev/null +++ b/headers/libs/libcxxrt/unwind.h @@ -0,0 +1,40 @@ +/* + * Copyright 2012 David Chisnall. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UNWIND_H_INCLUDED +#define UNWIND_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__arm__) && !defined(__ARM_DWARF_EH__) +#include "unwind-arm.h" +#else +#include "unwind-itanium.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/libcxxrt/AUTHORS b/src/libs/libcxxrt/AUTHORS new file mode 100644 index 0000000000..2d70ee83a4 --- /dev/null +++ b/src/libs/libcxxrt/AUTHORS @@ -0,0 +1,2 @@ +David Chisnall +PathScale engineers diff --git a/src/libs/libcxxrt/COPYRIGHT b/src/libs/libcxxrt/COPYRIGHT new file mode 100644 index 0000000000..c432d61a1d --- /dev/null +++ b/src/libs/libcxxrt/COPYRIGHT @@ -0,0 +1,3 @@ +PathScale Inc +NetBSD Foundation +FreeBSD Foundation diff --git a/src/libs/libcxxrt/LICENSE b/src/libs/libcxxrt/LICENSE new file mode 100644 index 0000000000..cda1ea2f7b --- /dev/null +++ b/src/libs/libcxxrt/LICENSE @@ -0,0 +1,14 @@ +The BSD License + +Copyright 2010-2011 PathScale, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of PathScale, Inc. diff --git a/src/libs/libcxxrt/README b/src/libs/libcxxrt/README new file mode 100644 index 0000000000..c784c11693 --- /dev/null +++ b/src/libs/libcxxrt/README @@ -0,0 +1,50 @@ +libcxxabi +========= + +This library implements the Code Sourcery C++ ABI, as documented here: + +http://www.codesourcery.com/public/cxx-abi/abi.html + +It is intended to sit below an STL implementation, and provide features required by the compiler for implementation of the C++ language. + +Current Status +-------------- + +At present, the library implements the following parts of the ABI specification: + +- RTTI classes and support for the dynamic_cast<> operator. +- Exception handling. +- Thread-safe initializers. + +Exception handling requires the assistance of a stack-unwinding library +implementing the low-level parts of the ABI. Either libgcc_s or libunwind +should work for this purpose. + +The library depends on various libc features, but does not depend on any C++ +features not implemented purely in the compiler or in the library itself. + +Supported Platforms +------------------- + +This code was initially developed on FreeBSD/x86, and has also been tested on FreeBSD/x86-64. It should work on other platforms that use the Code Sourcery ABI, for example Itanium, however this is untested. + +This library also supports the ARM EH ABI. + +Installation +------------ + +The default build system does not perform any installation. It is expected that this will be done by at a higher level. The exact installation steps depend on how you plan on deploying libcxxrt. + +There are three files that you may consider installing: + +- cxxabi.h (and unwind.h and either unwind-arm.h or unwind-itanium.h) +- libcxxrt.a +- libcxxrt.so + +The first describes the contract between this library and the compiler / STL implementation (lib[std]{cxx,c++}). Its contents should be considered semi-private, as it is probably not a good idea to encourage any code above the STL implementation to depend on it. Doing so will introduce portability issues. You may install this file but I recommend simply copying or linking it into your STL implementation's build directory. + +In general, I recommend against installing both the .a and the .so file. For static linking, the .a file should be linked against the static and dynamic versions of your STL implementation. Statically linking libcxxrt into your STL implementation means that users who dynamically link against the STL implementation can have libcxxrt upgraded automatically when you ship a new version of your STL implementation. + +The other option, installing the .so, is recommended for situations where you have two or more STL implementations and wish to be able to link against both (e.g. where an application links one library using libstdc++ and another using libc++). To support this case, you should link both STL implementations against libcxxrt.so. + +Supporting all of these options in the CMake build system is not practical - the amount of effort required to select the one that you want would be more than the effort required to perform the installation from an external script or build system. diff --git a/src/libs/libcxxrt/auxhelper.cc b/src/libs/libcxxrt/auxhelper.cc new file mode 100644 index 0000000000..3e98da036a --- /dev/null +++ b/src/libs/libcxxrt/auxhelper.cc @@ -0,0 +1,82 @@ +/* + * Copyright 2010-2011 PathScale, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * aux.cc - Compiler helper functions. + * + * The functions declared in this file are intended to be called only by code + * that is automatically generated by C++ compilers for some common cases. + */ + +#include +#include "stdexcept.h" + +/** + * Called to generate a bad cast exception. This function is intended to allow + * compilers to insert code generating this exception without needing to + * duplicate the code for throwing the exception in every call site. + */ +extern "C" void __cxa_bad_cast() +{ + throw std::bad_cast(); +} + +/** + * Called to generate a bad typeid exception. This function is intended to + * allow compilers to insert code generating this exception without needing to + * duplicate the code for throwing the exception in every call site. + */ +extern "C" void __cxa_bad_typeid() +{ + throw std::bad_typeid(); +} + +/** + * Compilers may (but are not required to) set any pure-virtual function's + * vtable entry to this function. This makes debugging slightly easier, as + * users can add a breakpoint on this function to tell if they've accidentally + * called a pure-virtual function. + */ +extern "C" void __cxa_pure_virtual() +{ + abort(); +} + +/** + * Compilers may (but are not required to) set any deleted-virtual function's + * vtable entry to this function. This makes debugging slightly easier, as + * users can add a breakpoint on this function to tell if they've accidentally + * called a deleted-virtual function. + */ +extern "C" void __cxa_deleted_virtual() +{ + abort(); +} + +extern "C" void __cxa_throw_bad_array_new_length() +{ + throw std::bad_array_new_length(); +} diff --git a/src/libs/libcxxrt/cxa_atexit.c b/src/libs/libcxxrt/cxa_atexit.c new file mode 100644 index 0000000000..533a9d44f7 --- /dev/null +++ b/src/libs/libcxxrt/cxa_atexit.c @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2012 David Chisnall. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +/* Special thanks to TBricks for partially funding this work */ + +#ifdef __sun__ +#include +#include + +static struct atexit_handler { + void (*f)(void *); + void *p; + void *d; + struct atexit_handler *next; +} *head; + +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + +int __cxa_atexit( void (*f)(void *), void *p, void *d) { + pthread_mutex_lock(&lock); + struct atexit_handler *h = malloc(sizeof(*h)); + if (!h) { + pthread_mutex_unlock(&lock); + return 1; + } + h->f = f; + h->p = p; + h->d = d; + h->next = head; + head = h; + pthread_mutex_unlock(&lock); + return 0; +} + +void __cxa_finalize(void *d ) { + pthread_mutex_lock(&lock); + struct atexit_handler **last = &head; + for (struct atexit_handler *h = head ; h ; h = h->next) { + if ((h->d == d) || (d == 0)) { + *last = h->next; + h->f(h->p); + free(h); + } else { + last = &h->next; + } + } + pthread_mutex_unlock(&lock); +} +#endif diff --git a/src/libs/libcxxrt/cxa_finalize.c b/src/libs/libcxxrt/cxa_finalize.c new file mode 100644 index 0000000000..f0d1b8cb66 --- /dev/null +++ b/src/libs/libcxxrt/cxa_finalize.c @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2012 David Chisnall. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + + +void __cxa_finalize(void *d ); + +extern void *__dso_handle; + +__attribute__((__destructor__, __used__)) +static void cleanup(void) { + __cxa_finalize(&__dso_handle); +} diff --git a/src/libs/libcxxrt/dynamic_cast.cc b/src/libs/libcxxrt/dynamic_cast.cc new file mode 100644 index 0000000000..6ae3a40355 --- /dev/null +++ b/src/libs/libcxxrt/dynamic_cast.cc @@ -0,0 +1,210 @@ +/* + * Copyright 2010-2011 PathScale, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "typeinfo.h" +#include + +using namespace ABI_NAMESPACE; + +/** + * Vtable header. + */ +struct vtable_header +{ + /** Offset of the leaf object. */ + ptrdiff_t leaf_offset; + /** Type of the object. */ + const __class_type_info *type; +}; + +/** + * Simple macro that does pointer arithmetic in bytes but returns a value of + * the same type as the original. + */ +#define ADD_TO_PTR(x, off) reinterpret_cast<__typeof__(x)>(reinterpret_cast(x) + off) + +bool std::type_info::__do_catch(std::type_info const *ex_type, + void **exception_object, + unsigned int outer) const +{ + const type_info *type = this; + + if (type == ex_type) + { + return true; + } + if (const __class_type_info *cti = dynamic_cast(type)) + { + return ex_type->__do_upcast(cti, exception_object); + } + return false; +} + +bool __pbase_type_info::__do_catch(std::type_info const *ex_type, + void **exception_object, + unsigned int outer) const +{ + if (ex_type == this) + { + return true; + } + if (!ex_type->__is_pointer_p()) + { + // Can't catch a non-pointer type in a pointer catch + return false; + } + + if (!(outer & 1)) + { + // If the low bit is cleared on this means that we've gone + // through a pointer that is not const qualified. + return false; + } + // Clear the low bit on outer if we're not const qualified. + if (!(__flags & __const_mask)) + { + outer &= ~1; + } + + const __pbase_type_info *ptr_type = + static_cast(ex_type); + + if (ptr_type->__flags & ~__flags) + { + // Handler pointer is less qualified + return false; + } + + // Special case for void* handler. + if(*__pointee == typeid(void)) + { + return true; + } + + return __pointee->__do_catch(ptr_type->__pointee, exception_object, outer); +} + +void *__class_type_info::cast_to(void *obj, const struct __class_type_info *other) const +{ + if (this == other) + { + return obj; + } + return 0; +} + +void *__si_class_type_info::cast_to(void *obj, const struct __class_type_info *other) const +{ + if (this == other) + { + return obj; + } + return __base_type->cast_to(obj, other); +} +bool __si_class_type_info::__do_upcast(const __class_type_info *target, + void **thrown_object) const +{ + if (this == target) + { + return true; + } + return __base_type->__do_upcast(target, thrown_object); +} + +void *__vmi_class_type_info::cast_to(void *obj, const struct __class_type_info *other) const +{ + if (__do_upcast(other, &obj)) + { + return obj; + } + return 0; +} + +bool __vmi_class_type_info::__do_upcast(const __class_type_info *target, + void **thrown_object) const +{ + if (this == target) + { + return true; + } + for (unsigned int i=0 ; i<__base_count ; i++) + { + const __base_class_type_info *info = &__base_info[i]; + ptrdiff_t offset = info->offset(); + // If this is a virtual superclass, the offset is stored in the + // object's vtable at the offset requested; 2.9.5.6.c: + // + // 'For a non-virtual base, this is the offset in the object of the + // base subobject. For a virtual base, this is the offset in the + // virtual table of the virtual base offset for the virtual base + // referenced (negative).' + + void *obj = *thrown_object; + if (info->isVirtual()) + { + // Object's vtable + ptrdiff_t *off = *static_cast(obj); + // Offset location in vtable + off = ADD_TO_PTR(off, offset); + offset = *off; + } + void *cast = ADD_TO_PTR(obj, offset); + + if (info->__base_type == target || + (info->__base_type->__do_upcast(target, &cast))) + { + *thrown_object = cast; + return true; + } + } + return 0; +} + + +/** + * ABI function used to implement the dynamic_cast<> operator. Some cases of + * this operator are implemented entirely in the compiler (e.g. to void*). + * This function implements the dynamic casts of the form dynamic_cast(v). + * This will be translated to a call to this function with the value v as the + * first argument. The type id of the static type of v is the second argument + * and the type id of the destination type (T) is the third argument. + * + * The third argument is a hint about the compiler's guess at the correct + * pointer offset. If this value is negative, then -1 indicates no hint, -2 + * that src is not a public base of dst, and -3 that src is a multiple public + * base type but never a virtual base type + */ +extern "C" void* __dynamic_cast(const void *sub, + const __class_type_info *src, + const __class_type_info *dst, + ptrdiff_t src2dst_offset) +{ + const char *vtable_location = *static_cast(sub); + const vtable_header *header = + reinterpret_cast(vtable_location - sizeof(vtable_header)); + void *leaf = ADD_TO_PTR(const_cast(sub), header->leaf_offset); + return header->type->cast_to(leaf, dst); +} diff --git a/src/libs/libcxxrt/exception.cc b/src/libs/libcxxrt/exception.cc new file mode 100644 index 0000000000..89032da941 --- /dev/null +++ b/src/libs/libcxxrt/exception.cc @@ -0,0 +1,1542 @@ +/* + * Copyright 2010-2011 PathScale, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "typeinfo.h" +#include "dwarf_eh.h" +#include "atomic.h" +#include "cxxabi.h" + +#pragma weak pthread_key_create +#pragma weak pthread_setspecific +#pragma weak pthread_getspecific +#pragma weak pthread_once +#ifdef LIBCXXRT_WEAK_LOCKS +#pragma weak pthread_mutex_lock +#define pthread_mutex_lock(mtx) do {\ + if (pthread_mutex_lock) pthread_mutex_lock(mtx);\ + } while(0) +#pragma weak pthread_mutex_unlock +#define pthread_mutex_unlock(mtx) do {\ + if (pthread_mutex_unlock) pthread_mutex_unlock(mtx);\ + } while(0) +#pragma weak pthread_cond_signal +#define pthread_cond_signal(cv) do {\ + if (pthread_cond_signal) pthread_cond_signal(cv);\ + } while(0) +#pragma weak pthread_cond_wait +#define pthread_cond_wait(cv, mtx) do {\ + if (pthread_cond_wait) pthread_cond_wait(cv, mtx);\ + } while(0) +#endif + +using namespace ABI_NAMESPACE; + +/** + * Saves the result of the landing pad that we have found. For ARM, this is + * stored in the generic unwind structure, while on other platforms it is + * stored in the C++ exception. + */ +static void saveLandingPad(struct _Unwind_Context *context, + struct _Unwind_Exception *ucb, + struct __cxa_exception *ex, + int selector, + dw_eh_ptr_t landingPad) +{ +#if defined(__arm__) && !defined(__ARM_DWARF_EH__) + // On ARM, we store the saved exception in the generic part of the structure + ucb->barrier_cache.sp = _Unwind_GetGR(context, 13); + ucb->barrier_cache.bitpattern[1] = static_cast(selector); + ucb->barrier_cache.bitpattern[3] = reinterpret_cast(landingPad); +#endif + // Cache the results for the phase 2 unwind, if we found a handler + // and this is not a foreign exception. + if (ex) + { + ex->handlerSwitchValue = selector; + ex->catchTemp = landingPad; + } +} + +/** + * Loads the saved landing pad. Returns 1 on success, 0 on failure. + */ +static int loadLandingPad(struct _Unwind_Context *context, + struct _Unwind_Exception *ucb, + struct __cxa_exception *ex, + unsigned long *selector, + dw_eh_ptr_t *landingPad) +{ +#if defined(__arm__) && !defined(__ARM_DWARF_EH__) + *selector = ucb->barrier_cache.bitpattern[1]; + *landingPad = reinterpret_cast(ucb->barrier_cache.bitpattern[3]); + return 1; +#else + if (ex) + { + *selector = ex->handlerSwitchValue; + *landingPad = reinterpret_cast(ex->catchTemp); + return 0; + } + return 0; +#endif +} + +static inline _Unwind_Reason_Code continueUnwinding(struct _Unwind_Exception *ex, + struct _Unwind_Context *context) +{ +#if defined(__arm__) && !defined(__ARM_DWARF_EH__) + if (__gnu_unwind_frame(ex, context) != _URC_OK) { return _URC_FAILURE; } +#endif + return _URC_CONTINUE_UNWIND; +} + + +extern "C" void __cxa_free_exception(void *thrown_exception); +extern "C" void __cxa_free_dependent_exception(void *thrown_exception); +extern "C" void* __dynamic_cast(const void *sub, + const __class_type_info *src, + const __class_type_info *dst, + ptrdiff_t src2dst_offset); + +/** + * The type of a handler that has been found. + */ +typedef enum +{ + /** No handler. */ + handler_none, + /** + * A cleanup - the exception will propagate through this frame, but code + * must be run when this happens. + */ + handler_cleanup, + /** + * A catch statement. The exception will not propagate past this frame + * (without an explicit rethrow). + */ + handler_catch +} handler_type; + +/** + * Per-thread info required by the runtime. We store a single structure + * pointer in thread-local storage, because this tends to be a scarce resource + * and it's impolite to steal all of it and not leave any for the rest of the + * program. + * + * Instances of this structure are allocated lazily - at most one per thread - + * and are destroyed on thread termination. + */ +struct __cxa_thread_info +{ + /** The termination handler for this thread. */ + terminate_handler terminateHandler; + /** The unexpected exception handler for this thread. */ + unexpected_handler unexpectedHandler; + /** + * The number of emergency buffers held by this thread. This is 0 in + * normal operation - the emergency buffers are only used when malloc() + * fails to return memory for allocating an exception. Threads are not + * permitted to hold more than 4 emergency buffers (as per recommendation + * in ABI spec [3.3.1]). + */ + int emergencyBuffersHeld; + /** + * The exception currently running in a cleanup. + */ + _Unwind_Exception *currentCleanup; + /** + * Our state with respect to foreign exceptions. Usually none, set to + * caught if we have just caught an exception and rethrown if we are + * rethrowing it. + */ + enum + { + none, + caught, + rethrown + } foreign_exception_state; + /** + * The public part of this structure, accessible from outside of this + * module. + */ + __cxa_eh_globals globals; +}; +/** + * Dependent exception. This + */ +struct __cxa_dependent_exception +{ +#if __LP64__ + void *primaryException; +#endif + std::type_info *exceptionType; + void (*exceptionDestructor) (void *); + unexpected_handler unexpectedHandler; + terminate_handler terminateHandler; + __cxa_exception *nextException; + int handlerCount; +#if defined(__arm__) && !defined(__ARM_DWARF_EH__) + _Unwind_Exception *nextCleanup; + int cleanupCount; +#endif + int handlerSwitchValue; + const char *actionRecord; + const char *languageSpecificData; + void *catchTemp; + void *adjustedPtr; +#if !__LP64__ + void *primaryException; +#endif + _Unwind_Exception unwindHeader; +}; + + +namespace std +{ + void unexpected(); + class exception + { + public: + virtual ~exception() throw(); + virtual const char* what() const throw(); + }; + +} + +/** + * Class of exceptions to distinguish between this and other exception types. + * + * The first four characters are the vendor ID. Currently, we use GNUC, + * because we aim for ABI-compatibility with the GNU implementation, and + * various checks may test for equality of the class, which is incorrect. + */ +static const uint64_t exception_class = + EXCEPTION_CLASS('G', 'N', 'U', 'C', 'C', '+', '+', '\0'); +/** + * Class used for dependent exceptions. + */ +static const uint64_t dependent_exception_class = + EXCEPTION_CLASS('G', 'N', 'U', 'C', 'C', '+', '+', '\x01'); +/** + * The low four bytes of the exception class, indicating that we conform to the + * Itanium C++ ABI. This is currently unused, but should be used in the future + * if we change our exception class, to allow this library and libsupc++ to be + * linked to the same executable and both to interoperate. + */ +static const uint32_t abi_exception_class = + GENERIC_EXCEPTION_CLASS('C', '+', '+', '\0'); + +static bool isCXXException(uint64_t cls) +{ + return (cls == exception_class) || (cls == dependent_exception_class); +} + +static bool isDependentException(uint64_t cls) +{ + return cls == dependent_exception_class; +} + +static __cxa_exception *exceptionFromPointer(void *ex) +{ + return reinterpret_cast<__cxa_exception*>(static_cast(ex) - + offsetof(struct __cxa_exception, unwindHeader)); +} +static __cxa_exception *realExceptionFromException(__cxa_exception *ex) +{ + if (!isDependentException(ex->unwindHeader.exception_class)) { return ex; } + return reinterpret_cast<__cxa_exception*>((reinterpret_cast<__cxa_dependent_exception*>(ex))->primaryException)-1; +} + + +namespace std +{ + // Forward declaration of standard library terminate() function used to + // abort execution. + void terminate(void); +} + +using namespace ABI_NAMESPACE; + + + +/** The global termination handler. */ +static terminate_handler terminateHandler = abort; +/** The global unexpected exception handler. */ +static unexpected_handler unexpectedHandler = std::terminate; + +/** Key used for thread-local data. */ +static pthread_key_t eh_key; + + +/** + * Cleanup function, allowing foreign exception handlers to correctly destroy + * this exception if they catch it. + */ +static void exception_cleanup(_Unwind_Reason_Code reason, + struct _Unwind_Exception *ex) +{ + __cxa_free_exception(static_cast(ex)); +} +static void dependent_exception_cleanup(_Unwind_Reason_Code reason, + struct _Unwind_Exception *ex) +{ + + __cxa_free_dependent_exception(static_cast(ex)); +} + +/** + * Recursively walk a list of exceptions and delete them all in post-order. + */ +static void free_exception_list(__cxa_exception *ex) +{ + if (0 != ex->nextException) + { + free_exception_list(ex->nextException); + } + // __cxa_free_exception() expects to be passed the thrown object, which + // immediately follows the exception, not the exception itself + __cxa_free_exception(ex+1); +} + +/** + * Cleanup function called when a thread exists to make certain that all of the + * per-thread data is deleted. + */ +static void thread_cleanup(void* thread_info) +{ + __cxa_thread_info *info = static_cast<__cxa_thread_info*>(thread_info); + if (info->globals.caughtExceptions) + { + // If this is a foreign exception, ask it to clean itself up. + if (info->foreign_exception_state != __cxa_thread_info::none) + { + _Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(info->globals.caughtExceptions); + e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e); + } + else + { + free_exception_list(info->globals.caughtExceptions); + } + } + free(thread_info); +} + + +/** + * Once control used to protect the key creation. + */ +static pthread_once_t once_control = PTHREAD_ONCE_INIT; + +/** + * We may not be linked against a full pthread implementation. If we're not, + * then we need to fake the thread-local storage by storing 'thread-local' + * things in a global. + */ +static bool fakeTLS; +/** + * Thread-local storage for a single-threaded program. + */ +static __cxa_thread_info singleThreadInfo; +/** + * Initialise eh_key. + */ +static void init_key(void) +{ + if ((0 == pthread_key_create) || + (0 == pthread_setspecific) || + (0 == pthread_getspecific)) + { + fakeTLS = true; + return; + } + pthread_key_create(&eh_key, thread_cleanup); + pthread_setspecific(eh_key, reinterpret_cast(0x42)); + fakeTLS = (pthread_getspecific(eh_key) != reinterpret_cast(0x42)); + pthread_setspecific(eh_key, 0); +} + +/** + * Returns the thread info structure, creating it if it is not already created. + */ +static __cxa_thread_info *thread_info() +{ + if ((0 == pthread_once) || pthread_once(&once_control, init_key)) + { + fakeTLS = true; + } + if (fakeTLS) { return &singleThreadInfo; } + __cxa_thread_info *info = static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key)); + if (0 == info) + { + info = static_cast<__cxa_thread_info*>(calloc(1, sizeof(__cxa_thread_info))); + pthread_setspecific(eh_key, info); + } + return info; +} +/** + * Fast version of thread_info(). May fail if thread_info() is not called on + * this thread at least once already. + */ +static __cxa_thread_info *thread_info_fast() +{ + if (fakeTLS) { return &singleThreadInfo; } + return static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key)); +} +/** + * ABI function returning the __cxa_eh_globals structure. + */ +extern "C" __cxa_eh_globals *ABI_NAMESPACE::__cxa_get_globals(void) +{ + return &(thread_info()->globals); +} +/** + * Version of __cxa_get_globals() assuming that __cxa_get_globals() has already + * been called at least once by this thread. + */ +extern "C" __cxa_eh_globals *ABI_NAMESPACE::__cxa_get_globals_fast(void) +{ + return &(thread_info_fast()->globals); +} + +/** + * An emergency allocation reserved for when malloc fails. This is treated as + * 16 buffers of 1KB each. + */ +static char emergency_buffer[16384]; +/** + * Flag indicating whether each buffer is allocated. + */ +static bool buffer_allocated[16]; +/** + * Lock used to protect emergency allocation. + */ +static pthread_mutex_t emergency_malloc_lock = PTHREAD_MUTEX_INITIALIZER; +/** + * Condition variable used to wait when two threads are both trying to use the + * emergency malloc() buffer at once. + */ +static pthread_cond_t emergency_malloc_wait = PTHREAD_COND_INITIALIZER; + +/** + * Allocates size bytes from the emergency allocation mechanism, if possible. + * This function will fail if size is over 1KB or if this thread already has 4 + * emergency buffers. If all emergency buffers are allocated, it will sleep + * until one becomes available. + */ +static char *emergency_malloc(size_t size) +{ + if (size > 1024) { return 0; } + + __cxa_thread_info *info = thread_info(); + // Only 4 emergency buffers allowed per thread! + if (info->emergencyBuffersHeld > 3) { return 0; } + + pthread_mutex_lock(&emergency_malloc_lock); + int buffer = -1; + while (buffer < 0) + { + // While we were sleeping on the lock, another thread might have free'd + // enough memory for us to use, so try the allocation again - no point + // using the emergency buffer if there is some real memory that we can + // use... + void *m = calloc(1, size); + if (0 != m) + { + pthread_mutex_unlock(&emergency_malloc_lock); + return static_cast(m); + } + for (int i=0 ; i<16 ; i++) + { + if (!buffer_allocated[i]) + { + buffer = i; + buffer_allocated[i] = true; + break; + } + } + // If there still isn't a buffer available, then sleep on the condition + // variable. This will be signalled when another thread releases one + // of the emergency buffers. + if (buffer < 0) + { + pthread_cond_wait(&emergency_malloc_wait, &emergency_malloc_lock); + } + } + pthread_mutex_unlock(&emergency_malloc_lock); + info->emergencyBuffersHeld++; + return emergency_buffer + (1024 * buffer); +} + +/** + * Frees a buffer returned by emergency_malloc(). + * + * Note: Neither this nor emergency_malloc() is particularly efficient. This + * should not matter, because neither will be called in normal operation - they + * are only used when the program runs out of memory, which should not happen + * often. + */ +static void emergency_malloc_free(char *ptr) +{ + int buffer = -1; + // Find the buffer corresponding to this pointer. + for (int i=0 ; i<16 ; i++) + { + if (ptr == static_cast(emergency_buffer + (1024 * i))) + { + buffer = i; + break; + } + } + assert(buffer >= 0 && + "Trying to free something that is not an emergency buffer!"); + // emergency_malloc() is expected to return 0-initialized data. We don't + // zero the buffer when allocating it, because the static buffers will + // begin life containing 0 values. + memset(ptr, 0, 1024); + // Signal the condition variable to wake up any threads that are blocking + // waiting for some space in the emergency buffer + pthread_mutex_lock(&emergency_malloc_lock); + // In theory, we don't need to do this with the lock held. In practice, + // our array of bools will probably be updated using 32-bit or 64-bit + // memory operations, so this update may clobber adjacent values. + buffer_allocated[buffer] = false; + pthread_cond_signal(&emergency_malloc_wait); + pthread_mutex_unlock(&emergency_malloc_lock); +} + +static char *alloc_or_die(size_t size) +{ + char *buffer = static_cast(calloc(1, size)); + + // If calloc() doesn't want to give us any memory, try using an emergency + // buffer. + if (0 == buffer) + { + buffer = emergency_malloc(size); + // This is only reached if the allocation is greater than 1KB, and + // anyone throwing objects that big really should know better. + if (0 == buffer) + { + fprintf(stderr, "Out of memory attempting to allocate exception\n"); + std::terminate(); + } + } + return buffer; +} +static void free_exception(char *e) +{ + // If this allocation is within the address range of the emergency buffer, + // don't call free() because it was not allocated with malloc() + if ((e >= emergency_buffer) && + (e < (emergency_buffer + sizeof(emergency_buffer)))) + { + emergency_malloc_free(e); + } + else + { + free(e); + } +} + +/** + * Allocates an exception structure. Returns a pointer to the space that can + * be used to store an object of thrown_size bytes. This function will use an + * emergency buffer if malloc() fails, and may block if there are no such + * buffers available. + */ +extern "C" void *__cxa_allocate_exception(size_t thrown_size) +{ + size_t size = thrown_size + sizeof(__cxa_exception); + char *buffer = alloc_or_die(size); + return buffer+sizeof(__cxa_exception); +} + +extern "C" void *__cxa_allocate_dependent_exception(void) +{ + size_t size = sizeof(__cxa_dependent_exception); + char *buffer = alloc_or_die(size); + return buffer+sizeof(__cxa_dependent_exception); +} + +/** + * __cxa_free_exception() is called when an exception was thrown in between + * calling __cxa_allocate_exception() and actually throwing the exception. + * This happens when the object's copy constructor throws an exception. + * + * In this implementation, it is also called by __cxa_end_catch() and during + * thread cleanup. + */ +extern "C" void __cxa_free_exception(void *thrown_exception) +{ + __cxa_exception *ex = reinterpret_cast<__cxa_exception*>(thrown_exception) - 1; + // Free the object that was thrown, calling its destructor + if (0 != ex->exceptionDestructor) + { + try + { + ex->exceptionDestructor(thrown_exception); + } + catch(...) + { + // FIXME: Check that this is really what the spec says to do. + std::terminate(); + } + } + + free_exception(reinterpret_cast(ex)); +} + +static void releaseException(__cxa_exception *exception) +{ + if (isDependentException(exception->unwindHeader.exception_class)) + { + __cxa_free_dependent_exception(exception+1); + return; + } + if (__sync_sub_and_fetch(&exception->referenceCount, 1) == 0) + { + // __cxa_free_exception() expects to be passed the thrown object, + // which immediately follows the exception, not the exception + // itself + __cxa_free_exception(exception+1); + } +} + +void __cxa_free_dependent_exception(void *thrown_exception) +{ + __cxa_dependent_exception *ex = reinterpret_cast<__cxa_dependent_exception*>(thrown_exception) - 1; + assert(isDependentException(ex->unwindHeader.exception_class)); + if (ex->primaryException) + { + releaseException(realExceptionFromException(reinterpret_cast<__cxa_exception*>(ex))); + } + free_exception(reinterpret_cast(ex)); +} + +/** + * Callback function used with _Unwind_Backtrace(). + * + * Prints a stack trace. Used only for debugging help. + * + * Note: As of FreeBSD 8.1, dladd() still doesn't work properly, so this only + * correctly prints function names from public, relocatable, symbols. + */ +static _Unwind_Reason_Code trace(struct _Unwind_Context *context, void *c) +{ + Dl_info myinfo; + int mylookup = + dladdr(reinterpret_cast(__cxa_current_exception_type), &myinfo); + void *ip = reinterpret_cast(_Unwind_GetIP(context)); + Dl_info info; + if (dladdr(ip, &info) != 0) + { + if (mylookup == 0 || strcmp(info.dli_fname, myinfo.dli_fname) != 0) + { + printf("%p:%s() in %s\n", ip, info.dli_sname, info.dli_fname); + } + } + return _URC_CONTINUE_UNWIND; +} + +/** + * Report a failure that occurred when attempting to throw an exception. + * + * If the failure happened by falling off the end of the stack without finding + * a handler, prints a back trace before aborting. + */ +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) +extern "C" void *__cxa_begin_catch(void *e) throw(); +#else +extern "C" void *__cxa_begin_catch(void *e); +#endif +static void report_failure(_Unwind_Reason_Code err, __cxa_exception *thrown_exception) +{ + switch (err) + { + default: break; + case _URC_FATAL_PHASE1_ERROR: + fprintf(stderr, "Fatal error during phase 1 unwinding\n"); + break; +#if !defined(__arm__) || defined(__ARM_DWARF_EH__) + case _URC_FATAL_PHASE2_ERROR: + fprintf(stderr, "Fatal error during phase 2 unwinding\n"); + break; +#endif + case _URC_END_OF_STACK: + __cxa_begin_catch (&(thrown_exception->unwindHeader)); + std::terminate(); + fprintf(stderr, "Terminating due to uncaught exception %p", + static_cast(thrown_exception)); + thrown_exception = realExceptionFromException(thrown_exception); + static const __class_type_info *e_ti = + static_cast(&typeid(std::exception)); + const __class_type_info *throw_ti = + dynamic_cast(thrown_exception->exceptionType); + if (throw_ti) + { + std::exception *e = + static_cast(e_ti->cast_to(static_cast(thrown_exception+1), + throw_ti)); + if (e) + { + fprintf(stderr, " '%s'", e->what()); + } + } + + size_t bufferSize = 128; + char *demangled = static_cast(malloc(bufferSize)); + const char *mangled = thrown_exception->exceptionType->name(); + int status; + demangled = __cxa_demangle(mangled, demangled, &bufferSize, &status); + fprintf(stderr, " of type %s\n", + status == 0 ? demangled : mangled); + if (status == 0) { free(demangled); } + // Print a back trace if no handler is found. + // TODO: Make this optional + _Unwind_Backtrace(trace, 0); + + // Just abort. No need to call std::terminate for the second time + abort(); + break; + } + std::terminate(); +} + +static void throw_exception(__cxa_exception *ex) +{ + __cxa_thread_info *info = thread_info(); + ex->unexpectedHandler = info->unexpectedHandler; + if (0 == ex->unexpectedHandler) + { + ex->unexpectedHandler = unexpectedHandler; + } + ex->terminateHandler = info->terminateHandler; + if (0 == ex->terminateHandler) + { + ex->terminateHandler = terminateHandler; + } + info->globals.uncaughtExceptions++; + + _Unwind_Reason_Code err = _Unwind_RaiseException(&ex->unwindHeader); + // The _Unwind_RaiseException() function should not return, it should + // unwind the stack past this function. If it does return, then something + // has gone wrong. + report_failure(err, ex); +} + + +/** + * ABI function for throwing an exception. Takes the object to be thrown (the + * pointer returned by __cxa_allocate_exception()), the type info for the + * pointee, and the destructor (if there is one) as arguments. + */ +extern "C" void __cxa_throw(void *thrown_exception, + std::type_info *tinfo, + void(*dest)(void*)) +{ + __cxa_exception *ex = reinterpret_cast<__cxa_exception*>(thrown_exception) - 1; + + ex->referenceCount = 1; + ex->exceptionType = tinfo; + + ex->exceptionDestructor = dest; + + ex->unwindHeader.exception_class = exception_class; + ex->unwindHeader.exception_cleanup = exception_cleanup; + + throw_exception(ex); +} + +extern "C" void __cxa_rethrow_primary_exception(void* thrown_exception) +{ + if (NULL == thrown_exception) { return; } + + __cxa_exception *original = exceptionFromPointer(thrown_exception); + __cxa_dependent_exception *ex = reinterpret_cast<__cxa_dependent_exception*>(__cxa_allocate_dependent_exception())-1; + + ex->primaryException = thrown_exception; + __cxa_increment_exception_refcount(thrown_exception); + + ex->exceptionType = original->exceptionType; + ex->unwindHeader.exception_class = dependent_exception_class; + ex->unwindHeader.exception_cleanup = dependent_exception_cleanup; + + throw_exception(reinterpret_cast<__cxa_exception*>(ex)); +} + +extern "C" void *__cxa_current_primary_exception(void) +{ + __cxa_eh_globals* globals = __cxa_get_globals(); + __cxa_exception *ex = globals->caughtExceptions; + + if (0 == ex) { return NULL; } + ex = realExceptionFromException(ex); + __sync_fetch_and_add(&ex->referenceCount, 1); + return ex + 1; +} + +extern "C" void __cxa_increment_exception_refcount(void* thrown_exception) +{ + if (NULL == thrown_exception) { return; } + __cxa_exception *ex = static_cast<__cxa_exception*>(thrown_exception) - 1; + if (isDependentException(ex->unwindHeader.exception_class)) { return; } + __sync_fetch_and_add(&ex->referenceCount, 1); +} +extern "C" void __cxa_decrement_exception_refcount(void* thrown_exception) +{ + if (NULL == thrown_exception) { return; } + __cxa_exception *ex = static_cast<__cxa_exception*>(thrown_exception) - 1; + releaseException(ex); +} + +/** + * ABI function. Rethrows the current exception. Does not remove the + * exception from the stack or decrement its handler count - the compiler is + * expected to set the landing pad for this function to the end of the catch + * block, and then call _Unwind_Resume() to continue unwinding once + * __cxa_end_catch() has been called and any cleanup code has been run. + */ +extern "C" void __cxa_rethrow() +{ + __cxa_thread_info *ti = thread_info(); + __cxa_eh_globals *globals = &ti->globals; + // Note: We don't remove this from the caught list here, because + // __cxa_end_catch will be called when we unwind out of the try block. We + // could probably make this faster by providing an alternative rethrow + // function and ensuring that all cleanup code is run before calling it, so + // we can skip the top stack frame when unwinding. + __cxa_exception *ex = globals->caughtExceptions; + + if (0 == ex) + { + fprintf(stderr, + "Attempting to rethrow an exception that doesn't exist!\n"); + std::terminate(); + } + + if (ti->foreign_exception_state != __cxa_thread_info::none) + { + ti->foreign_exception_state = __cxa_thread_info::rethrown; + _Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(ex); + _Unwind_Reason_Code err = _Unwind_Resume_or_Rethrow(e); + report_failure(err, ex); + return; + } + + assert(ex->handlerCount > 0 && "Rethrowing uncaught exception!"); + + // ex->handlerCount will be decremented in __cxa_end_catch in enclosing + // catch block + + // Make handler count negative. This will tell __cxa_end_catch that + // exception was rethrown and exception object should not be destroyed + // when handler count become zero + ex->handlerCount = -ex->handlerCount; + + // Continue unwinding the stack with this exception. This should unwind to + // the place in the caller where __cxa_end_catch() is called. The caller + // will then run cleanup code and bounce the exception back with + // _Unwind_Resume(). + _Unwind_Reason_Code err = _Unwind_Resume_or_Rethrow(&ex->unwindHeader); + report_failure(err, ex); +} + +/** + * Returns the type_info object corresponding to the filter. + */ +static std::type_info *get_type_info_entry(_Unwind_Context *context, + dwarf_eh_lsda *lsda, + int filter) +{ + // Get the address of the record in the table. + dw_eh_ptr_t record = lsda->type_table - + dwarf_size_of_fixed_size_field(lsda->type_table_encoding)*filter; + //record -= 4; + dw_eh_ptr_t start = record; + // Read the value, but it's probably an indirect reference... + int64_t offset = read_value(lsda->type_table_encoding, &record); + + // (If the entry is 0, don't try to dereference it. That would be bad.) + if (offset == 0) { return 0; } + + // ...so we need to resolve it + return reinterpret_cast(resolve_indirect_value(context, + lsda->type_table_encoding, offset, start)); +} + + + +/** + * Checks the type signature found in a handler against the type of the thrown + * object. If ex is 0 then it is assumed to be a foreign exception and only + * matches cleanups. + */ +static bool check_type_signature(__cxa_exception *ex, + const std::type_info *type, + void *&adjustedPtr) +{ + void *exception_ptr = static_cast(ex+1); + const std::type_info *ex_type = ex ? ex->exceptionType : 0; + + bool is_ptr = ex ? ex_type->__is_pointer_p() : false; + if (is_ptr) + { + exception_ptr = *static_cast(exception_ptr); + } + // Always match a catchall, even with a foreign exception + // + // Note: A 0 here is a catchall, not a cleanup, so we return true to + // indicate that we found a catch. + if (0 == type) + { + if (ex) + { + adjustedPtr = exception_ptr; + } + return true; + } + + if (0 == ex) { return false; } + + // If the types are the same, no casting is needed. + if (*type == *ex_type) + { + adjustedPtr = exception_ptr; + return true; + } + + + if (type->__do_catch(ex_type, &exception_ptr, 1)) + { + adjustedPtr = exception_ptr; + return true; + } + + return false; +} +/** + * Checks whether the exception matches the type specifiers in this action + * record. If the exception only matches cleanups, then this returns false. + * If it matches a catch (including a catchall) then it returns true. + * + * The selector argument is used to return the selector that is passed in the + * second exception register when installing the context. + */ +static handler_type check_action_record(_Unwind_Context *context, + dwarf_eh_lsda *lsda, + dw_eh_ptr_t action_record, + __cxa_exception *ex, + unsigned long *selector, + void *&adjustedPtr) +{ + if (!action_record) { return handler_cleanup; } + handler_type found = handler_none; + while (action_record) + { + int filter = read_sleb128(&action_record); + dw_eh_ptr_t action_record_offset_base = action_record; + int displacement = read_sleb128(&action_record); + action_record = displacement ? + action_record_offset_base + displacement : 0; + // We only check handler types for C++ exceptions - foreign exceptions + // are only allowed for cleanups and catchalls. + if (filter > 0) + { + std::type_info *handler_type = get_type_info_entry(context, lsda, filter); + if (check_type_signature(ex, handler_type, adjustedPtr)) + { + *selector = filter; + return handler_catch; + } + } + else if (filter < 0 && 0 != ex) + { + bool matched = false; + *selector = filter; +#if defined(__arm__) && !defined(__ARM_DWARF_EH__) + filter++; + std::type_info *handler_type = get_type_info_entry(context, lsda, filter--); + while (handler_type) + { + if (check_type_signature(ex, handler_type, adjustedPtr)) + { + matched = true; + break; + } + handler_type = get_type_info_entry(context, lsda, filter--); + } +#else + unsigned char *type_index = reinterpret_cast(lsda->type_table) - filter - 1; + while (*type_index) + { + std::type_info *handler_type = get_type_info_entry(context, lsda, *(type_index++)); + // If the exception spec matches a permitted throw type for + // this function, don't report a handler - we are allowed to + // propagate this exception out. + if (check_type_signature(ex, handler_type, adjustedPtr)) + { + matched = true; + break; + } + } +#endif + if (matched) { continue; } + // If we don't find an allowed exception spec, we need to install + // the context for this action. The landing pad will then call the + // unexpected exception function. Treat this as a catch + return handler_catch; + } + else if (filter == 0) + { + *selector = filter; + found = handler_cleanup; + } + } + return found; +} + +static void pushCleanupException(_Unwind_Exception *exceptionObject, + __cxa_exception *ex) +{ +#if defined(__arm__) && !defined(__ARM_DWARF_EH__) + __cxa_thread_info *info = thread_info_fast(); + if (ex) + { + ex->cleanupCount++; + if (ex->cleanupCount > 1) + { + assert(exceptionObject == info->currentCleanup); + return; + } + ex->nextCleanup = info->currentCleanup; + } + info->currentCleanup = exceptionObject; +#endif +} + +/** + * The exception personality function. This is referenced in the unwinding + * DWARF metadata and is called by the unwind library for each C++ stack frame + * containing catch or cleanup code. + */ +extern "C" +BEGIN_PERSONALITY_FUNCTION(__gxx_personality_v0) + // This personality function is for version 1 of the ABI. If you use it + // with a future version of the ABI, it won't know what to do, so it + // reports a fatal error and give up before it breaks anything. + if (1 != version) + { + return _URC_FATAL_PHASE1_ERROR; + } + __cxa_exception *ex = 0; + __cxa_exception *realEx = 0; + + // If this exception is throw by something else then we can't make any + // assumptions about its layout beyond the fields declared in + // _Unwind_Exception. + bool foreignException = !isCXXException(exceptionClass); + + // If this isn't a foreign exception, then we have a C++ exception structure + if (!foreignException) + { + ex = exceptionFromPointer(exceptionObject); + realEx = realExceptionFromException(ex); + } + +#if defined(__arm__) && !defined(__ARM_DWARF_EH__) + unsigned char *lsda_addr = + static_cast(_Unwind_GetLanguageSpecificData(context)); +#else + unsigned char *lsda_addr = + reinterpret_cast(static_cast(_Unwind_GetLanguageSpecificData(context))); +#endif + + // No LSDA implies no landing pads - try the next frame + if (0 == lsda_addr) { return continueUnwinding(exceptionObject, context); } + + // These two variables define how the exception will be handled. + dwarf_eh_action action = {0}; + unsigned long selector = 0; + + // During the search phase, we do a complete lookup. If we return + // _URC_HANDLER_FOUND, then the phase 2 unwind will call this function with + // a _UA_HANDLER_FRAME action, telling us to install the handler frame. If + // we return _URC_CONTINUE_UNWIND, we may be called again later with a + // _UA_CLEANUP_PHASE action for this frame. + // + // The point of the two-stage unwind allows us to entirely avoid any stack + // unwinding if there is no handler. If there are just cleanups found, + // then we can just panic call an abort function. + // + // Matching a handler is much more expensive than matching a cleanup, + // because we don't need to bother doing type comparisons (or looking at + // the type table at all) for a cleanup. This means that there is no need + // to cache the result of finding a cleanup, because it's (quite) quick to + // look it up again from the action table. + if (actions & _UA_SEARCH_PHASE) + { + struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr); + + if (!dwarf_eh_find_callsite(context, &lsda, &action)) + { + // EH range not found. This happens if exception is thrown and not + // caught inside a cleanup (destructor). We should call + // terminate() in this case. The catchTemp (landing pad) field of + // exception object will contain null when personality function is + // called with _UA_HANDLER_FRAME action for phase 2 unwinding. + return _URC_HANDLER_FOUND; + } + + handler_type found_handler = check_action_record(context, &lsda, + action.action_record, realEx, &selector, ex->adjustedPtr); + // If there's no action record, we've only found a cleanup, so keep + // searching for something real + if (found_handler == handler_catch) + { + // Cache the results for the phase 2 unwind, if we found a handler + // and this is not a foreign exception. + if (ex) + { + saveLandingPad(context, exceptionObject, ex, selector, action.landing_pad); + ex->languageSpecificData = reinterpret_cast(lsda_addr); + ex->actionRecord = reinterpret_cast(action.action_record); + // ex->adjustedPtr is set when finding the action record. + } + return _URC_HANDLER_FOUND; + } + return continueUnwinding(exceptionObject, context); + } + + + // If this is a foreign exception, we didn't have anywhere to cache the + // lookup stuff, so we need to do it again. If this is either a forced + // unwind, a foreign exception, or a cleanup, then we just install the + // context for a cleanup. + if (!(actions & _UA_HANDLER_FRAME)) + { + // cleanup + struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr); + dwarf_eh_find_callsite(context, &lsda, &action); + if (0 == action.landing_pad) { return continueUnwinding(exceptionObject, context); } + handler_type found_handler = check_action_record(context, &lsda, + action.action_record, realEx, &selector, ex->adjustedPtr); + // Ignore handlers this time. + if (found_handler != handler_cleanup) { return continueUnwinding(exceptionObject, context); } + pushCleanupException(exceptionObject, ex); + } + else if (foreignException) + { + struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr); + dwarf_eh_find_callsite(context, &lsda, &action); + check_action_record(context, &lsda, action.action_record, realEx, + &selector, ex->adjustedPtr); + } + else if (ex->catchTemp == 0) + { + // Uncaught exception in cleanup, calling terminate + std::terminate(); + } + else + { + // Restore the saved info if we saved some last time. + loadLandingPad(context, exceptionObject, ex, &selector, &action.landing_pad); + ex->catchTemp = 0; + ex->handlerSwitchValue = 0; + } + + + _Unwind_SetIP(context, reinterpret_cast(action.landing_pad)); + _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), + reinterpret_cast(exceptionObject)); + _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), selector); + + return _URC_INSTALL_CONTEXT; +} + +/** + * ABI function called when entering a catch statement. The argument is the + * pointer passed out of the personality function. This is always the start of + * the _Unwind_Exception object. The return value for this function is the + * pointer to the caught exception, which is either the adjusted pointer (for + * C++ exceptions) of the unadjusted pointer (for foreign exceptions). + */ +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) +extern "C" void *__cxa_begin_catch(void *e) throw() +#else +extern "C" void *__cxa_begin_catch(void *e) +#endif +{ + // We can't call the fast version here, because if the first exception that + // we see is a foreign exception then we won't have called it yet. + __cxa_thread_info *ti = thread_info(); + __cxa_eh_globals *globals = &ti->globals; + globals->uncaughtExceptions--; + _Unwind_Exception *exceptionObject = static_cast<_Unwind_Exception*>(e); + + if (isCXXException(exceptionObject->exception_class)) + { + __cxa_exception *ex = exceptionFromPointer(exceptionObject); + + if (ex->handlerCount == 0) + { + // Add this to the front of the list of exceptions being handled + // and increment its handler count so that it won't be deleted + // prematurely. + ex->nextException = globals->caughtExceptions; + globals->caughtExceptions = ex; + } + + if (ex->handlerCount < 0) + { + // Rethrown exception is catched before end of catch block. + // Clear the rethrow flag (make value positive) - we are allowed + // to delete this exception at the end of the catch block, as long + // as it isn't thrown again later. + + // Code pattern: + // + // try { + // throw x; + // } + // catch() { + // try { + // throw; + // } + // catch() { + // __cxa_begin_catch() <- we are here + // } + // } + ex->handlerCount = -ex->handlerCount + 1; + } + else + { + ex->handlerCount++; + } + ti->foreign_exception_state = __cxa_thread_info::none; + + return ex->adjustedPtr; + } + else + { + // If this is a foreign exception, then we need to be able to + // store it. We can't chain foreign exceptions, so we give up + // if there are already some outstanding ones. + if (globals->caughtExceptions != 0) + { + std::terminate(); + } + globals->caughtExceptions = reinterpret_cast<__cxa_exception*>(exceptionObject); + ti->foreign_exception_state = __cxa_thread_info::caught; + } + // exceptionObject is the pointer to the _Unwind_Exception within the + // __cxa_exception. The throw object is after this + return (reinterpret_cast(exceptionObject) + sizeof(_Unwind_Exception)); +} + + + +/** + * ABI function called when exiting a catch block. This will free the current + * exception if it is no longer referenced in other catch blocks. + */ +extern "C" void __cxa_end_catch() +{ + // We can call the fast version here because the slow version is called in + // __cxa_throw(), which must have been called before we end a catch block + __cxa_thread_info *ti = thread_info_fast(); + __cxa_eh_globals *globals = &ti->globals; + __cxa_exception *ex = globals->caughtExceptions; + + assert(0 != ex && "Ending catch when no exception is on the stack!"); + + if (ti->foreign_exception_state != __cxa_thread_info::none) + { + globals->caughtExceptions = 0; + if (ti->foreign_exception_state != __cxa_thread_info::rethrown) + { + _Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(ti->globals.caughtExceptions); + e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e); + } + ti->foreign_exception_state = __cxa_thread_info::none; + return; + } + + bool deleteException = true; + + if (ex->handlerCount < 0) + { + // exception was rethrown. Exception should not be deleted even if + // handlerCount become zero. + // Code pattern: + // try { + // throw x; + // } + // catch() { + // { + // throw; + // } + // cleanup { + // __cxa_end_catch(); <- we are here + // } + // } + // + + ex->handlerCount++; + deleteException = false; + } + else + { + ex->handlerCount--; + } + + if (ex->handlerCount == 0) + { + globals->caughtExceptions = ex->nextException; + if (deleteException) + { + releaseException(ex); + } + } +} + +/** + * ABI function. Returns the type of the current exception. + */ +extern "C" std::type_info *__cxa_current_exception_type() +{ + __cxa_eh_globals *globals = __cxa_get_globals(); + __cxa_exception *ex = globals->caughtExceptions; + return ex ? ex->exceptionType : 0; +} + +/** + * ABI function, called when an exception specification is violated. + * + * This function does not return. + */ +extern "C" void __cxa_call_unexpected(void*exception) +{ + _Unwind_Exception *exceptionObject = static_cast<_Unwind_Exception*>(exception); + if (exceptionObject->exception_class == exception_class) + { + __cxa_exception *ex = exceptionFromPointer(exceptionObject); + if (ex->unexpectedHandler) + { + ex->unexpectedHandler(); + // Should not be reached. + abort(); + } + } + std::unexpected(); + // Should not be reached. + abort(); +} + +/** + * ABI function, returns the adjusted pointer to the exception object. + */ +extern "C" void *__cxa_get_exception_ptr(void *exceptionObject) +{ + return exceptionFromPointer(exceptionObject)->adjustedPtr; +} + +/** + * As an extension, we provide the ability for the unexpected and terminate + * handlers to be thread-local. We default to the standards-compliant + * behaviour where they are global. + */ +static bool thread_local_handlers = false; + + +namespace pathscale +{ + /** + * Sets whether unexpected and terminate handlers should be thread-local. + */ + void set_use_thread_local_handlers(bool flag) throw() + { + thread_local_handlers = flag; + } + /** + * Sets a thread-local unexpected handler. + */ + unexpected_handler set_unexpected(unexpected_handler f) throw() + { + static __cxa_thread_info *info = thread_info(); + unexpected_handler old = info->unexpectedHandler; + info->unexpectedHandler = f; + return old; + } + /** + * Sets a thread-local terminate handler. + */ + terminate_handler set_terminate(terminate_handler f) throw() + { + static __cxa_thread_info *info = thread_info(); + terminate_handler old = info->terminateHandler; + info->terminateHandler = f; + return old; + } +} + +namespace std +{ + /** + * Sets the function that will be called when an exception specification is + * violated. + */ + unexpected_handler set_unexpected(unexpected_handler f) throw() + { + if (thread_local_handlers) { return pathscale::set_unexpected(f); } + + return ATOMIC_SWAP(&unexpectedHandler, f); + } + /** + * Sets the function that is called to terminate the program. + */ + terminate_handler set_terminate(terminate_handler f) throw() + { + if (thread_local_handlers) { return pathscale::set_terminate(f); } + + return ATOMIC_SWAP(&terminateHandler, f); + } + /** + * Terminates the program, calling a custom terminate implementation if + * required. + */ + void terminate() + { + static __cxa_thread_info *info = thread_info(); + if (0 != info && 0 != info->terminateHandler) + { + info->terminateHandler(); + // Should not be reached - a terminate handler is not expected to + // return. + abort(); + } + terminateHandler(); + } + /** + * Called when an unexpected exception is encountered (i.e. an exception + * violates an exception specification). This calls abort() unless a + * custom handler has been set.. + */ + void unexpected() + { + static __cxa_thread_info *info = thread_info(); + if (0 != info && 0 != info->unexpectedHandler) + { + info->unexpectedHandler(); + // Should not be reached - a terminate handler is not expected to + // return. + abort(); + } + unexpectedHandler(); + } + /** + * Returns whether there are any exceptions currently being thrown that + * have not been caught. This can occur inside a nested catch statement. + */ + bool uncaught_exception() throw() + { + __cxa_thread_info *info = thread_info(); + return info->globals.uncaughtExceptions != 0; + } + /** + * Returns the number of exceptions currently being thrown that have not + * been caught. This can occur inside a nested catch statement. + */ + int uncaught_exceptions() throw() + { + __cxa_thread_info *info = thread_info(); + return info->globals.uncaughtExceptions; + } + /** + * Returns the current unexpected handler. + */ + unexpected_handler get_unexpected() throw() + { + __cxa_thread_info *info = thread_info(); + if (info->unexpectedHandler) + { + return info->unexpectedHandler; + } + return ATOMIC_LOAD(&unexpectedHandler); + } + /** + * Returns the current terminate handler. + */ + terminate_handler get_terminate() throw() + { + __cxa_thread_info *info = thread_info(); + if (info->terminateHandler) + { + return info->terminateHandler; + } + return ATOMIC_LOAD(&terminateHandler); + } +} +#if defined(__arm__) && !defined(__ARM_DWARF_EH__) +extern "C" _Unwind_Exception *__cxa_get_cleanup(void) +{ + __cxa_thread_info *info = thread_info_fast(); + _Unwind_Exception *exceptionObject = info->currentCleanup; + if (isCXXException(exceptionObject->exception_class)) + { + __cxa_exception *ex = exceptionFromPointer(exceptionObject); + ex->cleanupCount--; + if (ex->cleanupCount == 0) + { + info->currentCleanup = ex->nextCleanup; + ex->nextCleanup = 0; + } + } + else + { + info->currentCleanup = 0; + } + return exceptionObject; +} + +asm ( +".pushsection .text.__cxa_end_cleanup \n" +".global __cxa_end_cleanup \n" +".type __cxa_end_cleanup, \"function\" \n" +"__cxa_end_cleanup: \n" +" push {r1, r2, r3, r4} \n" +" bl __cxa_get_cleanup \n" +" push {r1, r2, r3, r4} \n" +" b _Unwind_Resume \n" +" bl abort \n" +".popsection \n" +); +#endif diff --git a/src/libs/libcxxrt/guard.cc b/src/libs/libcxxrt/guard.cc new file mode 100644 index 0000000000..34d294cf74 --- /dev/null +++ b/src/libs/libcxxrt/guard.cc @@ -0,0 +1,193 @@ +/* + * Copyright 2010-2012 PathScale, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * guard.cc: Functions for thread-safe static initialisation. + * + * Static values in C++ can be initialised lazily their first use. This file + * contains functions that are used to ensure that two threads attempting to + * initialize the same static do not call the constructor twice. This is + * important because constructors can have side effects, so calling the + * constructor twice may be very bad. + * + * Statics that require initialisation are protected by a 64-bit value. Any + * platform that can do 32-bit atomic test and set operations can use this + * value as a low-overhead lock. Because statics (in most sane code) are + * accessed far more times than they are initialised, this lock implementation + * is heavily optimised towards the case where the static has already been + * initialised. + */ +#include +#include +#include +#include +#include +#include "atomic.h" + +// Older GCC doesn't define __LITTLE_ENDIAN__ +#ifndef __LITTLE_ENDIAN__ + // If __BYTE_ORDER__ is defined, use that instead +# ifdef __BYTE_ORDER__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define __LITTLE_ENDIAN__ +# endif + // x86 and ARM are the most common little-endian CPUs, so let's have a + // special case for them (ARM is already special cased). Assume everything + // else is big endian. +# elif defined(__x86_64) || defined(__i386) +# define __LITTLE_ENDIAN__ +# endif +#endif + + +/* + * The least significant bit of the guard variable indicates that the object + * has been initialised, the most significant bit is used for a spinlock. + */ +#ifdef __arm__ +// ARM ABI - 32-bit guards. +typedef uint32_t guard_t; +typedef uint32_t guard_lock_t; +static const uint32_t LOCKED = static_cast(1) << 31; +static const uint32_t INITIALISED = 1; +#define LOCK_PART(guard) (guard) +#define INIT_PART(guard) (guard) +#elif defined(_LP64) +typedef uint64_t guard_t; +typedef uint64_t guard_lock_t; +# if defined(__LITTLE_ENDIAN__) +static const guard_t LOCKED = static_cast(1) << 63; +static const guard_t INITIALISED = 1; +# else +static const guard_t LOCKED = 1; +static const guard_t INITIALISED = static_cast(1) << 56; +# endif +#define LOCK_PART(guard) (guard) +#define INIT_PART(guard) (guard) +#else +typedef uint32_t guard_lock_t; +# if defined(__LITTLE_ENDIAN__) +typedef struct { + uint32_t init_half; + uint32_t lock_half; +} guard_t; +static const uint32_t LOCKED = static_cast(1) << 31; +static const uint32_t INITIALISED = 1; +# else +typedef struct { + uint32_t init_half; + uint32_t lock_half; +} guard_t; +static_assert(sizeof(guard_t) == sizeof(uint64_t), ""); +static const uint32_t LOCKED = 1; +static const uint32_t INITIALISED = static_cast(1) << 24; +# endif +#define LOCK_PART(guard) (&(guard)->lock_half) +#define INIT_PART(guard) (&(guard)->init_half) +#endif +static const guard_lock_t INITIAL = 0; + +/** + * Acquires a lock on a guard, returning 0 if the object has already been + * initialised, and 1 if it has not. If the object is already constructed then + * this function just needs to read a byte from memory and return. + */ +extern "C" int __cxa_guard_acquire(volatile guard_t *guard_object) +{ + guard_lock_t old; + // Not an atomic read, doesn't establish a happens-before relationship, but + // if one is already established and we end up seeing an initialised state + // then it's a fast path, otherwise we'll do something more expensive than + // this test anyway... + if (INITIALISED == *INIT_PART(guard_object)) + return 0; + // Spin trying to do the initialisation + for (;;) + { + // Loop trying to move the value of the guard from 0 (not + // locked, not initialised) to the locked-uninitialised + // position. + old = __sync_val_compare_and_swap(LOCK_PART(guard_object), + INITIAL, LOCKED); + if (old == INITIAL) { + // Lock obtained. If lock and init bit are + // in separate words, check for init race. + if (INIT_PART(guard_object) == LOCK_PART(guard_object)) + return 1; + if (INITIALISED != *INIT_PART(guard_object)) + return 1; + + // No need for a memory barrier here, + // see first comment. + *LOCK_PART(guard_object) = INITIAL; + return 0; + } + // If lock and init bit are in the same word, check again + // if we are done. + if (INIT_PART(guard_object) == LOCK_PART(guard_object) && + old == INITIALISED) + return 0; + + assert(old == LOCKED); + // Another thread holds the lock. + // If lock and init bit are in different words, check + // if we are done before yielding and looping. + if (INIT_PART(guard_object) != LOCK_PART(guard_object) && + INITIALISED == *INIT_PART(guard_object)) + return 0; + sched_yield(); + } +} + +/** + * Releases the lock without marking the object as initialised. This function + * is called if initialising a static causes an exception to be thrown. + */ +extern "C" void __cxa_guard_abort(volatile guard_t *guard_object) +{ + __attribute__((unused)) + bool reset = __sync_bool_compare_and_swap(LOCK_PART(guard_object), + LOCKED, INITIAL); + assert(reset); +} +/** + * Releases the guard and marks the object as initialised. This function is + * called after successful initialisation of a static. + */ +extern "C" void __cxa_guard_release(volatile guard_t *guard_object) +{ + guard_lock_t old; + if (INIT_PART(guard_object) == LOCK_PART(guard_object)) + old = LOCKED; + else + old = INITIAL; + __attribute__((unused)) + bool reset = __sync_bool_compare_and_swap(INIT_PART(guard_object), + old, INITIALISED); + assert(reset); + if (INIT_PART(guard_object) != LOCK_PART(guard_object)) + *LOCK_PART(guard_object) = INITIAL; +} diff --git a/src/libs/libcxxrt/libelftc_dem_gnu3.c b/src/libs/libcxxrt/libelftc_dem_gnu3.c new file mode 100644 index 0000000000..70ef3e8e1d --- /dev/null +++ b/src/libs/libcxxrt/libelftc_dem_gnu3.c @@ -0,0 +1,3893 @@ +/*- + * Copyright (c) 2007, 2008 Hyogeol Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @file cpp_demangle.c + * @brief Decode IA-64 C++ ABI style implementation. + * + * IA-64 standard ABI(Itanium C++ ABI) references. + * + * http://www.codesourcery.com/cxx-abi/abi.html#mangling \n + * http://www.codesourcery.com/cxx-abi/abi-mangling.html + */ + +/** @brief Dynamic vector data for string. */ +struct vector_str { + /** Current size */ + size_t size; + /** Total capacity */ + size_t capacity; + /** String array */ + char **container; +}; + +#define BUFFER_GROWFACTOR 1.618 +#define VECTOR_DEF_CAPACITY 8 +#define ELFTC_ISDIGIT(C) (isdigit((C) & 0xFF)) + +enum type_qualifier { + TYPE_PTR, TYPE_REF, TYPE_CMX, TYPE_IMG, TYPE_EXT, TYPE_RST, TYPE_VAT, + TYPE_CST, TYPE_VEC +}; + +struct vector_type_qualifier { + size_t size, capacity; + enum type_qualifier *q_container; + struct vector_str ext_name; +}; + +enum read_cmd { + READ_FAIL, READ_NEST, READ_TMPL, READ_EXPR, READ_EXPL, READ_LOCAL, + READ_TYPE, READ_FUNC, READ_PTRMEM +}; + +struct vector_read_cmd { + size_t size, capacity; + enum read_cmd *r_container; +}; + +struct cpp_demangle_data { + struct vector_str output; /* output string vector */ + struct vector_str output_tmp; + struct vector_str subst; /* substitution string vector */ + struct vector_str tmpl; + struct vector_str class_type; + struct vector_read_cmd cmd; + bool paren; /* parenthesis opened */ + bool pfirst; /* first element of parameter */ + bool mem_rst; /* restrict member function */ + bool mem_vat; /* volatile member function */ + bool mem_cst; /* const member function */ + int func_type; + const char *cur; /* current mangled name ptr */ + const char *last_sname; /* last source name */ + int push_head; +}; + +#define CPP_DEMANGLE_TRY_LIMIT 128 +#define FLOAT_SPRINTF_TRY_LIMIT 5 +#define FLOAT_QUADRUPLE_BYTES 16 +#define FLOAT_EXTENED_BYTES 10 + +#define SIMPLE_HASH(x,y) (64 * x + y) + +static size_t get_strlen_sum(const struct vector_str *v); +static bool vector_str_grow(struct vector_str *v); + +static size_t +get_strlen_sum(const struct vector_str *v) +{ + size_t i, len = 0; + + if (v == NULL) + return (0); + + assert(v->size > 0); + + for (i = 0; i < v->size; ++i) + len += strlen(v->container[i]); + + return (len); +} + +/** + * @brief Deallocate resource in vector_str. + */ +static void +vector_str_dest(struct vector_str *v) +{ + size_t i; + + if (v == NULL) + return; + + for (i = 0; i < v->size; ++i) + free(v->container[i]); + + free(v->container); +} + +/** + * @brief Find string in vector_str. + * @param v Destination vector. + * @param o String to find. + * @param l Length of the string. + * @return -1 at failed, 0 at not found, 1 at found. + */ +static int +vector_str_find(const struct vector_str *v, const char *o, size_t l) +{ + size_t i; + + if (v == NULL || o == NULL) + return (-1); + + for (i = 0; i < v->size; ++i) + if (strncmp(v->container[i], o, l) == 0) + return (1); + + return (0); +} + +/** + * @brief Get new allocated flat string from vector. + * + * If l is not NULL, return length of the string. + * @param v Destination vector. + * @param l Length of the string. + * @return NULL at failed or NUL terminated new allocated string. + */ +static char * +vector_str_get_flat(const struct vector_str *v, size_t *l) +{ + ssize_t elem_pos, elem_size, rtn_size; + size_t i; + char *rtn; + + if (v == NULL || v->size == 0) + return (NULL); + + if ((rtn_size = get_strlen_sum(v)) == 0) + return (NULL); + + if ((rtn = malloc(sizeof(char) * (rtn_size + 1))) == NULL) + return (NULL); + + elem_pos = 0; + for (i = 0; i < v->size; ++i) { + elem_size = strlen(v->container[i]); + + memcpy(rtn + elem_pos, v->container[i], elem_size); + + elem_pos += elem_size; + } + + rtn[rtn_size] = '\0'; + + if (l != NULL) + *l = rtn_size; + + return (rtn); +} + +static bool +vector_str_grow(struct vector_str *v) +{ + size_t i, tmp_cap; + char **tmp_ctn; + + if (v == NULL) + return (false); + + assert(v->capacity > 0); + + tmp_cap = v->capacity * BUFFER_GROWFACTOR; + + assert(tmp_cap > v->capacity); + + if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL) + return (false); + + for (i = 0; i < v->size; ++i) + tmp_ctn[i] = v->container[i]; + + free(v->container); + + v->container = tmp_ctn; + v->capacity = tmp_cap; + + return (true); +} + +/** + * @brief Initialize vector_str. + * @return false at failed, true at success. + */ +static bool +vector_str_init(struct vector_str *v) +{ + + if (v == NULL) + return (false); + + v->size = 0; + v->capacity = VECTOR_DEF_CAPACITY; + + assert(v->capacity > 0); + + if ((v->container = malloc(sizeof(char *) * v->capacity)) == NULL) + return (false); + + assert(v->container != NULL); + + return (true); +} + +/** + * @brief Remove last element in vector_str. + * @return false at failed, true at success. + */ +static bool +vector_str_pop(struct vector_str *v) +{ + + if (v == NULL) + return (false); + + if (v->size == 0) + return (true); + + --v->size; + + free(v->container[v->size]); + v->container[v->size] = NULL; + + return (true); +} + +/** + * @brief Push back string to vector. + * @return false at failed, true at success. + */ +static bool +vector_str_push(struct vector_str *v, const char *str, size_t len) +{ + + if (v == NULL || str == NULL) + return (false); + + if (v->size == v->capacity && vector_str_grow(v) == false) + return (false); + + if ((v->container[v->size] = malloc(sizeof(char) * (len + 1))) == NULL) + return (false); + + snprintf(v->container[v->size], len + 1, "%s", str); + + ++v->size; + + return (true); +} + +/** + * @brief Push front org vector to det vector. + * @return false at failed, true at success. + */ +static bool +vector_str_push_vector_head(struct vector_str *dst, struct vector_str *org) +{ + size_t i, j, tmp_cap; + char **tmp_ctn; + + if (dst == NULL || org == NULL) + return (false); + + tmp_cap = (dst->size + org->size) * BUFFER_GROWFACTOR; + + if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL) + return (false); + + for (i = 0; i < org->size; ++i) + if ((tmp_ctn[i] = strdup(org->container[i])) == NULL) { + for (j = 0; j < i; ++j) + free(tmp_ctn[j]); + + free(tmp_ctn); + + return (false); + } + + for (i = 0; i < dst->size; ++i) + tmp_ctn[i + org->size] = dst->container[i]; + + free(dst->container); + + dst->container = tmp_ctn; + dst->capacity = tmp_cap; + dst->size += org->size; + + return (true); +} + +/** + * @brief Get new allocated flat string from vector between begin and end. + * + * If r_len is not NULL, string length will be returned. + * @return NULL at failed or NUL terminated new allocated string. + */ +static char * +vector_str_substr(const struct vector_str *v, size_t begin, size_t end, + size_t *r_len) +{ + size_t cur, i, len; + char *rtn; + + if (v == NULL || begin > end) + return (NULL); + + len = 0; + for (i = begin; i < end + 1; ++i) + len += strlen(v->container[i]); + + if ((rtn = malloc(sizeof(char) * (len + 1))) == NULL) + return (NULL); + + if (r_len != NULL) + *r_len = len; + + cur = 0; + for (i = begin; i < end + 1; ++i) { + len = strlen(v->container[i]); + memcpy(rtn + cur, v->container[i], len); + cur += len; + } + rtn[cur] = '\0'; + + return (rtn); +} + +static void cpp_demangle_data_dest(struct cpp_demangle_data *); +static int cpp_demangle_data_init(struct cpp_demangle_data *, + const char *); +static int cpp_demangle_get_subst(struct cpp_demangle_data *, size_t); +static int cpp_demangle_get_tmpl_param(struct cpp_demangle_data *, size_t); +static int cpp_demangle_push_fp(struct cpp_demangle_data *, + char *(*)(const char *, size_t)); +static int cpp_demangle_push_str(struct cpp_demangle_data *, const char *, + size_t); +static int cpp_demangle_push_subst(struct cpp_demangle_data *, + const char *, size_t); +static int cpp_demangle_push_subst_v(struct cpp_demangle_data *, + struct vector_str *); +static int cpp_demangle_push_type_qualifier(struct cpp_demangle_data *, + struct vector_type_qualifier *, const char *); +static int cpp_demangle_read_array(struct cpp_demangle_data *); +static int cpp_demangle_read_encoding(struct cpp_demangle_data *); +static int cpp_demangle_read_expr_primary(struct cpp_demangle_data *); +static int cpp_demangle_read_expression(struct cpp_demangle_data *); +static int cpp_demangle_read_expression_flat(struct cpp_demangle_data *, + char **); +static int cpp_demangle_read_expression_binary(struct cpp_demangle_data *, + const char *, size_t); +static int cpp_demangle_read_expression_unary(struct cpp_demangle_data *, + const char *, size_t); +static int cpp_demangle_read_expression_trinary(struct cpp_demangle_data *, + const char *, size_t, const char *, size_t); +static int cpp_demangle_read_function(struct cpp_demangle_data *, int *, + struct vector_type_qualifier *); +static int cpp_demangle_local_source_name(struct cpp_demangle_data *ddata); +static int cpp_demangle_read_local_name(struct cpp_demangle_data *); +static int cpp_demangle_read_name(struct cpp_demangle_data *); +static int cpp_demangle_read_name_flat(struct cpp_demangle_data *, + char**); +static int cpp_demangle_read_nested_name(struct cpp_demangle_data *); +static int cpp_demangle_read_number(struct cpp_demangle_data *, long *); +static int cpp_demangle_read_number_as_string(struct cpp_demangle_data *, + char **); +static int cpp_demangle_read_nv_offset(struct cpp_demangle_data *); +static int cpp_demangle_read_offset(struct cpp_demangle_data *); +static int cpp_demangle_read_offset_number(struct cpp_demangle_data *); +static int cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *); +static int cpp_demangle_read_sname(struct cpp_demangle_data *); +static int cpp_demangle_read_subst(struct cpp_demangle_data *); +static int cpp_demangle_read_subst_std(struct cpp_demangle_data *); +static int cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *, + const char *, size_t); +static int cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *); +static int cpp_demangle_read_tmpl_args(struct cpp_demangle_data *); +static int cpp_demangle_read_tmpl_param(struct cpp_demangle_data *); +static int cpp_demangle_read_type(struct cpp_demangle_data *, int); +static int cpp_demangle_read_type_flat(struct cpp_demangle_data *, + char **); +static int cpp_demangle_read_uqname(struct cpp_demangle_data *); +static int cpp_demangle_read_v_offset(struct cpp_demangle_data *); +static char *decode_fp_to_double(const char *, size_t); +static char *decode_fp_to_float(const char *, size_t); +static char *decode_fp_to_float128(const char *, size_t); +static char *decode_fp_to_float80(const char *, size_t); +static char *decode_fp_to_long_double(const char *, size_t); +static int hex_to_dec(char); +static void vector_read_cmd_dest(struct vector_read_cmd *); +static int vector_read_cmd_find(struct vector_read_cmd *, enum read_cmd); +static int vector_read_cmd_init(struct vector_read_cmd *); +static int vector_read_cmd_pop(struct vector_read_cmd *); +static int vector_read_cmd_push(struct vector_read_cmd *, enum read_cmd); +static void vector_type_qualifier_dest(struct vector_type_qualifier *); +static int vector_type_qualifier_init(struct vector_type_qualifier *); +static int vector_type_qualifier_push(struct vector_type_qualifier *, + enum type_qualifier); + +/** + * @brief Decode the input string by IA-64 C++ ABI style. + * + * GNU GCC v3 use IA-64 standard ABI. + * @return New allocated demangled string or NULL if failed. + * @todo 1. Testing and more test case. 2. Code cleaning. + */ +char * +__cxa_demangle_gnu3(const char *org) +{ + struct cpp_demangle_data ddata; + ssize_t org_len; + unsigned int limit; + char *rtn = NULL; + + if (org == NULL) + return (NULL); + + org_len = strlen(org); + if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) { + if ((rtn = malloc(org_len + 19)) == NULL) + return (NULL); + snprintf(rtn, org_len + 19, + "global constructors keyed to %s", org + 11); + return (rtn); + } + + // Try demangling as a type for short encodings + if ((org_len < 2) || (org[0] != '_' || org[1] != 'Z' )) { + if (!cpp_demangle_data_init(&ddata, org)) + return (NULL); + if (!cpp_demangle_read_type(&ddata, 0)) + goto clean; + rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL); + goto clean; + } + + + if (!cpp_demangle_data_init(&ddata, org + 2)) + return (NULL); + + rtn = NULL; + + if (!cpp_demangle_read_encoding(&ddata)) + goto clean; + + limit = 0; + while (*ddata.cur != '\0') { + /* + * Breaking at some gcc info at tail. e.g) @@GLIBCXX_3.4 + */ + if (*ddata.cur == '@' && *(ddata.cur + 1) == '@') + break; + if (!cpp_demangle_read_type(&ddata, 1)) + goto clean; + if (limit++ > CPP_DEMANGLE_TRY_LIMIT) + goto clean; + } + + if (ddata.output.size == 0) + goto clean; + if (ddata.paren && !vector_str_push(&ddata.output, ")", 1)) + goto clean; + if (ddata.mem_vat && !vector_str_push(&ddata.output, " volatile", 9)) + goto clean; + if (ddata.mem_cst && !vector_str_push(&ddata.output, " const", 6)) + goto clean; + if (ddata.mem_rst && !vector_str_push(&ddata.output, " restrict", 9)) + goto clean; + + rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL); + +clean: + cpp_demangle_data_dest(&ddata); + + return (rtn); +} + +static void +cpp_demangle_data_dest(struct cpp_demangle_data *d) +{ + + if (d == NULL) + return; + + vector_read_cmd_dest(&d->cmd); + vector_str_dest(&d->class_type); + vector_str_dest(&d->tmpl); + vector_str_dest(&d->subst); + vector_str_dest(&d->output_tmp); + vector_str_dest(&d->output); +} + +static int +cpp_demangle_data_init(struct cpp_demangle_data *d, const char *cur) +{ + + if (d == NULL || cur == NULL) + return (0); + + if (!vector_str_init(&d->output)) + return (0); + if (!vector_str_init(&d->output_tmp)) + goto clean1; + if (!vector_str_init(&d->subst)) + goto clean2; + if (!vector_str_init(&d->tmpl)) + goto clean3; + if (!vector_str_init(&d->class_type)) + goto clean4; + if (!vector_read_cmd_init(&d->cmd)) + goto clean5; + + assert(d->output.container != NULL); + assert(d->output_tmp.container != NULL); + assert(d->subst.container != NULL); + assert(d->tmpl.container != NULL); + assert(d->class_type.container != NULL); + + d->paren = false; + d->pfirst = false; + d->mem_rst = false; + d->mem_vat = false; + d->mem_cst = false; + d->func_type = 0; + d->cur = cur; + d->last_sname = NULL; + d->push_head = 0; + + return (1); + +clean5: + vector_str_dest(&d->class_type); +clean4: + vector_str_dest(&d->tmpl); +clean3: + vector_str_dest(&d->subst); +clean2: + vector_str_dest(&d->output_tmp); +clean1: + vector_str_dest(&d->output); + + return (0); +} + +static int +cpp_demangle_push_fp(struct cpp_demangle_data *ddata, + char *(*decoder)(const char *, size_t)) +{ + size_t len; + int rtn; + const char *fp; + char *f; + + if (ddata == NULL || decoder == NULL) + return (0); + + fp = ddata->cur; + while (*ddata->cur != 'E') + ++ddata->cur; + + if ((f = decoder(fp, ddata->cur - fp)) == NULL) + return (0); + + rtn = 0; + if ((len = strlen(f)) > 0) + rtn = cpp_demangle_push_str(ddata, f, len); + + free(f); + + ++ddata->cur; + + return (rtn); +} + +static int +cpp_demangle_push_str(struct cpp_demangle_data *ddata, const char *str, + size_t len) +{ + + if (ddata == NULL || str == NULL || len == 0) + return (0); + + if (ddata->push_head > 0) + return (vector_str_push(&ddata->output_tmp, str, len)); + + return (vector_str_push(&ddata->output, str, len)); +} + +static int +cpp_demangle_push_subst(struct cpp_demangle_data *ddata, const char *str, + size_t len) +{ + + if (ddata == NULL || str == NULL || len == 0) + return (0); + + if (!vector_str_find(&ddata->subst, str, len)) + return (vector_str_push(&ddata->subst, str, len)); + + return (1); +} + +static int +cpp_demangle_push_subst_v(struct cpp_demangle_data *ddata, struct vector_str *v) +{ + size_t str_len; + int rtn; + char *str; + + if (ddata == NULL || v == NULL) + return (0); + + if ((str = vector_str_get_flat(v, &str_len)) == NULL) + return (0); + + rtn = cpp_demangle_push_subst(ddata, str, str_len); + + free(str); + + return (rtn); +} + +static int +cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, + struct vector_type_qualifier *v, const char *type_str) +{ + struct vector_str subst_v; + size_t idx, e_idx, e_len; + int rtn; + char *buf; + + if (ddata == NULL || v == NULL) + return (0); + + if ((idx = v->size) == 0) + return (1); + + rtn = 0; + if (type_str != NULL) { + if (!vector_str_init(&subst_v)) + return (0); + if (!vector_str_push(&subst_v, type_str, strlen(type_str))) + goto clean; + } + + e_idx = 0; + while (idx > 0) { + switch (v->q_container[idx - 1]) { + case TYPE_PTR: + if (!cpp_demangle_push_str(ddata, "*", 1)) + goto clean; + if (type_str != NULL) { + if (!vector_str_push(&subst_v, "*", 1)) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_REF: + if (!cpp_demangle_push_str(ddata, "&", 1)) + goto clean; + if (type_str != NULL) { + if (!vector_str_push(&subst_v, "&", 1)) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_CMX: + if (!cpp_demangle_push_str(ddata, " complex", 8)) + goto clean; + if (type_str != NULL) { + if (!vector_str_push(&subst_v, " complex", 8)) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_IMG: + if (!cpp_demangle_push_str(ddata, " imaginary", 10)) + goto clean; + if (type_str != NULL) { + if (!vector_str_push(&subst_v, " imaginary", + 10)) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_EXT: + if (v->ext_name.size == 0 || + e_idx > v->ext_name.size - 1) + goto clean; + if ((e_len = strlen(v->ext_name.container[e_idx])) == + 0) + goto clean; + if ((buf = malloc(e_len + 2)) == NULL) + goto clean; + snprintf(buf, e_len + 2, " %s", + v->ext_name.container[e_idx]); + + if (!cpp_demangle_push_str(ddata, buf, e_len + 1)) { + free(buf); + goto clean; + } + + if (type_str != NULL) { + if (!vector_str_push(&subst_v, buf, + e_len + 1)) { + free(buf); + goto clean; + } + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) { + free(buf); + goto clean; + } + } + free(buf); + ++e_idx; + break; + + case TYPE_RST: + if (!cpp_demangle_push_str(ddata, " restrict", 9)) + goto clean; + if (type_str != NULL) { + if (!vector_str_push(&subst_v, " restrict", 9)) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_VAT: + if (!cpp_demangle_push_str(ddata, " volatile", 9)) + goto clean; + if (type_str != NULL) { + if (!vector_str_push(&subst_v, " volatile", 9)) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_CST: + if (!cpp_demangle_push_str(ddata, " const", 6)) + goto clean; + if (type_str != NULL) { + if (!vector_str_push(&subst_v, " const", 6)) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_VEC: + if (v->ext_name.size == 0 || + e_idx > v->ext_name.size - 1) + goto clean; + if ((e_len = strlen(v->ext_name.container[e_idx])) == + 0) + goto clean; + if ((buf = malloc(e_len + 12)) == NULL) + goto clean; + snprintf(buf, e_len + 12, " __vector(%s)", + v->ext_name.container[e_idx]); + if (!cpp_demangle_push_str(ddata, buf, e_len + 11)) { + free(buf); + goto clean; + } + if (type_str != NULL) { + if (!vector_str_push(&subst_v, buf, + e_len + 11)) { + free(buf); + goto clean; + } + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) { + free(buf); + goto clean; + } + } + free(buf); + ++e_idx; + break; + }; + --idx; + } + + rtn = 1; +clean: + if (type_str != NULL) + vector_str_dest(&subst_v); + + return (rtn); +} + +static int +cpp_demangle_get_subst(struct cpp_demangle_data *ddata, size_t idx) +{ + size_t len; + + if (ddata == NULL || ddata->subst.size <= idx) + return (0); + if ((len = strlen(ddata->subst.container[idx])) == 0) + return (0); + if (!cpp_demangle_push_str(ddata, ddata->subst.container[idx], len)) + return (0); + + /* skip '_' */ + ++ddata->cur; + + return (1); +} + +static int +cpp_demangle_get_tmpl_param(struct cpp_demangle_data *ddata, size_t idx) +{ + size_t len; + + if (ddata == NULL || ddata->tmpl.size <= idx) + return (0); + if ((len = strlen(ddata->tmpl.container[idx])) == 0) + return (0); + if (!cpp_demangle_push_str(ddata, ddata->tmpl.container[idx], len)) + return (0); + + ++ddata->cur; + + return (1); +} + +static int +cpp_demangle_read_array(struct cpp_demangle_data *ddata) +{ + size_t i, num_len, exp_len, p_idx, idx; + const char *num; + char *exp; + + if (ddata == NULL || *(++ddata->cur) == '\0') + return (0); + + if (*ddata->cur == '_') { + if (*(++ddata->cur) == '\0') + return (0); + + if (!cpp_demangle_read_type(ddata, 0)) + return (0); + + if (!cpp_demangle_push_str(ddata, "[]", 2)) + return (0); + } else { + if (ELFTC_ISDIGIT(*ddata->cur) != 0) { + num = ddata->cur; + while (ELFTC_ISDIGIT(*ddata->cur) != 0) + ++ddata->cur; + if (*ddata->cur != '_') + return (0); + num_len = ddata->cur - num; + assert(num_len > 0); + if (*(++ddata->cur) == '\0') + return (0); + if (!cpp_demangle_read_type(ddata, 0)) + return (0); + if (!cpp_demangle_push_str(ddata, "[", 1)) + return (0); + if (!cpp_demangle_push_str(ddata, num, num_len)) + return (0); + if (!cpp_demangle_push_str(ddata, "]", 1)) + return (0); + } else { + p_idx = ddata->output.size; + if (!cpp_demangle_read_expression(ddata)) + return (0); + if ((exp = vector_str_substr(&ddata->output, p_idx, + ddata->output.size - 1, &exp_len)) == NULL) + return (0); + idx = ddata->output.size; + for (i = p_idx; i < idx; ++i) + if (!vector_str_pop(&ddata->output)) { + free(exp); + return (0); + } + if (*ddata->cur != '_') { + free(exp); + return (0); + } + ++ddata->cur; + if (*ddata->cur == '\0') { + free(exp); + return (0); + } + if (!cpp_demangle_read_type(ddata, 0)) { + free(exp); + return (0); + } + if (!cpp_demangle_push_str(ddata, "[", 1)) { + free(exp); + return (0); + } + if (!cpp_demangle_push_str(ddata, exp, exp_len)) { + free(exp); + return (0); + } + if (!cpp_demangle_push_str(ddata, "]", 1)) { + free(exp); + return (0); + } + free(exp); + } + } + + return (1); +} + +static int +cpp_demangle_read_expr_primary(struct cpp_demangle_data *ddata) +{ + const char *num; + + if (ddata == NULL || *(++ddata->cur) == '\0') + return (0); + + if (*ddata->cur == '_' && *(ddata->cur + 1) == 'Z') { + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + if (!cpp_demangle_read_encoding(ddata)) + return (0); + ++ddata->cur; + return (1); + } + + switch (*ddata->cur) { + case 'b': + if (*(ddata->cur + 2) != 'E') + return (0); + switch (*(++ddata->cur)) { + case '0': + ddata->cur += 2; + return (cpp_demangle_push_str(ddata, "false", 5)); + case '1': + ddata->cur += 2; + return (cpp_demangle_push_str(ddata, "true", 4)); + default: + return (0); + }; + + case 'd': + ++ddata->cur; + return (cpp_demangle_push_fp(ddata, decode_fp_to_double)); + + case 'e': + ++ddata->cur; + if (sizeof(long double) == 10) + return (cpp_demangle_push_fp(ddata, + decode_fp_to_double)); + return (cpp_demangle_push_fp(ddata, decode_fp_to_float80)); + + case 'f': + ++ddata->cur; + return (cpp_demangle_push_fp(ddata, decode_fp_to_float)); + + case 'g': + ++ddata->cur; + if (sizeof(long double) == 16) + return (cpp_demangle_push_fp(ddata, + decode_fp_to_double)); + return (cpp_demangle_push_fp(ddata, decode_fp_to_float128)); + + case 'i': + case 'j': + case 'l': + case 'm': + case 'n': + case 's': + case 't': + case 'x': + case 'y': + if (*(++ddata->cur) == 'n') { + if (!cpp_demangle_push_str(ddata, "-", 1)) + return (0); + ++ddata->cur; + } + num = ddata->cur; + while (*ddata->cur != 'E') { + if (!ELFTC_ISDIGIT(*ddata->cur)) + return (0); + ++ddata->cur; + } + ++ddata->cur; + return (cpp_demangle_push_str(ddata, num, + ddata->cur - num - 1)); + + default: + return (0); + }; +} + +static int +cpp_demangle_read_expression(struct cpp_demangle_data *ddata) +{ + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { + case SIMPLE_HASH('s', 't'): + ddata->cur += 2; + return (cpp_demangle_read_type(ddata, 0)); + + case SIMPLE_HASH('s', 'r'): + ddata->cur += 2; + if (!cpp_demangle_read_type(ddata, 0)) + return (0); + if (!cpp_demangle_read_uqname(ddata)) + return (0); + if (*ddata->cur == 'I') + return (cpp_demangle_read_tmpl_args(ddata)); + return (1); + + case SIMPLE_HASH('a', 'a'): + /* operator && */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "&&", 2)); + + case SIMPLE_HASH('a', 'd'): + /* operator & (unary) */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "&", 1)); + + case SIMPLE_HASH('a', 'n'): + /* operator & */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "&", 1)); + + case SIMPLE_HASH('a', 'N'): + /* operator &= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "&=", 2)); + + case SIMPLE_HASH('a', 'S'): + /* operator = */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "=", 1)); + + case SIMPLE_HASH('c', 'l'): + /* operator () */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "()", 2)); + + case SIMPLE_HASH('c', 'm'): + /* operator , */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, ",", 1)); + + case SIMPLE_HASH('c', 'o'): + /* operator ~ */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "~", 1)); + + case SIMPLE_HASH('c', 'v'): + /* operator (cast) */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "(cast)", 6)); + + case SIMPLE_HASH('d', 'a'): + /* operator delete [] */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "delete []", 9)); + + case SIMPLE_HASH('d', 'e'): + /* operator * (unary) */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "*", 1)); + + case SIMPLE_HASH('d', 'l'): + /* operator delete */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "delete", 6)); + + case SIMPLE_HASH('d', 'v'): + /* operator / */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "/", 1)); + + case SIMPLE_HASH('d', 'V'): + /* operator /= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "/=", 2)); + + case SIMPLE_HASH('e', 'o'): + /* operator ^ */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "^", 1)); + + case SIMPLE_HASH('e', 'O'): + /* operator ^= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "^=", 2)); + + case SIMPLE_HASH('e', 'q'): + /* operator == */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "==", 2)); + + case SIMPLE_HASH('g', 'e'): + /* operator >= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, ">=", 2)); + + case SIMPLE_HASH('g', 't'): + /* operator > */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, ">", 1)); + + case SIMPLE_HASH('i', 'x'): + /* operator [] */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "[]", 2)); + + case SIMPLE_HASH('l', 'e'): + /* operator <= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "<=", 2)); + + case SIMPLE_HASH('l', 's'): + /* operator << */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "<<", 2)); + + case SIMPLE_HASH('l', 'S'): + /* operator <<= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "<<=", 3)); + + case SIMPLE_HASH('l', 't'): + /* operator < */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "<", 1)); + + case SIMPLE_HASH('m', 'i'): + /* operator - */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "-", 1)); + + case SIMPLE_HASH('m', 'I'): + /* operator -= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "-=", 2)); + + case SIMPLE_HASH('m', 'l'): + /* operator * */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "*", 1)); + + case SIMPLE_HASH('m', 'L'): + /* operator *= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "*=", 2)); + + case SIMPLE_HASH('m', 'm'): + /* operator -- */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "--", 2)); + + case SIMPLE_HASH('n', 'a'): + /* operator new[] */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "new []", 6)); + + case SIMPLE_HASH('n', 'e'): + /* operator != */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "!=", 2)); + + case SIMPLE_HASH('n', 'g'): + /* operator - (unary) */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "-", 1)); + + case SIMPLE_HASH('n', 't'): + /* operator ! */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "!", 1)); + + case SIMPLE_HASH('n', 'w'): + /* operator new */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "new", 3)); + + case SIMPLE_HASH('o', 'o'): + /* operator || */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "||", 2)); + + case SIMPLE_HASH('o', 'r'): + /* operator | */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "|", 1)); + + case SIMPLE_HASH('o', 'R'): + /* operator |= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "|=", 2)); + + case SIMPLE_HASH('p', 'l'): + /* operator + */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "+", 1)); + + case SIMPLE_HASH('p', 'L'): + /* operator += */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "+=", 2)); + + case SIMPLE_HASH('p', 'm'): + /* operator ->* */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "->*", 3)); + + case SIMPLE_HASH('p', 'p'): + /* operator ++ */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "++", 2)); + + case SIMPLE_HASH('p', 's'): + /* operator + (unary) */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "+", 1)); + + case SIMPLE_HASH('p', 't'): + /* operator -> */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "->", 2)); + + case SIMPLE_HASH('q', 'u'): + /* operator ? */ + ddata->cur += 2; + return (cpp_demangle_read_expression_trinary(ddata, "?", 1, + ":", 1)); + + case SIMPLE_HASH('r', 'm'): + /* operator % */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "%", 1)); + + case SIMPLE_HASH('r', 'M'): + /* operator %= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "%=", 2)); + + case SIMPLE_HASH('r', 's'): + /* operator >> */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, ">>", 2)); + + case SIMPLE_HASH('r', 'S'): + /* operator >>= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, ">>=", 3)); + + case SIMPLE_HASH('r', 'z'): + /* operator sizeof */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6)); + + case SIMPLE_HASH('s', 'v'): + /* operator sizeof */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6)); + }; + + switch (*ddata->cur) { + case 'L': + return (cpp_demangle_read_expr_primary(ddata)); + case 'T': + return (cpp_demangle_read_tmpl_param(ddata)); + }; + + return (0); +} + +static int +cpp_demangle_read_expression_flat(struct cpp_demangle_data *ddata, char **str) +{ + struct vector_str *output; + size_t i, p_idx, idx, exp_len; + char *exp; + + output = ddata->push_head > 0 ? &ddata->output_tmp : + &ddata->output; + + p_idx = output->size; + + if (!cpp_demangle_read_expression(ddata)) + return (0); + + if ((exp = vector_str_substr(output, p_idx, output->size - 1, + &exp_len)) == NULL) + return (0); + + idx = output->size; + for (i = p_idx; i < idx; ++i) { + if (!vector_str_pop(output)) { + free(exp); + return (0); + } + } + + *str = exp; + + return (1); +} + +static int +cpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata, + const char *name, size_t len) +{ + + if (ddata == NULL || name == NULL || len == 0) + return (0); + if (!cpp_demangle_read_expression(ddata)) + return (0); + if (!cpp_demangle_push_str(ddata, name, len)) + return (0); + + return (cpp_demangle_read_expression(ddata)); +} + +static int +cpp_demangle_read_expression_unary(struct cpp_demangle_data *ddata, + const char *name, size_t len) +{ + + if (ddata == NULL || name == NULL || len == 0) + return (0); + if (!cpp_demangle_read_expression(ddata)) + return (0); + + return (cpp_demangle_push_str(ddata, name, len)); +} + +static int +cpp_demangle_read_expression_trinary(struct cpp_demangle_data *ddata, + const char *name1, size_t len1, const char *name2, size_t len2) +{ + + if (ddata == NULL || name1 == NULL || len1 == 0 || name2 == NULL || + len2 == 0) + return (0); + + if (!cpp_demangle_read_expression(ddata)) + return (0); + if (!cpp_demangle_push_str(ddata, name1, len1)) + return (0); + if (!cpp_demangle_read_expression(ddata)) + return (0); + if (!cpp_demangle_push_str(ddata, name2, len2)) + return (0); + + return (cpp_demangle_read_expression(ddata)); +} + +static int +cpp_demangle_read_function(struct cpp_demangle_data *ddata, int *ext_c, + struct vector_type_qualifier *v) +{ + size_t class_type_size, class_type_len, limit; + const char *class_type; + + if (ddata == NULL || *ddata->cur != 'F' || v == NULL) + return (0); + + ++ddata->cur; + if (*ddata->cur == 'Y') { + if (ext_c != NULL) + *ext_c = 1; + ++ddata->cur; + } + if (!cpp_demangle_read_type(ddata, 0)) + return (0); + if (*ddata->cur != 'E') { + if (!cpp_demangle_push_str(ddata, "(", 1)) + return (0); + if (vector_read_cmd_find(&ddata->cmd, READ_PTRMEM)) { + if ((class_type_size = ddata->class_type.size) == 0) + return (0); + class_type = + ddata->class_type.container[class_type_size - 1]; + if (class_type == NULL) + return (0); + if ((class_type_len = strlen(class_type)) == 0) + return (0); + if (!cpp_demangle_push_str(ddata, class_type, + class_type_len)) + return (0); + if (!cpp_demangle_push_str(ddata, "::*", 3)) + return (0); + ++ddata->func_type; + } else { + if (!cpp_demangle_push_type_qualifier(ddata, v, + (const char *) NULL)) + return (0); + vector_type_qualifier_dest(v); + if (!vector_type_qualifier_init(v)) + return (0); + } + + if (!cpp_demangle_push_str(ddata, ")(", 2)) + return (0); + + limit = 0; + for (;;) { + if (!cpp_demangle_read_type(ddata, 0)) + return (0); + if (*ddata->cur == 'E') + break; + if (limit++ > CPP_DEMANGLE_TRY_LIMIT) + return (0); + } + + if (vector_read_cmd_find(&ddata->cmd, READ_PTRMEM) == 1) { + if (!cpp_demangle_push_type_qualifier(ddata, v, + (const char *) NULL)) + return (0); + vector_type_qualifier_dest(v); + if (!vector_type_qualifier_init(v)) + return (0); + } + + if (!cpp_demangle_push_str(ddata, ")", 1)) + return (0); + } + + ++ddata->cur; + + return (1); +} + +/* read encoding, encoding are function name, data name, special-name */ +static int +cpp_demangle_read_encoding(struct cpp_demangle_data *ddata) +{ + char *name, *type, *num_str; + long offset; + int rtn; + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + /* special name */ + switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { + case SIMPLE_HASH('G', 'A'): + if (!cpp_demangle_push_str(ddata, "hidden alias for ", 17)) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + return (cpp_demangle_read_encoding(ddata)); + + case SIMPLE_HASH('G', 'R'): + if (!cpp_demangle_push_str(ddata, "reference temporary #", 21)) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + if (!cpp_demangle_read_name_flat(ddata, &name)) + return (0); + rtn = 0; + if (!cpp_demangle_read_number_as_string(ddata, &num_str)) + goto clean1; + if (!cpp_demangle_push_str(ddata, num_str, strlen(num_str))) + goto clean2; + if (!cpp_demangle_push_str(ddata, " for ", 5)) + goto clean2; + if (!cpp_demangle_push_str(ddata, name, strlen(name))) + goto clean2; + rtn = 1; + clean2: + free(num_str); + clean1: + free(name); + return (rtn); + + case SIMPLE_HASH('G', 'T'): + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + switch (*ddata->cur) { + case 'n': + if (!cpp_demangle_push_str(ddata, + "non-transaction clone for ", 26)) + return (0); + case 't': + default: + if (!cpp_demangle_push_str(ddata, + "transaction clone for ", 22)) + return (0); + } + ++ddata->cur; + return (cpp_demangle_read_encoding(ddata)); + + case SIMPLE_HASH('G', 'V'): + /* sentry object for 1 time init */ + if (!cpp_demangle_push_str(ddata, "guard variable for ", 20)) + return (0); + ddata->cur += 2; + break; + + case SIMPLE_HASH('T', 'c'): + /* virtual function covariant override thunk */ + if (!cpp_demangle_push_str(ddata, + "virtual function covariant override ", 36)) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + if (!cpp_demangle_read_offset(ddata)) + return (0); + if (!cpp_demangle_read_offset(ddata)) + return (0); + return (cpp_demangle_read_encoding(ddata)); + + case SIMPLE_HASH('T', 'C'): + /* construction vtable */ + if (!cpp_demangle_push_str(ddata, "construction vtable for ", + 24)) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + if (!cpp_demangle_read_type_flat(ddata, &type)) + return (0); + rtn = 0; + if (!cpp_demangle_read_number(ddata, &offset)) + goto clean3; + if (*ddata->cur++ != '_') + goto clean3; + if (!cpp_demangle_read_type(ddata, 0)) + goto clean3; + if (!cpp_demangle_push_str(ddata, "-in-", 4)) + goto clean3; + if (!cpp_demangle_push_str(ddata, type, strlen(type))) + goto clean3; + rtn = 1; + clean3: + free(type); + return (rtn); + + case SIMPLE_HASH('T', 'D'): + /* typeinfo common proxy */ + break; + + case SIMPLE_HASH('T', 'F'): + /* typeinfo fn */ + if (!cpp_demangle_push_str(ddata, "typeinfo fn for ", 16)) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + return (cpp_demangle_read_type(ddata, 0)); + + case SIMPLE_HASH('T', 'h'): + /* virtual function non-virtual override thunk */ + if (!cpp_demangle_push_str(ddata, + "virtual function non-virtual override ", 38)) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + if (!cpp_demangle_read_nv_offset(ddata)) + return (0); + return (cpp_demangle_read_encoding(ddata)); + + case SIMPLE_HASH('T', 'H'): + /* TLS init function */ + if (!cpp_demangle_push_str(ddata, "TLS init function for ", + 22)) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + break; + + case SIMPLE_HASH('T', 'I'): + /* typeinfo structure */ + if (!cpp_demangle_push_str(ddata, "typeinfo for ", 13)) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + return (cpp_demangle_read_type(ddata, 0)); + + case SIMPLE_HASH('T', 'J'): + /* java class */ + if (!cpp_demangle_push_str(ddata, "java Class for ", 15)) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + return (cpp_demangle_read_type(ddata, 0)); + + case SIMPLE_HASH('T', 'S'): + /* RTTI name (NTBS) */ + if (!cpp_demangle_push_str(ddata, "typeinfo name for ", 18)) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + return (cpp_demangle_read_type(ddata, 0)); + + case SIMPLE_HASH('T', 'T'): + /* VTT table */ + if (!cpp_demangle_push_str(ddata, "VTT for ", 8)) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + return (cpp_demangle_read_type(ddata, 0)); + + case SIMPLE_HASH('T', 'v'): + /* virtual function virtual override thunk */ + if (!cpp_demangle_push_str(ddata, + "virtual function virtual override ", 34)) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + if (!cpp_demangle_read_v_offset(ddata)) + return (0); + return (cpp_demangle_read_encoding(ddata)); + + case SIMPLE_HASH('T', 'V'): + /* virtual table */ + if (!cpp_demangle_push_str(ddata, "vtable for ", 12)) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + return (cpp_demangle_read_type(ddata, 0)); + + case SIMPLE_HASH('T', 'W'): + /* TLS wrapper function */ + if (!cpp_demangle_push_str(ddata, "TLS wrapper function for ", + 25)) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + break; + }; + + return (cpp_demangle_read_name(ddata)); +} + +static int +cpp_demangle_read_local_name(struct cpp_demangle_data *ddata) +{ + size_t limit; + + if (ddata == NULL) + return (0); + if (*(++ddata->cur) == '\0') + return (0); + if (!cpp_demangle_read_encoding(ddata)) + return (0); + + limit = 0; + for (;;) { + if (!cpp_demangle_read_type(ddata, 1)) + return (0); + if (*ddata->cur == 'E') + break; + if (limit++ > CPP_DEMANGLE_TRY_LIMIT) + return (0); + } + if (*(++ddata->cur) == '\0') + return (0); + if (ddata->paren == true) { + if (!cpp_demangle_push_str(ddata, ")", 1)) + return (0); + ddata->paren = false; + } + if (*ddata->cur == 's') + ++ddata->cur; + else { + if (!cpp_demangle_push_str(ddata, "::", 2)) + return (0); + if (!cpp_demangle_read_name(ddata)) + return (0); + } + if (*ddata->cur == '_') { + ++ddata->cur; + while (ELFTC_ISDIGIT(*ddata->cur) != 0) + ++ddata->cur; + } + + return (1); +} + +static int +cpp_demangle_read_name(struct cpp_demangle_data *ddata) +{ + struct vector_str *output, v; + size_t p_idx, subst_str_len; + int rtn; + char *subst_str; + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; + + subst_str = NULL; + + switch (*ddata->cur) { + case 'S': + return (cpp_demangle_read_subst(ddata)); + case 'N': + return (cpp_demangle_read_nested_name(ddata)); + case 'Z': + return (cpp_demangle_read_local_name(ddata)); + }; + + if (!vector_str_init(&v)) + return (0); + + p_idx = output->size; + rtn = 0; + if (!cpp_demangle_read_uqname(ddata)) + goto clean; + if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, + &subst_str_len)) == NULL) + goto clean; + if (subst_str_len > 8 && strstr(subst_str, "operator") != NULL) { + rtn = 1; + goto clean; + } + if (!vector_str_push(&v, subst_str, subst_str_len)) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, &v)) + goto clean; + + if (*ddata->cur == 'I') { + p_idx = output->size; + if (!cpp_demangle_read_tmpl_args(ddata)) + goto clean; + free(subst_str); + if ((subst_str = vector_str_substr(output, p_idx, + output->size - 1, &subst_str_len)) == NULL) + goto clean; + if (!vector_str_push(&v, subst_str, subst_str_len)) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, &v)) + goto clean; + } + + rtn = 1; + +clean: + free(subst_str); + vector_str_dest(&v); + + return (rtn); +} + +static int +cpp_demangle_read_name_flat(struct cpp_demangle_data *ddata, char **str) +{ + struct vector_str *output; + size_t i, p_idx, idx, name_len; + char *name; + + output = ddata->push_head > 0 ? &ddata->output_tmp : + &ddata->output; + + p_idx = output->size; + + if (!cpp_demangle_read_name(ddata)) + return (0); + + if ((name = vector_str_substr(output, p_idx, output->size - 1, + &name_len)) == NULL) + return (0); + + idx = output->size; + for (i = p_idx; i < idx; ++i) { + if (!vector_str_pop(output)) { + free(name); + return (0); + } + } + + *str = name; + + return (1); +} + +static int +cpp_demangle_read_nested_name(struct cpp_demangle_data *ddata) +{ + struct vector_str *output, v; + size_t limit, p_idx, subst_str_len; + int rtn; + char *subst_str; + + if (ddata == NULL || *ddata->cur != 'N') + return (0); + if (*(++ddata->cur) == '\0') + return (0); + + while (*ddata->cur == 'r' || *ddata->cur == 'V' || + *ddata->cur == 'K') { + switch (*ddata->cur) { + case 'r': + ddata->mem_rst = true; + break; + case 'V': + ddata->mem_vat = true; + break; + case 'K': + ddata->mem_cst = true; + break; + }; + ++ddata->cur; + } + + output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; + if (!vector_str_init(&v)) + return (0); + + rtn = 0; + limit = 0; + for (;;) { + p_idx = output->size; + switch (*ddata->cur) { + case 'I': + if (!cpp_demangle_read_tmpl_args(ddata)) + goto clean; + break; + case 'S': + if (!cpp_demangle_read_subst(ddata)) + goto clean; + break; + case 'T': + if (!cpp_demangle_read_tmpl_param(ddata)) + goto clean; + break; + default: + if (!cpp_demangle_read_uqname(ddata)) + goto clean; + }; + + if ((subst_str = vector_str_substr(output, p_idx, + output->size - 1, &subst_str_len)) == NULL) + goto clean; + if (!vector_str_push(&v, subst_str, subst_str_len)) { + free(subst_str); + goto clean; + } + free(subst_str); + + if (!cpp_demangle_push_subst_v(ddata, &v)) + goto clean; + if (*ddata->cur == 'E') + break; + else if (*ddata->cur != 'I' && + *ddata->cur != 'C' && *ddata->cur != 'D') { + if (!cpp_demangle_push_str(ddata, "::", 2)) + goto clean; + if (!vector_str_push(&v, "::", 2)) + goto clean; + } + if (limit++ > CPP_DEMANGLE_TRY_LIMIT) + goto clean; + } + + ++ddata->cur; + rtn = 1; + +clean: + vector_str_dest(&v); + + return (rtn); +} + +/* + * read number + * number ::= [n] + */ +static int +cpp_demangle_read_number(struct cpp_demangle_data *ddata, long *rtn) +{ + long len, negative_factor; + + if (ddata == NULL || rtn == NULL) + return (0); + + negative_factor = 1; + if (*ddata->cur == 'n') { + negative_factor = -1; + + ++ddata->cur; + } + if (ELFTC_ISDIGIT(*ddata->cur) == 0) + return (0); + + errno = 0; + if ((len = strtol(ddata->cur, (char **) NULL, 10)) == 0 && + errno != 0) + return (0); + + while (ELFTC_ISDIGIT(*ddata->cur) != 0) + ++ddata->cur; + + assert(len >= 0); + assert(negative_factor == 1 || negative_factor == -1); + + *rtn = len * negative_factor; + + return (1); +} + +static int +cpp_demangle_read_number_as_string(struct cpp_demangle_data *ddata, char **str) +{ + long n; + + if (!cpp_demangle_read_number(ddata, &n)) { + *str = NULL; + return (0); + } + + if (asprintf(str, "%ld", n) < 0) { + *str = NULL; + return (0); + } + + return (1); +} + +static int +cpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata) +{ + + if (ddata == NULL) + return (0); + + if (!cpp_demangle_push_str(ddata, "offset : ", 9)) + return (0); + + return (cpp_demangle_read_offset_number(ddata)); +} + +/* read offset, offset are nv-offset, v-offset */ +static int +cpp_demangle_read_offset(struct cpp_demangle_data *ddata) +{ + + if (ddata == NULL) + return (0); + + if (*ddata->cur == 'h') { + ++ddata->cur; + return (cpp_demangle_read_nv_offset(ddata)); + } else if (*ddata->cur == 'v') { + ++ddata->cur; + return (cpp_demangle_read_v_offset(ddata)); + } + + return (0); +} + +static int +cpp_demangle_read_offset_number(struct cpp_demangle_data *ddata) +{ + bool negative; + const char *start; + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + /* offset could be negative */ + if (*ddata->cur == 'n') { + negative = true; + start = ddata->cur + 1; + } else { + negative = false; + start = ddata->cur; + } + + while (*ddata->cur != '_') + ++ddata->cur; + + if (negative && !cpp_demangle_push_str(ddata, "-", 1)) + return (0); + + assert(start != NULL); + + if (!cpp_demangle_push_str(ddata, start, ddata->cur - start)) + return (0); + if (!cpp_demangle_push_str(ddata, " ", 1)) + return (0); + + ++ddata->cur; + + return (1); +} + +static int +cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *ddata) +{ + size_t class_type_len, i, idx, p_idx; + int p_func_type, rtn; + char *class_type; + + if (ddata == NULL || *ddata->cur != 'M' || *(++ddata->cur) == '\0') + return (0); + + p_idx = ddata->output.size; + if (!cpp_demangle_read_type(ddata, 0)) + return (0); + + if ((class_type = vector_str_substr(&ddata->output, p_idx, + ddata->output.size - 1, &class_type_len)) == NULL) + return (0); + + rtn = 0; + idx = ddata->output.size; + for (i = p_idx; i < idx; ++i) + if (!vector_str_pop(&ddata->output)) + goto clean1; + + if (!vector_read_cmd_push(&ddata->cmd, READ_PTRMEM)) + goto clean1; + + if (!vector_str_push(&ddata->class_type, class_type, class_type_len)) + goto clean2; + + p_func_type = ddata->func_type; + if (!cpp_demangle_read_type(ddata, 0)) + goto clean3; + + if (p_func_type == ddata->func_type) { + if (!cpp_demangle_push_str(ddata, " ", 1)) + goto clean3; + if (!cpp_demangle_push_str(ddata, class_type, class_type_len)) + goto clean3; + if (!cpp_demangle_push_str(ddata, "::*", 3)) + goto clean3; + } + + rtn = 1; +clean3: + if (!vector_str_pop(&ddata->class_type)) + rtn = 0; +clean2: + if (!vector_read_cmd_pop(&ddata->cmd)) + rtn = 0; +clean1: + free(class_type); + + return (rtn); +} + +/* read source-name, source-name is */ +static int +cpp_demangle_read_sname(struct cpp_demangle_data *ddata) +{ + long len; + int err; + + if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 || + len <= 0) + return (0); + + if (len == 12 && (memcmp("_GLOBAL__N_1", ddata->cur, 12) == 0)) + err = cpp_demangle_push_str(ddata, "(anonymous namespace)", 21); + else + err = cpp_demangle_push_str(ddata, ddata->cur, len); + + if (err == 0) + return (0); + + assert(ddata->output.size > 0); + if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == 0) + ddata->last_sname = + ddata->output.container[ddata->output.size - 1]; + + ddata->cur += len; + + return (1); +} + +static int +cpp_demangle_read_subst(struct cpp_demangle_data *ddata) +{ + long nth; + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + /* abbreviations of the form Sx */ + switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { + case SIMPLE_HASH('S', 'a'): + /* std::allocator */ + if (cpp_demangle_push_str(ddata, "std::allocator", 14) == 0) + return (0); + ddata->cur += 2; + if (*ddata->cur == 'I') + return (cpp_demangle_read_subst_stdtmpl(ddata, + "std::allocator", 14)); + return (1); + + case SIMPLE_HASH('S', 'b'): + /* std::basic_string */ + if (!cpp_demangle_push_str(ddata, "std::basic_string", 17)) + return (0); + ddata->cur += 2; + if (*ddata->cur == 'I') + return (cpp_demangle_read_subst_stdtmpl(ddata, + "std::basic_string", 17)); + return (1); + + case SIMPLE_HASH('S', 'd'): + /* std::basic_iostream > */ + if (!cpp_demangle_push_str(ddata, "std::iostream", 19)) + return (0); + ddata->last_sname = "iostream"; + ddata->cur += 2; + if (*ddata->cur == 'I') + return (cpp_demangle_read_subst_stdtmpl(ddata, + "std::iostream", 19)); + return (1); + + case SIMPLE_HASH('S', 'i'): + /* std::basic_istream > */ + if (!cpp_demangle_push_str(ddata, "std::istream", 18)) + return (0); + ddata->last_sname = "istream"; + ddata->cur += 2; + if (*ddata->cur == 'I') + return (cpp_demangle_read_subst_stdtmpl(ddata, + "std::istream", 18)); + return (1); + + case SIMPLE_HASH('S', 'o'): + /* std::basic_ostream > */ + if (!cpp_demangle_push_str(ddata, "std::ostream", 18)) + return (0); + ddata->last_sname = "istream"; + ddata->cur += 2; + if (*ddata->cur == 'I') + return (cpp_demangle_read_subst_stdtmpl(ddata, + "std::ostream", 18)); + return (1); + + case SIMPLE_HASH('S', 's'): + /* + * std::basic_string, + * std::allocator > + * + * a.k.a std::string + */ + if (!cpp_demangle_push_str(ddata, "std::string", 11)) + return (0); + ddata->last_sname = "string"; + ddata->cur += 2; + if (*ddata->cur == 'I') + return (cpp_demangle_read_subst_stdtmpl(ddata, + "std::string", 11)); + return (1); + + case SIMPLE_HASH('S', 't'): + /* std:: */ + return (cpp_demangle_read_subst_std(ddata)); + }; + + if (*(++ddata->cur) == '\0') + return (0); + + /* substitution */ + if (*ddata->cur == '_') + return (cpp_demangle_get_subst(ddata, 0)); + else { + errno = 0; + /* substitution number is base 36 */ + if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 && + errno != 0) + return (0); + + /* first was '_', so increase one */ + ++nth; + + while (*ddata->cur != '_') + ++ddata->cur; + + assert(nth > 0); + + return (cpp_demangle_get_subst(ddata, nth)); + } + + /* NOTREACHED */ + return (0); +} + +static int +cpp_demangle_read_subst_std(struct cpp_demangle_data *ddata) +{ + struct vector_str *output, v; + size_t p_idx, subst_str_len; + int rtn; + char *subst_str; + + if (ddata == NULL) + return (0); + + if (!vector_str_init(&v)) + return (0); + + subst_str = NULL; + rtn = 0; + if (!cpp_demangle_push_str(ddata, "std::", 5)) + goto clean; + + if (!vector_str_push(&v, "std::", 5)) + goto clean; + + ddata->cur += 2; + + output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; + + p_idx = output->size; + if (!cpp_demangle_read_uqname(ddata)) + goto clean; + + if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, + &subst_str_len)) == NULL) + goto clean; + + if (!vector_str_push(&v, subst_str, subst_str_len)) + goto clean; + + if (!cpp_demangle_push_subst_v(ddata, &v)) + goto clean; + + if (*ddata->cur == 'I') { + p_idx = output->size; + if (!cpp_demangle_read_tmpl_args(ddata)) + goto clean; + free(subst_str); + if ((subst_str = vector_str_substr(output, p_idx, + output->size - 1, &subst_str_len)) == NULL) + goto clean; + if (!vector_str_push(&v, subst_str, subst_str_len)) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, &v)) + goto clean; + } + + rtn = 1; +clean: + free(subst_str); + vector_str_dest(&v); + + return (rtn); +} + +static int +cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *ddata, + const char *str, size_t len) +{ + struct vector_str *output; + size_t p_idx, substr_len; + int rtn; + char *subst_str, *substr; + + if (ddata == NULL || str == NULL || len == 0) + return (0); + + output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; + + p_idx = output->size; + substr = NULL; + subst_str = NULL; + + if (!cpp_demangle_read_tmpl_args(ddata)) + return (0); + if ((substr = vector_str_substr(output, p_idx, output->size - 1, + &substr_len)) == NULL) + return (0); + + rtn = 0; + if ((subst_str = malloc(sizeof(char) * (substr_len + len + 1))) == + NULL) + goto clean; + + memcpy(subst_str, str, len); + memcpy(subst_str + len, substr, substr_len); + subst_str[substr_len + len] = '\0'; + + if (!cpp_demangle_push_subst(ddata, subst_str, substr_len + len)) + goto clean; + + rtn = 1; +clean: + free(subst_str); + free(substr); + + return (rtn); +} + +static int +cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *ddata) +{ + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + switch (*ddata->cur) { + case 'L': + return (cpp_demangle_read_expr_primary(ddata)); + case 'X': + return (cpp_demangle_read_expression(ddata)); + }; + + return (cpp_demangle_read_type(ddata, 0)); +} + +static int +cpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata) +{ + struct vector_str *v; + size_t arg_len, idx, limit, size; + char *arg; + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + ++ddata->cur; + + if (!vector_read_cmd_push(&ddata->cmd, READ_TMPL)) + return (0); + + if (!cpp_demangle_push_str(ddata, "<", 1)) + return (0); + + limit = 0; + v = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; + for (;;) { + idx = v->size; + if (!cpp_demangle_read_tmpl_arg(ddata)) + return (0); + if ((arg = vector_str_substr(v, idx, v->size - 1, &arg_len)) == + NULL) + return (0); + if (!vector_str_find(&ddata->tmpl, arg, arg_len) && + !vector_str_push(&ddata->tmpl, arg, arg_len)) { + free(arg); + return (0); + } + + free(arg); + + if (*ddata->cur == 'E') { + ++ddata->cur; + size = v->size; + assert(size > 0); + if (!strncmp(v->container[size - 1], ">", 1)) { + if (!cpp_demangle_push_str(ddata, " >", 2)) + return (0); + } else if (!cpp_demangle_push_str(ddata, ">", 1)) + return (0); + break; + } else if (*ddata->cur != 'I' && + !cpp_demangle_push_str(ddata, ", ", 2)) + return (0); + + if (limit++ > CPP_DEMANGLE_TRY_LIMIT) + return (0); + } + + return (vector_read_cmd_pop(&ddata->cmd)); +} + +/* + * Read template parameter that forms in 'T[number]_'. + * This function much like to read_subst but only for types. + */ +static int +cpp_demangle_read_tmpl_param(struct cpp_demangle_data *ddata) +{ + long nth; + + if (ddata == NULL || *ddata->cur != 'T') + return (0); + + ++ddata->cur; + + if (*ddata->cur == '_') + return (cpp_demangle_get_tmpl_param(ddata, 0)); + else { + + errno = 0; + if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 && + errno != 0) + return (0); + + /* T_ is first */ + ++nth; + + while (*ddata->cur != '_') + ++ddata->cur; + + assert(nth > 0); + + return (cpp_demangle_get_tmpl_param(ddata, nth)); + } + + /* NOTREACHED */ + return (0); +} + +static int +cpp_demangle_read_type(struct cpp_demangle_data *ddata, int delimit) +{ + struct vector_type_qualifier v; + struct vector_str *output; + size_t p_idx, type_str_len; + int extern_c, is_builtin; + long len; + char *type_str, *exp_str, *num_str; + + if (ddata == NULL) + return (0); + + output = &ddata->output; + if (ddata->output.size > 0 && !strncmp(ddata->output.container[ddata->output.size - 1], ">", 1)) { + ddata->push_head++; + output = &ddata->output_tmp; + } else if (delimit == 1) { + if (ddata->paren == false) { + if (!cpp_demangle_push_str(ddata, "(", 1)) + return (0); + if (ddata->output.size < 2) + return (0); + ddata->paren = true; + ddata->pfirst = true; + /* Need pop function name */ + if (ddata->subst.size == 1 && + !vector_str_pop(&ddata->subst)) + return (0); + } + + if (ddata->pfirst) + ddata->pfirst = false; + else if (*ddata->cur != 'I' && + !cpp_demangle_push_str(ddata, ", ", 2)) + return (0); + } + + assert(output != NULL); + /* + * [r, V, K] [P, R, C, G, U] builtin, function, class-enum, array + * pointer-to-member, template-param, template-template-param, subst + */ + + if (!vector_type_qualifier_init(&v)) + return (0); + + extern_c = 0; + is_builtin = 1; + p_idx = output->size; + type_str = exp_str = num_str = NULL; +again: + /* builtin type */ + switch (*ddata->cur) { + case 'a': + /* signed char */ + if (!cpp_demangle_push_str(ddata, "signed char", 11)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'A': + /* array type */ + if (!cpp_demangle_read_array(ddata)) + goto clean; + is_builtin = 0; + goto rtn; + + case 'b': + /* bool */ + if (!cpp_demangle_push_str(ddata, "bool", 4)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'C': + /* complex pair */ + if (!vector_type_qualifier_push(&v, TYPE_CMX)) + goto clean; + ++ddata->cur; + goto again; + + case 'c': + /* char */ + if (!cpp_demangle_push_str(ddata, "char", 4)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'd': + /* double */ + if (!cpp_demangle_push_str(ddata, "double", 6)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'D': + ++ddata->cur; + switch (*ddata->cur) { + case 'd': + /* IEEE 754r decimal floating point (64 bits) */ + if (!cpp_demangle_push_str(ddata, "decimal64", 9)) + goto clean; + ++ddata->cur; + break; + case 'e': + /* IEEE 754r decimal floating point (128 bits) */ + if (!cpp_demangle_push_str(ddata, "decimal128", 10)) + goto clean; + ++ddata->cur; + break; + case 'f': + /* IEEE 754r decimal floating point (32 bits) */ + if (!cpp_demangle_push_str(ddata, "decimal32", 9)) + goto clean; + ++ddata->cur; + break; + case 'h': + /* IEEE 754r half-precision floating point (16 bits) */ + if (!cpp_demangle_push_str(ddata, "half", 4)) + goto clean; + ++ddata->cur; + break; + case 'i': + /* char32_t */ + if (!cpp_demangle_push_str(ddata, "char32_t", 8)) + goto clean; + ++ddata->cur; + break; + case 'n': + /* std::nullptr_t (i.e., decltype(nullptr)) */ + if (!cpp_demangle_push_str(ddata, "decltype(nullptr)", + 17)) + goto clean; + ++ddata->cur; + break; + case 's': + /* char16_t */ + if (!cpp_demangle_push_str(ddata, "char16_t", 8)) + goto clean; + ++ddata->cur; + break; + case 'v': + /* gcc vector_size extension. */ + ++ddata->cur; + if (*ddata->cur == '_') { + ++ddata->cur; + if (!cpp_demangle_read_expression_flat(ddata, + &exp_str)) + goto clean; + if (!vector_str_push(&v.ext_name, exp_str, + strlen(exp_str))) + goto clean; + } else { + if (!cpp_demangle_read_number_as_string(ddata, + &num_str)) + goto clean; + if (!vector_str_push(&v.ext_name, num_str, + strlen(num_str))) + goto clean; + } + if (*ddata->cur != '_') + goto clean; + ++ddata->cur; + if (!vector_type_qualifier_push(&v, TYPE_VEC)) + goto clean; + goto again; + default: + goto clean; + } + goto rtn; + + case 'e': + /* long double */ + if (!cpp_demangle_push_str(ddata, "long double", 11)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'f': + /* float */ + if (!cpp_demangle_push_str(ddata, "float", 5)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'F': + /* function */ + if (!cpp_demangle_read_function(ddata, &extern_c, &v)) + goto clean; + is_builtin = 0; + goto rtn; + + case 'g': + /* __float128 */ + if (!cpp_demangle_push_str(ddata, "__float128", 10)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'G': + /* imaginary */ + if (!vector_type_qualifier_push(&v, TYPE_IMG)) + goto clean; + ++ddata->cur; + goto again; + + case 'h': + /* unsigned char */ + if (!cpp_demangle_push_str(ddata, "unsigned char", 13)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'i': + /* int */ + if (!cpp_demangle_push_str(ddata, "int", 3)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'j': + /* unsigned int */ + if (!cpp_demangle_push_str(ddata, "unsigned int", 12)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'K': + /* const */ + if (!vector_type_qualifier_push(&v, TYPE_CST)) + goto clean; + ++ddata->cur; + goto again; + + case 'l': + /* long */ + if (!cpp_demangle_push_str(ddata, "long", 4)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'm': + /* unsigned long */ + if (!cpp_demangle_push_str(ddata, "unsigned long", 13)) + goto clean; + + ++ddata->cur; + + goto rtn; + case 'M': + /* pointer to member */ + if (!cpp_demangle_read_pointer_to_member(ddata)) + goto clean; + is_builtin = 0; + goto rtn; + + case 'n': + /* __int128 */ + if (!cpp_demangle_push_str(ddata, "__int128", 8)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'o': + /* unsigned __int128 */ + if (!cpp_demangle_push_str(ddata, "unsigned __int128", 17)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'P': + /* pointer */ + if (!vector_type_qualifier_push(&v, TYPE_PTR)) + goto clean; + ++ddata->cur; + goto again; + + case 'r': + /* restrict */ + if (!vector_type_qualifier_push(&v, TYPE_RST)) + goto clean; + ++ddata->cur; + goto again; + + case 'R': + /* reference */ + if (!vector_type_qualifier_push(&v, TYPE_REF)) + goto clean; + ++ddata->cur; + goto again; + + case 's': + /* short, local string */ + if (!cpp_demangle_push_str(ddata, "short", 5)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'S': + /* substitution */ + if (!cpp_demangle_read_subst(ddata)) + goto clean; + is_builtin = 0; + goto rtn; + + case 't': + /* unsigned short */ + if (!cpp_demangle_push_str(ddata, "unsigned short", 14)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'T': + /* template parameter */ + if (!cpp_demangle_read_tmpl_param(ddata)) + goto clean; + is_builtin = 0; + goto rtn; + + case 'u': + /* vendor extended builtin */ + ++ddata->cur; + if (!cpp_demangle_read_sname(ddata)) + goto clean; + is_builtin = 0; + goto rtn; + + case 'U': + /* vendor extended type qualifier */ + if (!cpp_demangle_read_number(ddata, &len)) + goto clean; + if (len <= 0) + goto clean; + if (!vector_str_push(&v.ext_name, ddata->cur, len)) + return (0); + ddata->cur += len; + if (!vector_type_qualifier_push(&v, TYPE_EXT)) + goto clean; + goto again; + + case 'v': + /* void */ + if (!cpp_demangle_push_str(ddata, "void", 4)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'V': + /* volatile */ + if (!vector_type_qualifier_push(&v, TYPE_VAT)) + goto clean; + ++ddata->cur; + goto again; + + case 'w': + /* wchar_t */ + if (!cpp_demangle_push_str(ddata, "wchar_t", 6)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'x': + /* long long */ + if (!cpp_demangle_push_str(ddata, "long long", 9)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'y': + /* unsigned long long */ + if (!cpp_demangle_push_str(ddata, "unsigned long long", 18)) + goto clean; + ++ddata->cur; + goto rtn; + + case 'z': + /* ellipsis */ + if (!cpp_demangle_push_str(ddata, "ellipsis", 8)) + goto clean; + ++ddata->cur; + goto rtn; + }; + + if (!cpp_demangle_read_name(ddata)) + goto clean; + + is_builtin = 0; +rtn: + if ((type_str = vector_str_substr(output, p_idx, output->size - 1, + &type_str_len)) == NULL) + goto clean; + + if (is_builtin == 0) { + if (!vector_str_find(&ddata->subst, type_str, type_str_len) && + !vector_str_push(&ddata->subst, type_str, type_str_len)) + goto clean; + } + + if (!cpp_demangle_push_type_qualifier(ddata, &v, type_str)) + goto clean; + + free(type_str); + free(exp_str); + free(num_str); + vector_type_qualifier_dest(&v); + + if (ddata->push_head > 0) { + if (*ddata->cur == 'I' && cpp_demangle_read_tmpl_args(ddata) + == 0) + return (0); + + if (--ddata->push_head > 0) + return (1); + + if (!vector_str_push(&ddata->output_tmp, " ", 1)) + return (0); + + if (!vector_str_push_vector_head(&ddata->output, + &ddata->output_tmp)) + return (0); + + vector_str_dest(&ddata->output_tmp); + if (!vector_str_init(&ddata->output_tmp)) + return (0); + + if (!cpp_demangle_push_str(ddata, "(", 1)) + return (0); + + ddata->paren = true; + ddata->pfirst = true; + } + + return (1); +clean: + free(type_str); + free(exp_str); + free(num_str); + vector_type_qualifier_dest(&v); + + return (0); +} + +static int +cpp_demangle_read_type_flat(struct cpp_demangle_data *ddata, char **str) +{ + struct vector_str *output; + size_t i, p_idx, idx, type_len; + char *type; + + output = ddata->push_head > 0 ? &ddata->output_tmp : + &ddata->output; + + p_idx = output->size; + + if (!cpp_demangle_read_type(ddata, 0)) + return (0); + + if ((type = vector_str_substr(output, p_idx, output->size - 1, + &type_len)) == NULL) + return (0); + + idx = output->size; + for (i = p_idx; i < idx; ++i) { + if (!vector_str_pop(output)) { + free(type); + return (0); + } + } + + *str = type; + + return (1); +} + +/* + * read unqualified-name, unqualified name are operator-name, ctor-dtor-name, + * source-name + */ +static int +cpp_demangle_read_uqname(struct cpp_demangle_data *ddata) +{ + size_t len; + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + /* operator name */ + switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { + case SIMPLE_HASH('a', 'a'): + /* operator && */ + if (!cpp_demangle_push_str(ddata, "operator&&", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('a', 'd'): + /* operator & (unary) */ + if (!cpp_demangle_push_str(ddata, "operator&", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('a', 'n'): + /* operator & */ + if (!cpp_demangle_push_str(ddata, "operator&", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('a', 'N'): + /* operator &= */ + if (!cpp_demangle_push_str(ddata, "operator&=", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('a', 'S'): + /* operator = */ + if (!cpp_demangle_push_str(ddata, "operator=", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('c', 'l'): + /* operator () */ + if (!cpp_demangle_push_str(ddata, "operator()", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('c', 'm'): + /* operator , */ + if (!cpp_demangle_push_str(ddata, "operator,", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('c', 'o'): + /* operator ~ */ + if (!cpp_demangle_push_str(ddata, "operator~", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('c', 'v'): + /* operator (cast) */ + if (!cpp_demangle_push_str(ddata, "operator(cast)", 14)) + return (0); + ddata->cur += 2; + return (cpp_demangle_read_type(ddata, 1)); + + case SIMPLE_HASH('d', 'a'): + /* operator delete [] */ + if (!cpp_demangle_push_str(ddata, "operator delete []", 18)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('d', 'e'): + /* operator * (unary) */ + if (!cpp_demangle_push_str(ddata, "operator*", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('d', 'l'): + /* operator delete */ + if (!cpp_demangle_push_str(ddata, "operator delete", 15)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('d', 'v'): + /* operator / */ + if (!cpp_demangle_push_str(ddata, "operator/", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('d', 'V'): + /* operator /= */ + if (!cpp_demangle_push_str(ddata, "operator/=", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('e', 'o'): + /* operator ^ */ + if (!cpp_demangle_push_str(ddata, "operator^", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('e', 'O'): + /* operator ^= */ + if (!cpp_demangle_push_str(ddata, "operator^=", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('e', 'q'): + /* operator == */ + if (!cpp_demangle_push_str(ddata, "operator==", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('g', 'e'): + /* operator >= */ + if (!cpp_demangle_push_str(ddata, "operator>=", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('g', 't'): + /* operator > */ + if (!cpp_demangle_push_str(ddata, "operator>", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('i', 'x'): + /* operator [] */ + if (!cpp_demangle_push_str(ddata, "operator[]", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('l', 'e'): + /* operator <= */ + if (!cpp_demangle_push_str(ddata, "operator<=", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('l', 's'): + /* operator << */ + if (!cpp_demangle_push_str(ddata, "operator<<", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('l', 'S'): + /* operator <<= */ + if (!cpp_demangle_push_str(ddata, "operator<<=", 11)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('l', 't'): + /* operator < */ + if (!cpp_demangle_push_str(ddata, "operator<", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('m', 'i'): + /* operator - */ + if (!cpp_demangle_push_str(ddata, "operator-", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('m', 'I'): + /* operator -= */ + if (!cpp_demangle_push_str(ddata, "operator-=", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('m', 'l'): + /* operator * */ + if (!cpp_demangle_push_str(ddata, "operator*", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('m', 'L'): + /* operator *= */ + if (!cpp_demangle_push_str(ddata, "operator*=", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('m', 'm'): + /* operator -- */ + if (!cpp_demangle_push_str(ddata, "operator--", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('n', 'a'): + /* operator new[] */ + if (!cpp_demangle_push_str(ddata, "operator new []", 15)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('n', 'e'): + /* operator != */ + if (!cpp_demangle_push_str(ddata, "operator!=", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('n', 'g'): + /* operator - (unary) */ + if (!cpp_demangle_push_str(ddata, "operator-", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('n', 't'): + /* operator ! */ + if (!cpp_demangle_push_str(ddata, "operator!", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('n', 'w'): + /* operator new */ + if (!cpp_demangle_push_str(ddata, "operator new", 12)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('o', 'o'): + /* operator || */ + if (!cpp_demangle_push_str(ddata, "operator||", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('o', 'r'): + /* operator | */ + if (!cpp_demangle_push_str(ddata, "operator|", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('o', 'R'): + /* operator |= */ + if (!cpp_demangle_push_str(ddata, "operator|=", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('p', 'l'): + /* operator + */ + if (!cpp_demangle_push_str(ddata, "operator+", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('p', 'L'): + /* operator += */ + if (!cpp_demangle_push_str(ddata, "operator+=", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('p', 'm'): + /* operator ->* */ + if (!cpp_demangle_push_str(ddata, "operator->*", 11)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('p', 'p'): + /* operator ++ */ + if (!cpp_demangle_push_str(ddata, "operator++", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('p', 's'): + /* operator + (unary) */ + if (!cpp_demangle_push_str(ddata, "operator+", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('p', 't'): + /* operator -> */ + if (!cpp_demangle_push_str(ddata, "operator->", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('q', 'u'): + /* operator ? */ + if (!cpp_demangle_push_str(ddata, "operator?", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('r', 'm'): + /* operator % */ + if (!cpp_demangle_push_str(ddata, "operator%", 9)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('r', 'M'): + /* operator %= */ + if (!cpp_demangle_push_str(ddata, "operator%=", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('r', 's'): + /* operator >> */ + if (!cpp_demangle_push_str(ddata, "operator>>", 10)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('r', 'S'): + /* operator >>= */ + if (!cpp_demangle_push_str(ddata, "operator>>=", 11)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('r', 'z'): + /* operator sizeof */ + if (!cpp_demangle_push_str(ddata, "operator sizeof ", 16)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('s', 'r'): + /* scope resolution operator */ + if (!cpp_demangle_push_str(ddata, "scope resolution operator ", + 26)) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('s', 'v'): + /* operator sizeof */ + if (!cpp_demangle_push_str(ddata, "operator sizeof ", 16)) + return (0); + ddata->cur += 2; + return (1); + }; + + /* vendor extened operator */ + if (*ddata->cur == 'v' && ELFTC_ISDIGIT(*(ddata->cur + 1))) { + if (!cpp_demangle_push_str(ddata, "vendor extened operator ", + 24)) + return (0); + if (!cpp_demangle_push_str(ddata, ddata->cur + 1, 1)) + return (0); + ddata->cur += 2; + return (cpp_demangle_read_sname(ddata)); + } + + /* ctor-dtor-name */ + switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { + case SIMPLE_HASH('C', '1'): + /* FALLTHROUGH */ + case SIMPLE_HASH('C', '2'): + /* FALLTHROUGH */ + case SIMPLE_HASH('C', '3'): + if (ddata->last_sname == NULL) + return (0); + if ((len = strlen(ddata->last_sname)) == 0) + return (0); + if (!cpp_demangle_push_str(ddata, "::", 2)) + return (0); + if (!cpp_demangle_push_str(ddata, ddata->last_sname, len)) + return (0); + ddata->cur +=2; + return (1); + + case SIMPLE_HASH('D', '0'): + /* FALLTHROUGH */ + case SIMPLE_HASH('D', '1'): + /* FALLTHROUGH */ + case SIMPLE_HASH('D', '2'): + if (ddata->last_sname == NULL) + return (0); + if ((len = strlen(ddata->last_sname)) == 0) + return (0); + if (!cpp_demangle_push_str(ddata, "::~", 3)) + return (0); + if (!cpp_demangle_push_str(ddata, ddata->last_sname, len)) + return (0); + ddata->cur +=2; + return (1); + }; + + /* source name */ + if (ELFTC_ISDIGIT(*ddata->cur) != 0) + return (cpp_demangle_read_sname(ddata)); + + /* local source name */ + if (*ddata->cur == 'L') + return (cpp_demangle_local_source_name(ddata)); + + return (1); +} + +/* + * Read local source name. + * + * References: + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 + * http://gcc.gnu.org/viewcvs?view=rev&revision=124467 + */ +static int +cpp_demangle_local_source_name(struct cpp_demangle_data *ddata) +{ + /* L */ + if (ddata == NULL || *ddata->cur != 'L') + return (0); + ++ddata->cur; + + /* source name */ + if (!cpp_demangle_read_sname(ddata)) + return (0); + + /* discriminator */ + if (*ddata->cur == '_') { + ++ddata->cur; + while (ELFTC_ISDIGIT(*ddata->cur) != 0) + ++ddata->cur; + } + + return (1); +} + +static int +cpp_demangle_read_v_offset(struct cpp_demangle_data *ddata) +{ + + if (ddata == NULL) + return (0); + + if (!cpp_demangle_push_str(ddata, "offset : ", 9)) + return (0); + + if (!cpp_demangle_read_offset_number(ddata)) + return (0); + + if (!cpp_demangle_push_str(ddata, "virtual offset : ", 17)) + return (0); + + return (!cpp_demangle_read_offset_number(ddata)); +} + +/* + * Decode floating point representation to string + * Return new allocated string or NULL + * + * Todo + * Replace these functions to macro. + */ +static char * +decode_fp_to_double(const char *p, size_t len) +{ + double f; + size_t rtn_len, limit, i; + int byte; + char *rtn; + + if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(double)) + return (NULL); + + memset(&f, 0, sizeof(double)); + + for (i = 0; i < len / 2; ++i) { + byte = hex_to_dec(p[len - i * 2 - 1]) + + hex_to_dec(p[len - i * 2 - 2]) * 16; + + if (byte < 0 || byte > 255) + return (NULL); + +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN + ((unsigned char *)&f)[i] = (unsigned char)(byte); +#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + ((unsigned char *)&f)[sizeof(double) - i - 1] = + (unsigned char)(byte); +#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + } + + rtn_len = 64; + limit = 0; +again: + if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) + return (NULL); + + if (snprintf(rtn, rtn_len, "%fld", f) >= (int)rtn_len) { + free(rtn); + if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) + return (NULL); + rtn_len *= BUFFER_GROWFACTOR; + goto again; + } + + return rtn; +} + +static char * +decode_fp_to_float(const char *p, size_t len) +{ + size_t i, rtn_len, limit; + float f; + int byte; + char *rtn; + + if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(float)) + return (NULL); + + memset(&f, 0, sizeof(float)); + + for (i = 0; i < len / 2; ++i) { + byte = hex_to_dec(p[len - i * 2 - 1]) + + hex_to_dec(p[len - i * 2 - 2]) * 16; + if (byte < 0 || byte > 255) + return (NULL); +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN + ((unsigned char *)&f)[i] = (unsigned char)(byte); +#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + ((unsigned char *)&f)[sizeof(float) - i - 1] = + (unsigned char)(byte); +#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + } + + rtn_len = 64; + limit = 0; +again: + if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) + return (NULL); + + if (snprintf(rtn, rtn_len, "%ff", f) >= (int)rtn_len) { + free(rtn); + if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) + return (NULL); + rtn_len *= BUFFER_GROWFACTOR; + goto again; + } + + return rtn; +} + +static char * +decode_fp_to_float128(const char *p, size_t len) +{ + long double f; + size_t rtn_len, limit, i; + int byte; + unsigned char buf[FLOAT_QUADRUPLE_BYTES]; + char *rtn; + + switch(sizeof(long double)) { + case FLOAT_QUADRUPLE_BYTES: + return (decode_fp_to_long_double(p, len)); + case FLOAT_EXTENED_BYTES: + if (p == NULL || len == 0 || len % 2 != 0 || + len / 2 > FLOAT_QUADRUPLE_BYTES) + return (NULL); + + memset(buf, 0, FLOAT_QUADRUPLE_BYTES); + + for (i = 0; i < len / 2; ++i) { + byte = hex_to_dec(p[len - i * 2 - 1]) + + hex_to_dec(p[len - i * 2 - 2]) * 16; + if (byte < 0 || byte > 255) + return (NULL); +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN + buf[i] = (unsigned char)(byte); +#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + buf[FLOAT_QUADRUPLE_BYTES - i -1] = + (unsigned char)(byte); +#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + } + memset(&f, 0, FLOAT_EXTENED_BYTES); + +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN + memcpy(&f, buf, FLOAT_EXTENED_BYTES); +#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + memcpy(&f, buf + 6, FLOAT_EXTENED_BYTES); +#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + + rtn_len = 256; + limit = 0; +again: + if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) + return (NULL); + + if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { + free(rtn); + if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) + return (NULL); + rtn_len *= BUFFER_GROWFACTOR; + goto again; + } + + return (rtn); + default: + return (NULL); + } +} + +static char * +decode_fp_to_float80(const char *p, size_t len) +{ + long double f; + size_t rtn_len, limit, i; + int byte; + unsigned char buf[FLOAT_EXTENED_BYTES]; + char *rtn; + + switch(sizeof(long double)) { + case FLOAT_QUADRUPLE_BYTES: + if (p == NULL || len == 0 || len % 2 != 0 || + len / 2 > FLOAT_EXTENED_BYTES) + return (NULL); + + memset(buf, 0, FLOAT_EXTENED_BYTES); + + for (i = 0; i < len / 2; ++i) { + byte = hex_to_dec(p[len - i * 2 - 1]) + + hex_to_dec(p[len - i * 2 - 2]) * 16; + + if (byte < 0 || byte > 255) + return (NULL); + +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN + buf[i] = (unsigned char)(byte); +#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + buf[FLOAT_EXTENED_BYTES - i -1] = + (unsigned char)(byte); +#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + } + + memset(&f, 0, FLOAT_QUADRUPLE_BYTES); + +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN + memcpy(&f, buf, FLOAT_EXTENED_BYTES); +#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + memcpy((unsigned char *)(&f) + 6, buf, FLOAT_EXTENED_BYTES); +#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + + rtn_len = 256; + limit = 0; +again: + if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) + return (NULL); + + if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { + free(rtn); + if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) + return (NULL); + rtn_len *= BUFFER_GROWFACTOR; + goto again; + } + + return (rtn); + case FLOAT_EXTENED_BYTES: + return (decode_fp_to_long_double(p, len)); + default: + return (NULL); + } +} + +static char * +decode_fp_to_long_double(const char *p, size_t len) +{ + long double f; + size_t rtn_len, limit, i; + int byte; + char *rtn; + + if (p == NULL || len == 0 || len % 2 != 0 || + len / 2 > sizeof(long double)) + return (NULL); + + memset(&f, 0, sizeof(long double)); + + for (i = 0; i < len / 2; ++i) { + byte = hex_to_dec(p[len - i * 2 - 1]) + + hex_to_dec(p[len - i * 2 - 2]) * 16; + + if (byte < 0 || byte > 255) + return (NULL); + +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN + ((unsigned char *)&f)[i] = (unsigned char)(byte); +#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + ((unsigned char *)&f)[sizeof(long double) - i - 1] = + (unsigned char)(byte); +#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + } + + rtn_len = 256; + limit = 0; +again: + if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) + return (NULL); + + if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { + free(rtn); + if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) + return (NULL); + rtn_len *= BUFFER_GROWFACTOR; + goto again; + } + + return (rtn); +} + +/* Simple hex to integer function used by decode_to_* function. */ +static int +hex_to_dec(char c) +{ + + switch (c) { + case '0': + return (0); + case '1': + return (1); + case '2': + return (2); + case '3': + return (3); + case '4': + return (4); + case '5': + return (5); + case '6': + return (6); + case '7': + return (7); + case '8': + return (8); + case '9': + return (9); + case 'a': + return (10); + case 'b': + return (11); + case 'c': + return (12); + case 'd': + return (13); + case 'e': + return (14); + case 'f': + return (15); + default: + return (-1); + }; +} + +static void +vector_read_cmd_dest(struct vector_read_cmd *v) +{ + + if (v == NULL) + return; + + free(v->r_container); +} + +/* return -1 at failed, 0 at not found, 1 at found. */ +static int +vector_read_cmd_find(struct vector_read_cmd *v, enum read_cmd dst) +{ + size_t i; + + if (v == NULL || dst == READ_FAIL) + return (-1); + + for (i = 0; i < v->size; ++i) + if (v->r_container[i] == dst) + return (1); + + return (0); +} + +static int +vector_read_cmd_init(struct vector_read_cmd *v) +{ + + if (v == NULL) + return (0); + + v->size = 0; + v->capacity = VECTOR_DEF_CAPACITY; + + if ((v->r_container = malloc(sizeof(enum read_cmd) * v->capacity)) + == NULL) + return (0); + + return (1); +} + +static int +vector_read_cmd_pop(struct vector_read_cmd *v) +{ + + if (v == NULL || v->size == 0) + return (0); + + --v->size; + v->r_container[v->size] = READ_FAIL; + + return (1); +} + +static int +vector_read_cmd_push(struct vector_read_cmd *v, enum read_cmd cmd) +{ + enum read_cmd *tmp_r_ctn; + size_t tmp_cap; + size_t i; + + if (v == NULL) + return (0); + + if (v->size == v->capacity) { + tmp_cap = v->capacity * BUFFER_GROWFACTOR; + if ((tmp_r_ctn = malloc(sizeof(enum read_cmd) * tmp_cap)) + == NULL) + return (0); + for (i = 0; i < v->size; ++i) + tmp_r_ctn[i] = v->r_container[i]; + free(v->r_container); + v->r_container = tmp_r_ctn; + v->capacity = tmp_cap; + } + + v->r_container[v->size] = cmd; + ++v->size; + + return (1); +} + +static void +vector_type_qualifier_dest(struct vector_type_qualifier *v) +{ + + if (v == NULL) + return; + + free(v->q_container); + vector_str_dest(&v->ext_name); +} + +/* size, capacity, ext_name */ +static int +vector_type_qualifier_init(struct vector_type_qualifier *v) +{ + + if (v == NULL) + return (0); + + v->size = 0; + v->capacity = VECTOR_DEF_CAPACITY; + + if ((v->q_container = malloc(sizeof(enum type_qualifier) * v->capacity)) + == NULL) + return (0); + + assert(v->q_container != NULL); + + if (vector_str_init(&v->ext_name) == false) { + free(v->q_container); + return (0); + } + + return (1); +} + +static int +vector_type_qualifier_push(struct vector_type_qualifier *v, + enum type_qualifier t) +{ + enum type_qualifier *tmp_ctn; + size_t tmp_cap; + size_t i; + + if (v == NULL) + return (0); + + if (v->size == v->capacity) { + tmp_cap = v->capacity * BUFFER_GROWFACTOR; + if ((tmp_ctn = malloc(sizeof(enum type_qualifier) * tmp_cap)) + == NULL) + return (0); + for (i = 0; i < v->size; ++i) + tmp_ctn[i] = v->q_container[i]; + free(v->q_container); + v->q_container = tmp_ctn; + v->capacity = tmp_cap; + } + + v->q_container[v->size] = t; + ++v->size; + + return (1); +} diff --git a/src/libs/libcxxrt/memory.cc b/src/libs/libcxxrt/memory.cc new file mode 100644 index 0000000000..c8d28fc87e --- /dev/null +++ b/src/libs/libcxxrt/memory.cc @@ -0,0 +1,154 @@ +/* + * Copyright 2010-2011 PathScale, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * memory.cc - Contains stub definition of C++ new/delete operators. + * + * These definitions are intended to be used for testing and are weak symbols + * to allow them to be replaced by definitions from a STL implementation. + * These versions simply wrap malloc() and free(), they do not provide a + * C++-specific allocator. + */ + +#include +#include +#include "stdexcept.h" +#include "atomic.h" + + +namespace std +{ + struct nothrow_t {}; +} + + +/// The type of the function called when allocation fails. +typedef void (*new_handler)(); +/** + * The function to call when allocation fails. By default, there is no + * handler and a bad allocation exception is thrown if an allocation fails. + */ +static new_handler new_handl; + +namespace std +{ + /** + * Sets a function to be called when there is a failure in new. + */ + __attribute__((weak)) + new_handler set_new_handler(new_handler handler) + { + return ATOMIC_SWAP(&new_handl, handler); + } + __attribute__((weak)) + new_handler get_new_handler(void) + { + return ATOMIC_LOAD(&new_handl); + } +} + + +__attribute__((weak)) +void* operator new(size_t size) +{ + if (0 == size) + { + size = 1; + } + void * mem = malloc(size); + while (0 == mem) + { + new_handler h = std::get_new_handler(); + if (0 != h) + { + h(); + } + else + { + throw std::bad_alloc(); + } + mem = malloc(size); + } + + return mem; +} + +__attribute__((weak)) +void* operator new(size_t size, const std::nothrow_t &) throw() +{ + try { + return :: operator new(size); + } catch (...) { + // nothrow operator new should return NULL in case of + // std::bad_alloc exception in new handler + return NULL; + } +} + + +__attribute__((weak)) +void operator delete(void * ptr) +#if __cplusplus < 201000L +throw() +#endif +{ + free(ptr); +} + + +__attribute__((weak)) +void * operator new[](size_t size) +#if __cplusplus < 201000L +throw(std::bad_alloc) +#endif +{ + return ::operator new(size); +} + + +__attribute__((weak)) +void * operator new[](size_t size, const std::nothrow_t &) throw() +{ + try { + return ::operator new[](size); + } catch (...) { + // nothrow operator new should return NULL in case of + // std::bad_alloc exception in new handler + return NULL; + } +} + + +__attribute__((weak)) +void operator delete[](void * ptr) +#if __cplusplus < 201000L +throw() +#endif +{ + ::operator delete(ptr); +} + + diff --git a/src/libs/libcxxrt/stdexcept.cc b/src/libs/libcxxrt/stdexcept.cc new file mode 100644 index 0000000000..c1cea39f6a --- /dev/null +++ b/src/libs/libcxxrt/stdexcept.cc @@ -0,0 +1,99 @@ +/* + * Copyright 2010-2011 PathScale, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * stdexcept.cc - provides stub implementations of the exceptions required by the runtime. + */ +#include "stdexcept.h" + +namespace std { + +exception::exception() throw() {} +exception::~exception() {} +exception::exception(const exception&) throw() {} +exception& exception::operator=(const exception&) throw() +{ + return *this; +} +const char* exception::what() const throw() +{ + return "std::exception"; +} + +bad_alloc::bad_alloc() throw() {} +bad_alloc::~bad_alloc() {} +bad_alloc::bad_alloc(const bad_alloc&) throw() {} +bad_alloc& bad_alloc::operator=(const bad_alloc&) throw() +{ + return *this; +} +const char* bad_alloc::what() const throw() +{ + return "cxxrt::bad_alloc"; +} + + + +bad_cast::bad_cast() throw() {} +bad_cast::~bad_cast() {} +bad_cast::bad_cast(const bad_cast&) throw() {} +bad_cast& bad_cast::operator=(const bad_cast&) throw() +{ + return *this; +} +const char* bad_cast::what() const throw() +{ + return "std::bad_cast"; +} + +bad_typeid::bad_typeid() throw() {} +bad_typeid::~bad_typeid() {} +bad_typeid::bad_typeid(const bad_typeid &__rhs) throw() {} +bad_typeid& bad_typeid::operator=(const bad_typeid &__rhs) throw() +{ + return *this; +} + +const char* bad_typeid::what() const throw() +{ + return "std::bad_typeid"; +} + +bad_array_new_length::bad_array_new_length() throw() {} +bad_array_new_length::~bad_array_new_length() {} +bad_array_new_length::bad_array_new_length(const bad_array_new_length&) throw() {} +bad_array_new_length& bad_array_new_length::operator=(const bad_array_new_length&) throw() +{ + return *this; +} + +const char* bad_array_new_length::what() const throw() +{ + return "std::bad_array_new_length"; +} + +} // namespace std + diff --git a/src/libs/libcxxrt/terminate.cc b/src/libs/libcxxrt/terminate.cc new file mode 100644 index 0000000000..b7f50b474d --- /dev/null +++ b/src/libs/libcxxrt/terminate.cc @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2011 PathScale, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +namespace std +{ + /** + * Stub implementation of std::terminate. Used when the STL implementation + * doesn't provide one. + */ + __attribute__((weak)) + void terminate() + { + abort(); + } +} diff --git a/src/libs/libcxxrt/typeinfo.cc b/src/libs/libcxxrt/typeinfo.cc new file mode 100644 index 0000000000..71de9ae59b --- /dev/null +++ b/src/libs/libcxxrt/typeinfo.cc @@ -0,0 +1,132 @@ +/* + * Copyright 2010-2012 PathScale, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "typeinfo.h" +#include +#include +#include + +using std::type_info; + +type_info::~type_info() {} + +bool type_info::operator==(const type_info &other) const +{ + return __type_name == other.__type_name; +} +bool type_info::operator!=(const type_info &other) const +{ + return __type_name != other.__type_name; +} +bool type_info::before(const type_info &other) const +{ + return __type_name < other.__type_name; +} +const char* type_info::name() const +{ + return __type_name; +} +type_info::type_info (const type_info& rhs) +{ + __type_name = rhs.__type_name; +} +type_info& type_info::operator= (const type_info& rhs) +{ + return *new type_info(rhs); +} + +ABI_NAMESPACE::__fundamental_type_info::~__fundamental_type_info() {} +ABI_NAMESPACE::__array_type_info::~__array_type_info() {} +ABI_NAMESPACE::__function_type_info::~__function_type_info() {} +ABI_NAMESPACE::__enum_type_info::~__enum_type_info() {} +ABI_NAMESPACE::__class_type_info::~__class_type_info() {} +ABI_NAMESPACE::__si_class_type_info::~__si_class_type_info() {} +ABI_NAMESPACE::__vmi_class_type_info::~__vmi_class_type_info() {} +ABI_NAMESPACE::__pbase_type_info::~__pbase_type_info() {} +ABI_NAMESPACE::__pointer_type_info::~__pointer_type_info() {} +ABI_NAMESPACE::__pointer_to_member_type_info::~__pointer_to_member_type_info() {} + +// From libelftc +extern "C" char *__cxa_demangle_gnu3(const char *); + +extern "C" char* __cxa_demangle(const char* mangled_name, + char* buf, + size_t* n, + int* status) +{ + // TODO: We should probably just be linking against libelf-tc, rather than + // copying their code. This requires them to do an actual release, + // however, and for our changes to be pushed upstream. We also need to + // call a different demangling function here depending on the ABI (e.g. + // ARM). + char *demangled = __cxa_demangle_gnu3(mangled_name); + if (NULL != demangled) + { + size_t len = strlen(demangled); + if (buf == NULL) + { + if (n) + { + *n = len; + } + return demangled; + } + if (*n < len+1) + { + buf = static_cast(realloc(buf, len+1)); + } + if (0 != buf) + { + memcpy(buf, demangled, len); + buf[len] = 0; + if (n) + { + *n = len; + } + if (status) + { + *status = 0; + } + } + else + { + if (status) + { + *status = -1; + } + } + free(demangled); + } + else + { + if (status) + { + *status = -2; + } + return NULL; + } + return buf; +} From 18941b085c78fd93a10dea29a95ec0eb1c1ff225 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sun, 8 Nov 2015 20:48:19 +0100 Subject: [PATCH 153/370] Import libc++ --- headers/libs/libc++/CMakeLists.txt | 52 + headers/libs/libc++/__bit_reference | 1286 ++++ headers/libs/libc++/__config | 825 ++ headers/libs/libc++/__config_site.in | 22 + headers/libs/libc++/__debug | 222 + headers/libs/libc++/__functional_03 | 1576 ++++ headers/libs/libc++/__functional_base | 793 ++ headers/libs/libc++/__functional_base_03 | 224 + headers/libs/libc++/__hash_table | 2461 ++++++ headers/libs/libc++/__locale | 1475 ++++ headers/libs/libc++/__mutex_base | 410 + headers/libs/libc++/__nullptr | 66 + headers/libs/libc++/__refstring | 139 + headers/libs/libc++/__split_buffer | 640 ++ headers/libs/libc++/__sso_allocator | 79 + headers/libs/libc++/__std_stream | 358 + headers/libs/libc++/__tree | 2297 ++++++ headers/libs/libc++/__tuple | 348 + headers/libs/libc++/__undef___deallocate | 18 + headers/libs/libc++/__undef_min_max | 29 + headers/libs/libc++/algorithm | 5777 ++++++++++++++ headers/libs/libc++/array | 331 + headers/libs/libc++/atomic | 1799 +++++ headers/libs/libc++/atomic_support.h | 149 + headers/libs/libc++/bitset | 1122 +++ headers/libs/libc++/cassert | 25 + headers/libs/libc++/ccomplex | 29 + headers/libs/libc++/cctype | 64 + headers/libs/libc++/cerrno | 33 + headers/libs/libc++/cfenv | 82 + headers/libs/libc++/cfloat | 70 + headers/libs/libc++/chrono | 1154 +++ headers/libs/libc++/cinttypes | 258 + headers/libs/libc++/ciso646 | 25 + headers/libs/libc++/climits | 48 + headers/libs/libc++/clocale | 55 + headers/libs/libc++/cmath | 553 ++ headers/libs/libc++/codecvt | 550 ++ headers/libs/libc++/complex | 1567 ++++ headers/libs/libc++/complex.h | 37 + headers/libs/libc++/condition_variable | 267 + headers/libs/libc++/config_elast.h | 36 + headers/libs/libc++/csetjmp | 48 + headers/libs/libc++/csignal | 58 + headers/libs/libc++/cstdarg | 48 + headers/libs/libc++/cstdbool | 32 + headers/libs/libc++/cstddef | 60 + headers/libs/libc++/cstdint | 191 + headers/libs/libc++/cstdio | 174 + headers/libs/libc++/cstdlib | 158 + headers/libs/libc++/cstring | 114 + headers/libs/libc++/ctgmath | 29 + headers/libs/libc++/ctime | 74 + headers/libs/libc++/ctype.h | 69 + headers/libs/libc++/cwchar | 218 + headers/libs/libc++/cwctype | 87 + headers/libs/libc++/deque | 2906 +++++++ headers/libs/libc++/errno.h | 398 + headers/libs/libc++/exception | 254 + headers/libs/libc++/experimental/__config | 32 + headers/libs/libc++/experimental/algorithm | 120 + headers/libs/libc++/experimental/any | 590 ++ headers/libs/libc++/experimental/chrono | 59 + headers/libs/libc++/experimental/dynarray | 316 + headers/libs/libc++/experimental/functional | 454 ++ headers/libs/libc++/experimental/optional | 894 +++ headers/libs/libc++/experimental/ratio | 77 + headers/libs/libc++/experimental/string_view | 812 ++ headers/libs/libc++/experimental/system_error | 63 + headers/libs/libc++/experimental/tuple | 81 + headers/libs/libc++/experimental/type_traits | 427 ++ headers/libs/libc++/experimental/utility | 47 + headers/libs/libc++/ext/__hash | 135 + headers/libs/libc++/ext/hash_map | 994 +++ headers/libs/libc++/ext/hash_set | 661 ++ headers/libs/libc++/float.h | 83 + headers/libs/libc++/forward_list | 1649 ++++ headers/libs/libc++/fstream | 1457 ++++ headers/libs/libc++/functional | 2578 +++++++ headers/libs/libc++/future | 2604 +++++++ headers/libs/libc++/initializer_list | 118 + headers/libs/libc++/inttypes.h | 251 + headers/libs/libc++/iomanip | 654 ++ headers/libs/libc++/ios | 1028 +++ headers/libs/libc++/iosfwd | 199 + headers/libs/libc++/iostream | 64 + headers/libs/libc++/istream | 1733 +++++ headers/libs/libc++/iterator | 1614 ++++ headers/libs/libc++/limits | 813 ++ headers/libs/libc++/list | 2329 ++++++ headers/libs/libc++/locale | 4469 +++++++++++ headers/libs/libc++/map | 2230 ++++++ headers/libs/libc++/math.h | 1419 ++++ headers/libs/libc++/memory | 5637 ++++++++++++++ headers/libs/libc++/module.modulemap | 477 ++ headers/libs/libc++/mutex | 584 ++ headers/libs/libc++/new | 182 + headers/libs/libc++/numeric | 197 + headers/libs/libc++/ostream | 1113 +++ headers/libs/libc++/queue | 717 ++ headers/libs/libc++/random | 6724 +++++++++++++++++ headers/libs/libc++/ratio | 490 ++ headers/libs/libc++/regex | 6513 ++++++++++++++++ headers/libs/libc++/scoped_allocator | 604 ++ headers/libs/libc++/set | 1219 +++ headers/libs/libc++/setjmp.h | 45 + headers/libs/libc++/shared_mutex | 501 ++ headers/libs/libc++/sstream | 977 +++ headers/libs/libc++/stack | 292 + headers/libs/libc++/stddef.h | 62 + headers/libs/libc++/stdexcept | 170 + headers/libs/libc++/stdio.h | 127 + headers/libs/libc++/stdlib.h | 130 + headers/libs/libc++/streambuf | 575 ++ headers/libs/libc++/string | 4295 +++++++++++ headers/libs/libc++/strstream | 400 + .../libc++/support/android/locale_bionic.h | 31 + headers/libs/libc++/support/ibm/limits.h | 99 + headers/libs/libc++/support/ibm/support.h | 54 + headers/libs/libc++/support/ibm/xlocale.h | 326 + headers/libs/libc++/support/newlib/xlocale.h | 63 + .../libc++/support/solaris/floatingpoint.h | 14 + headers/libs/libc++/support/solaris/wchar.h | 47 + headers/libs/libc++/support/solaris/xlocale.h | 67 + .../libs/libc++/support/win32/limits_win32.h | 79 + .../libs/libc++/support/win32/locale_win32.h | 129 + .../libs/libc++/support/win32/math_win32.h | 117 + headers/libs/libc++/support/win32/support.h | 206 + headers/libs/libc++/support/xlocale/xlocale.h | 194 + headers/libs/libc++/system_error | 642 ++ headers/libs/libc++/tgmath.h | 29 + headers/libs/libc++/thread | 475 ++ headers/libs/libc++/tuple | 1135 +++ headers/libs/libc++/type_traits | 4259 +++++++++++ headers/libs/libc++/typeindex | 103 + headers/libs/libc++/typeinfo | 168 + headers/libs/libc++/unordered_map | 2251 ++++++ headers/libs/libc++/unordered_set | 1379 ++++ headers/libs/libc++/utility | 756 ++ headers/libs/libc++/valarray | 4881 ++++++++++++ headers/libs/libc++/vector | 3315 ++++++++ headers/libs/libc++/wchar.h | 136 + headers/libs/libc++/wctype.h | 79 + src/libs/libc++/.arcconfig | 4 + src/libs/libc++/CREDITS.TXT | 138 + src/libs/libc++/LICENSE.TXT | 76 + src/libs/libc++/TODO.TXT | 56 + src/libs/libc++/algorithm.cpp | 91 + src/libs/libc++/any.cpp | 18 + src/libs/libc++/bind.cpp | 30 + src/libs/libc++/chrono.cpp | 149 + src/libs/libc++/condition_variable.cpp | 87 + src/libs/libc++/debug.cpp | 570 ++ src/libs/libc++/exception.cpp | 309 + src/libs/libc++/future.cpp | 301 + src/libs/libc++/hash.cpp | 570 ++ src/libs/libc++/ios.cpp | 466 ++ src/libs/libc++/iostream.cpp | 88 + src/libs/libc++/locale.cpp | 6265 +++++++++++++++ src/libs/libc++/memory.cpp | 228 + src/libs/libc++/mutex.cpp | 284 + src/libs/libc++/new.cpp | 249 + src/libs/libc++/optional.cpp | 24 + src/libs/libc++/random.cpp | 152 + src/libs/libc++/regex.cpp | 333 + src/libs/libc++/shared_mutex.cpp | 117 + src/libs/libc++/stdexcept.cpp | 102 + src/libs/libc++/string.cpp | 528 ++ src/libs/libc++/strstream.cpp | 329 + src/libs/libc++/system_error.cpp | 209 + src/libs/libc++/thread.cpp | 232 + src/libs/libc++/typeinfo.cpp | 68 + src/libs/libc++/utility.cpp | 17 + src/libs/libc++/valarray.cpp | 54 + 174 files changed, 128532 insertions(+) create mode 100644 headers/libs/libc++/CMakeLists.txt create mode 100644 headers/libs/libc++/__bit_reference create mode 100644 headers/libs/libc++/__config create mode 100644 headers/libs/libc++/__config_site.in create mode 100644 headers/libs/libc++/__debug create mode 100644 headers/libs/libc++/__functional_03 create mode 100644 headers/libs/libc++/__functional_base create mode 100644 headers/libs/libc++/__functional_base_03 create mode 100644 headers/libs/libc++/__hash_table create mode 100644 headers/libs/libc++/__locale create mode 100644 headers/libs/libc++/__mutex_base create mode 100644 headers/libs/libc++/__nullptr create mode 100644 headers/libs/libc++/__refstring create mode 100644 headers/libs/libc++/__split_buffer create mode 100644 headers/libs/libc++/__sso_allocator create mode 100644 headers/libs/libc++/__std_stream create mode 100644 headers/libs/libc++/__tree create mode 100644 headers/libs/libc++/__tuple create mode 100644 headers/libs/libc++/__undef___deallocate create mode 100644 headers/libs/libc++/__undef_min_max create mode 100644 headers/libs/libc++/algorithm create mode 100644 headers/libs/libc++/array create mode 100644 headers/libs/libc++/atomic create mode 100644 headers/libs/libc++/atomic_support.h create mode 100644 headers/libs/libc++/bitset create mode 100644 headers/libs/libc++/cassert create mode 100644 headers/libs/libc++/ccomplex create mode 100644 headers/libs/libc++/cctype create mode 100644 headers/libs/libc++/cerrno create mode 100644 headers/libs/libc++/cfenv create mode 100644 headers/libs/libc++/cfloat create mode 100644 headers/libs/libc++/chrono create mode 100644 headers/libs/libc++/cinttypes create mode 100644 headers/libs/libc++/ciso646 create mode 100644 headers/libs/libc++/climits create mode 100644 headers/libs/libc++/clocale create mode 100644 headers/libs/libc++/cmath create mode 100644 headers/libs/libc++/codecvt create mode 100644 headers/libs/libc++/complex create mode 100644 headers/libs/libc++/complex.h create mode 100644 headers/libs/libc++/condition_variable create mode 100644 headers/libs/libc++/config_elast.h create mode 100644 headers/libs/libc++/csetjmp create mode 100644 headers/libs/libc++/csignal create mode 100644 headers/libs/libc++/cstdarg create mode 100644 headers/libs/libc++/cstdbool create mode 100644 headers/libs/libc++/cstddef create mode 100644 headers/libs/libc++/cstdint create mode 100644 headers/libs/libc++/cstdio create mode 100644 headers/libs/libc++/cstdlib create mode 100644 headers/libs/libc++/cstring create mode 100644 headers/libs/libc++/ctgmath create mode 100644 headers/libs/libc++/ctime create mode 100644 headers/libs/libc++/ctype.h create mode 100644 headers/libs/libc++/cwchar create mode 100644 headers/libs/libc++/cwctype create mode 100644 headers/libs/libc++/deque create mode 100644 headers/libs/libc++/errno.h create mode 100644 headers/libs/libc++/exception create mode 100644 headers/libs/libc++/experimental/__config create mode 100644 headers/libs/libc++/experimental/algorithm create mode 100644 headers/libs/libc++/experimental/any create mode 100644 headers/libs/libc++/experimental/chrono create mode 100644 headers/libs/libc++/experimental/dynarray create mode 100644 headers/libs/libc++/experimental/functional create mode 100644 headers/libs/libc++/experimental/optional create mode 100644 headers/libs/libc++/experimental/ratio create mode 100644 headers/libs/libc++/experimental/string_view create mode 100644 headers/libs/libc++/experimental/system_error create mode 100644 headers/libs/libc++/experimental/tuple create mode 100644 headers/libs/libc++/experimental/type_traits create mode 100644 headers/libs/libc++/experimental/utility create mode 100644 headers/libs/libc++/ext/__hash create mode 100644 headers/libs/libc++/ext/hash_map create mode 100644 headers/libs/libc++/ext/hash_set create mode 100644 headers/libs/libc++/float.h create mode 100644 headers/libs/libc++/forward_list create mode 100644 headers/libs/libc++/fstream create mode 100644 headers/libs/libc++/functional create mode 100644 headers/libs/libc++/future create mode 100644 headers/libs/libc++/initializer_list create mode 100644 headers/libs/libc++/inttypes.h create mode 100644 headers/libs/libc++/iomanip create mode 100644 headers/libs/libc++/ios create mode 100644 headers/libs/libc++/iosfwd create mode 100644 headers/libs/libc++/iostream create mode 100644 headers/libs/libc++/istream create mode 100644 headers/libs/libc++/iterator create mode 100644 headers/libs/libc++/limits create mode 100644 headers/libs/libc++/list create mode 100644 headers/libs/libc++/locale create mode 100644 headers/libs/libc++/map create mode 100644 headers/libs/libc++/math.h create mode 100644 headers/libs/libc++/memory create mode 100644 headers/libs/libc++/module.modulemap create mode 100644 headers/libs/libc++/mutex create mode 100644 headers/libs/libc++/new create mode 100644 headers/libs/libc++/numeric create mode 100644 headers/libs/libc++/ostream create mode 100644 headers/libs/libc++/queue create mode 100644 headers/libs/libc++/random create mode 100644 headers/libs/libc++/ratio create mode 100644 headers/libs/libc++/regex create mode 100644 headers/libs/libc++/scoped_allocator create mode 100644 headers/libs/libc++/set create mode 100644 headers/libs/libc++/setjmp.h create mode 100644 headers/libs/libc++/shared_mutex create mode 100644 headers/libs/libc++/sstream create mode 100644 headers/libs/libc++/stack create mode 100644 headers/libs/libc++/stddef.h create mode 100644 headers/libs/libc++/stdexcept create mode 100644 headers/libs/libc++/stdio.h create mode 100644 headers/libs/libc++/stdlib.h create mode 100644 headers/libs/libc++/streambuf create mode 100644 headers/libs/libc++/string create mode 100644 headers/libs/libc++/strstream create mode 100644 headers/libs/libc++/support/android/locale_bionic.h create mode 100644 headers/libs/libc++/support/ibm/limits.h create mode 100644 headers/libs/libc++/support/ibm/support.h create mode 100644 headers/libs/libc++/support/ibm/xlocale.h create mode 100644 headers/libs/libc++/support/newlib/xlocale.h create mode 100644 headers/libs/libc++/support/solaris/floatingpoint.h create mode 100644 headers/libs/libc++/support/solaris/wchar.h create mode 100644 headers/libs/libc++/support/solaris/xlocale.h create mode 100644 headers/libs/libc++/support/win32/limits_win32.h create mode 100644 headers/libs/libc++/support/win32/locale_win32.h create mode 100644 headers/libs/libc++/support/win32/math_win32.h create mode 100644 headers/libs/libc++/support/win32/support.h create mode 100644 headers/libs/libc++/support/xlocale/xlocale.h create mode 100644 headers/libs/libc++/system_error create mode 100644 headers/libs/libc++/tgmath.h create mode 100644 headers/libs/libc++/thread create mode 100644 headers/libs/libc++/tuple create mode 100644 headers/libs/libc++/type_traits create mode 100644 headers/libs/libc++/typeindex create mode 100644 headers/libs/libc++/typeinfo create mode 100644 headers/libs/libc++/unordered_map create mode 100644 headers/libs/libc++/unordered_set create mode 100644 headers/libs/libc++/utility create mode 100644 headers/libs/libc++/valarray create mode 100644 headers/libs/libc++/vector create mode 100644 headers/libs/libc++/wchar.h create mode 100644 headers/libs/libc++/wctype.h create mode 100644 src/libs/libc++/.arcconfig create mode 100644 src/libs/libc++/CREDITS.TXT create mode 100644 src/libs/libc++/LICENSE.TXT create mode 100644 src/libs/libc++/TODO.TXT create mode 100644 src/libs/libc++/algorithm.cpp create mode 100644 src/libs/libc++/any.cpp create mode 100644 src/libs/libc++/bind.cpp create mode 100644 src/libs/libc++/chrono.cpp create mode 100644 src/libs/libc++/condition_variable.cpp create mode 100644 src/libs/libc++/debug.cpp create mode 100644 src/libs/libc++/exception.cpp create mode 100644 src/libs/libc++/future.cpp create mode 100644 src/libs/libc++/hash.cpp create mode 100644 src/libs/libc++/ios.cpp create mode 100644 src/libs/libc++/iostream.cpp create mode 100644 src/libs/libc++/locale.cpp create mode 100644 src/libs/libc++/memory.cpp create mode 100644 src/libs/libc++/mutex.cpp create mode 100644 src/libs/libc++/new.cpp create mode 100644 src/libs/libc++/optional.cpp create mode 100644 src/libs/libc++/random.cpp create mode 100644 src/libs/libc++/regex.cpp create mode 100644 src/libs/libc++/shared_mutex.cpp create mode 100644 src/libs/libc++/stdexcept.cpp create mode 100644 src/libs/libc++/string.cpp create mode 100644 src/libs/libc++/strstream.cpp create mode 100644 src/libs/libc++/system_error.cpp create mode 100644 src/libs/libc++/thread.cpp create mode 100644 src/libs/libc++/typeinfo.cpp create mode 100644 src/libs/libc++/utility.cpp create mode 100644 src/libs/libc++/valarray.cpp diff --git a/headers/libs/libc++/CMakeLists.txt b/headers/libs/libc++/CMakeLists.txt new file mode 100644 index 0000000000..e16dc8b4de --- /dev/null +++ b/headers/libs/libc++/CMakeLists.txt @@ -0,0 +1,52 @@ +if (NOT LIBCXX_INSTALL_SUPPORT_HEADERS) + set(LIBCXX_SUPPORT_HEADER_PATTERN PATTERN "support" EXCLUDE) +endif() + +set(LIBCXX_HEADER_PATTERN + PATTERN "*" + PATTERN "CMakeLists.txt" EXCLUDE + PATTERN ".svn" EXCLUDE + PATTERN "__config_site.in" EXCLUDE + ${LIBCXX_SUPPORT_HEADER_PATTERN} + ) + +file(COPY . + DESTINATION "${CMAKE_BINARY_DIR}/include/c++/v1" + FILES_MATCHING + ${LIBCXX_HEADER_PATTERN} + ) + +if (LIBCXX_INSTALL_HEADERS) + install(DIRECTORY . + DESTINATION include/c++/v1 + COMPONENT libcxx + FILES_MATCHING + ${LIBCXX_HEADER_PATTERN} + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + ) + + if (LIBCXX_NEEDS_SITE_CONFIG) + set(UNIX_CAT cat) + if (WIN32) + set(UNIX_CAT type) + endif() + # Generate and install a custom __config header. The new header is created + # by prepending __config_site to the current __config header. + add_custom_command(OUTPUT ${LIBCXX_BINARY_DIR}/__generated_config + COMMAND ${CMAKE_COMMAND} -E copy ${LIBCXX_BINARY_DIR}/__config_site ${LIBCXX_BINARY_DIR}/__generated_config + COMMAND ${UNIX_CAT} ${LIBCXX_SOURCE_DIR}/include/__config >> ${LIBCXX_BINARY_DIR}/__generated_config + DEPENDS ${LIBCXX_SOURCE_DIR}/include/__config + ${LIBCXX_BINARY_DIR}/__config_site + ) + # Add a target that executes the generation commands. + add_custom_target(generate_config_header ALL + DEPENDS ${LIBCXX_BINARY_DIR}/__generated_config) + # Install the generated header as __config. + install(FILES ${LIBCXX_BINARY_DIR}/__generated_config + DESTINATION include/c++/v1 + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + RENAME __config + COMPONENT libcxx) + endif() + +endif() diff --git a/headers/libs/libc++/__bit_reference b/headers/libs/libc++/__bit_reference new file mode 100644 index 0000000000..5659ed0682 --- /dev/null +++ b/headers/libs/libc++/__bit_reference @@ -0,0 +1,1286 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_REFERENCE +#define _LIBCPP___BIT_REFERENCE + +#include <__config> +#include + +#include <__undef_min_max> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template class __bit_iterator; +template class __bit_const_reference; + +template +struct __has_storage_type +{ + static const bool value = false; +}; + +template ::value> +class __bit_reference +{ + typedef typename _Cp::__storage_type __storage_type; + typedef typename _Cp::__storage_pointer __storage_pointer; + + __storage_pointer __seg_; + __storage_type __mask_; + +#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC) + friend typename _Cp::__self; +#else + friend class _Cp::__self; +#endif + friend class __bit_const_reference<_Cp>; + friend class __bit_iterator<_Cp, false>; +public: + _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT + {return static_cast(*__seg_ & __mask_);} + _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT + {return !static_cast(*this);} + + _LIBCPP_INLINE_VISIBILITY + __bit_reference& operator=(bool __x) _NOEXCEPT + { + if (__x) + *__seg_ |= __mask_; + else + *__seg_ &= ~__mask_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT + {return operator=(static_cast(__x));} + + _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;} + _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, false> operator&() const _NOEXCEPT + {return __bit_iterator<_Cp, false>(__seg_, static_cast(__ctz(__mask_)));} +private: + _LIBCPP_INLINE_VISIBILITY + __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT + : __seg_(__s), __mask_(__m) {} +}; + +template +class __bit_reference<_Cp, false> +{ +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT +{ + bool __t = __x; + __x = __y; + __y = __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT +{ + bool __t = __x; + __x = __y; + __y = __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT +{ + bool __t = __x; + __x = __y; + __y = __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT +{ + bool __t = __x; + __x = __y; + __y = __t; +} + +template +class __bit_const_reference +{ + typedef typename _Cp::__storage_type __storage_type; + typedef typename _Cp::__const_storage_pointer __storage_pointer; + + __storage_pointer __seg_; + __storage_type __mask_; + +#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC) + friend typename _Cp::__self; +#else + friend class _Cp::__self; +#endif + friend class __bit_iterator<_Cp, true>; +public: + _LIBCPP_INLINE_VISIBILITY + __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT + : __seg_(__x.__seg_), __mask_(__x.__mask_) {} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT + {return static_cast(*__seg_ & __mask_);} + + _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, true> operator&() const _NOEXCEPT + {return __bit_iterator<_Cp, true>(__seg_, static_cast(__ctz(__mask_)));} +private: + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR + __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT + : __seg_(__s), __mask_(__m) {} + + __bit_const_reference& operator=(const __bit_const_reference& __x); +}; + +// find + +template +__bit_iterator<_Cp, _IsConst> +__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, _IsConst> _It; + typedef typename _It::__storage_type __storage_type; + static const unsigned __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = *__first.__seg_ & __m; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__ctz(__b))); + if (__n == __dn) + return __first + __n; + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + if (*__first.__seg_) + return _It(__first.__seg_, static_cast(_VSTD::__ctz(*__first.__seg_))); + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first.__seg_ & __m; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__ctz(__b))); + } + return _It(__first.__seg_, static_cast(__n)); +} + +template +__bit_iterator<_Cp, _IsConst> +__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, _IsConst> _It; + typedef typename _It::__storage_type __storage_type; + static const unsigned __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = ~*__first.__seg_ & __m; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__ctz(__b))); + if (__n == __dn) + return __first + __n; + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + { + __storage_type __b = ~*__first.__seg_; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__ctz(__b))); + } + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = ~*__first.__seg_ & __m; + if (__b) + return _It(__first.__seg_, static_cast(_VSTD::__ctz(__b))); + } + return _It(__first.__seg_, static_cast(__n)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<_Cp, _IsConst> +find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_) +{ + if (static_cast(__value_)) + return __find_bool_true(__first, static_cast(__last - __first)); + return __find_bool_false(__first, static_cast(__last - __first)); +} + +// count + +template +typename __bit_iterator<_Cp, _IsConst>::difference_type +__count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, _IsConst> _It; + typedef typename _It::__storage_type __storage_type; + typedef typename _It::difference_type difference_type; + static const unsigned __bits_per_word = _It::__bits_per_word; + difference_type __r = 0; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __r = _VSTD::__pop_count(*__first.__seg_ & __m); + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + __r += _VSTD::__pop_count(*__first.__seg_); + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __r += _VSTD::__pop_count(*__first.__seg_ & __m); + } + return __r; +} + +template +typename __bit_iterator<_Cp, _IsConst>::difference_type +__count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, _IsConst> _It; + typedef typename _It::__storage_type __storage_type; + typedef typename _It::difference_type difference_type; + static const unsigned __bits_per_word = _It::__bits_per_word; + difference_type __r = 0; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __r = _VSTD::__pop_count(~*__first.__seg_ & __m); + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + __r += _VSTD::__pop_count(~*__first.__seg_); + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __r += _VSTD::__pop_count(~*__first.__seg_ & __m); + } + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __bit_iterator<_Cp, _IsConst>::difference_type +count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_) +{ + if (static_cast(__value_)) + return __count_bool_true(__first, static_cast(__last - __first)); + return __count_bool_false(__first, static_cast(__last - __first)); +} + +// fill_n + +template +void +__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, false> _It; + typedef typename _It::__storage_type __storage_type; + static const unsigned __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + *__first.__seg_ &= ~__m; + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + __storage_type __nw = __n / __bits_per_word; + _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), 0, __nw * sizeof(__storage_type)); + __n -= __nw * __bits_per_word; + // do last partial word + if (__n > 0) + { + __first.__seg_ += __nw; + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + *__first.__seg_ &= ~__m; + } +} + +template +void +__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) +{ + typedef __bit_iterator<_Cp, false> _It; + typedef typename _It::__storage_type __storage_type; + static const unsigned __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) + { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = _VSTD::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + *__first.__seg_ |= __m; + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + __storage_type __nw = __n / __bits_per_word; + _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), -1, __nw * sizeof(__storage_type)); + __n -= __nw * __bits_per_word; + // do last partial word + if (__n > 0) + { + __first.__seg_ += __nw; + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + *__first.__seg_ |= __m; + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value_) +{ + if (__n > 0) + { + if (__value_) + __fill_n_true(__first, __n); + else + __fill_n_false(__first, __n); + } +} + +// fill + +template +inline _LIBCPP_INLINE_VISIBILITY +void +fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value_) +{ + _VSTD::fill_n(__first, static_cast(__last - __first), __value_); +} + +// copy + +template +__bit_iterator<_Cp, false> +__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, + __bit_iterator<_Cp, false> __result) +{ + typedef __bit_iterator<_Cp, _IsConst> _In; + typedef typename _In::difference_type difference_type; + typedef typename _In::__storage_type __storage_type; + static const unsigned __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__first.__ctz_ != 0) + { + unsigned __clz = __bits_per_word - __first.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); + __storage_type __b = *__first.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + ++__first.__seg_; + // __first.__ctz_ = 0; + } + // __first.__ctz_ == 0; + // do middle words + __storage_type __nw = __n / __bits_per_word; + _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_), + _VSTD::__to_raw_pointer(__first.__seg_), + __nw * sizeof(__storage_type)); + __n -= __nw * __bits_per_word; + __result.__seg_ += __nw; + // do last word + if (__n > 0) + { + __first.__seg_ += __nw; + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__ctz_ = static_cast(__n); + } + } + return __result; +} + +template +__bit_iterator<_Cp, false> +__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, + __bit_iterator<_Cp, false> __result) +{ + typedef __bit_iterator<_Cp, _IsConst> _In; + typedef typename _In::difference_type difference_type; + typedef typename _In::__storage_type __storage_type; + static const unsigned __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__first.__ctz_ != 0) + { + unsigned __clz_f = __bits_per_word - __first.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz_f), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = *__first.__seg_ & __m; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); + *__result.__seg_ &= ~__m; + if (__result.__ctz_ > __first.__ctz_) + *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_); + else + *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_); + __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__ddn + __result.__ctz_) % __bits_per_word); + __dn -= __ddn; + if (__dn > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __dn); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn); + __result.__ctz_ = static_cast(__dn); + } + ++__first.__seg_; + // __first.__ctz_ = 0; + } + // __first.__ctz_ == 0; + // do middle words + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __m = ~__storage_type(0) << __result.__ctz_; + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) + { + __storage_type __b = *__first.__seg_; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b << __result.__ctz_; + ++__result.__seg_; + *__result.__seg_ &= __m; + *__result.__seg_ |= __b >> __clz_r; + } + // do last word + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first.__seg_ & __m; + __storage_type __dn = _VSTD::min(__n, static_cast(__clz_r)); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b << __result.__ctz_; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> __dn; + __result.__ctz_ = static_cast(__n); + } + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<_Cp, false> +copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) +{ + if (__first.__ctz_ == __result.__ctz_) + return __copy_aligned(__first, __last, __result); + return __copy_unaligned(__first, __last, __result); +} + +// copy_backward + +template +__bit_iterator<_Cp, false> +__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, + __bit_iterator<_Cp, false> __result) +{ + typedef __bit_iterator<_Cp, _IsConst> _In; + typedef typename _In::difference_type difference_type; + typedef typename _In::__storage_type __storage_type; + static const unsigned __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__last.__ctz_ != 0) + { + difference_type __dn = _VSTD::min(static_cast(__last.__ctz_), __n); + __n -= __dn; + unsigned __clz = __bits_per_word - __last.__ctz_; + __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz); + __storage_type __b = *__last.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__ctz_ = static_cast(((-__dn & (__bits_per_word - 1)) + + __result.__ctz_) % __bits_per_word); + // __last.__ctz_ = 0 + } + // __last.__ctz_ == 0 || __n == 0 + // __result.__ctz_ == 0 || __n == 0 + // do middle words + __storage_type __nw = __n / __bits_per_word; + __result.__seg_ -= __nw; + __last.__seg_ -= __nw; + _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_), + _VSTD::__to_raw_pointer(__last.__seg_), + __nw * sizeof(__storage_type)); + __n -= __nw * __bits_per_word; + // do last word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n); + __storage_type __b = *--__last.__seg_ & __m; + *--__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__ctz_ = static_cast(-__n & (__bits_per_word - 1)); + } + } + return __result; +} + +template +__bit_iterator<_Cp, false> +__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, + __bit_iterator<_Cp, false> __result) +{ + typedef __bit_iterator<_Cp, _IsConst> _In; + typedef typename _In::difference_type difference_type; + typedef typename _In::__storage_type __storage_type; + static const unsigned __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__last.__ctz_ != 0) + { + difference_type __dn = _VSTD::min(static_cast(__last.__ctz_), __n); + __n -= __dn; + unsigned __clz_l = __bits_per_word - __last.__ctz_; + __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l); + __storage_type __b = *__last.__seg_ & __m; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __ddn = _VSTD::min(__dn, static_cast(__result.__ctz_)); + if (__ddn > 0) + { + __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r); + *__result.__seg_ &= ~__m; + if (__result.__ctz_ > __last.__ctz_) + *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); + else + *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_); + __result.__ctz_ = static_cast(((-__ddn & (__bits_per_word - 1)) + + __result.__ctz_) % __bits_per_word); + __dn -= __ddn; + } + if (__dn > 0) + { + // __result.__ctz_ == 0 + --__result.__seg_; + __result.__ctz_ = static_cast(-__dn & (__bits_per_word - 1)); + __m = ~__storage_type(0) << __result.__ctz_; + *__result.__seg_ &= ~__m; + __last.__ctz_ -= __dn + __ddn; + *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); + } + // __last.__ctz_ = 0 + } + // __last.__ctz_ == 0 || __n == 0 + // __result.__ctz_ != 0 || __n == 0 + // do middle words + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __m = ~__storage_type(0) >> __clz_r; + for (; __n >= __bits_per_word; __n -= __bits_per_word) + { + __storage_type __b = *--__last.__seg_; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> __clz_r; + *--__result.__seg_ &= __m; + *__result.__seg_ |= __b << __result.__ctz_; + } + // do last word + if (__n > 0) + { + __m = ~__storage_type(0) << (__bits_per_word - __n); + __storage_type __b = *--__last.__seg_ & __m; + __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __dn = _VSTD::min(__n, static_cast(__result.__ctz_)); + __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_); + __result.__ctz_ = static_cast(((-__dn & (__bits_per_word - 1)) + + __result.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) + { + // __result.__ctz_ == 0 + --__result.__seg_; + __result.__ctz_ = static_cast(-__n & (__bits_per_word - 1)); + __m = ~__storage_type(0) << __result.__ctz_; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn)); + } + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<_Cp, false> +copy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) +{ + if (__last.__ctz_ == __result.__ctz_) + return __copy_backward_aligned(__first, __last, __result); + return __copy_backward_unaligned(__first, __last, __result); +} + +// move + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<_Cp, false> +move(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) +{ + return _VSTD::copy(__first, __last, __result); +} + +// move_backward + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<_Cp, false> +move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) +{ + return _VSTD::copy_backward(__first, __last, __result); +} + +// swap_ranges + +template +__bit_iterator<__C2, false> +__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, + __bit_iterator<__C2, false> __result) +{ + typedef __bit_iterator<__C1, false> _I1; + typedef typename _I1::difference_type difference_type; + typedef typename _I1::__storage_type __storage_type; + static const unsigned __bits_per_word = _I1::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__first.__ctz_ != 0) + { + unsigned __clz = __bits_per_word - __first.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1; + *__first.__seg_ |= __b2; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + ++__first.__seg_; + // __first.__ctz_ = 0; + } + // __first.__ctz_ == 0; + // do middle words + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_) + swap(*__first.__seg_, *__result.__seg_); + // do last word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1; + *__first.__seg_ |= __b2; + __result.__ctz_ = static_cast(__n); + } + } + return __result; +} + +template +__bit_iterator<__C2, false> +__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, + __bit_iterator<__C2, false> __result) +{ + typedef __bit_iterator<__C1, false> _I1; + typedef typename _I1::difference_type difference_type; + typedef typename _I1::__storage_type __storage_type; + static const unsigned __bits_per_word = _I1::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) + { + // do first word + if (__first.__ctz_ != 0) + { + unsigned __clz_f = __bits_per_word - __first.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz_f), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + if (__result.__ctz_ > __first.__ctz_) + { + unsigned __s = __result.__ctz_ - __first.__ctz_; + *__result.__seg_ |= __b1 << __s; + *__first.__seg_ |= __b2 >> __s; + } + else + { + unsigned __s = __first.__ctz_ - __result.__ctz_; + *__result.__seg_ |= __b1 >> __s; + *__first.__seg_ |= __b2 << __s; + } + __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__ddn + __result.__ctz_) % __bits_per_word); + __dn -= __ddn; + if (__dn > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __dn); + __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + unsigned __s = __first.__ctz_ + __ddn; + *__result.__seg_ |= __b1 >> __s; + *__first.__seg_ |= __b2 << __s; + __result.__ctz_ = static_cast(__dn); + } + ++__first.__seg_; + // __first.__ctz_ = 0; + } + // __first.__ctz_ == 0; + // do middle words + __storage_type __m = ~__storage_type(0) << __result.__ctz_; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) + { + __storage_type __b1 = *__first.__seg_; + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1 << __result.__ctz_; + *__first.__seg_ = __b2 >> __result.__ctz_; + ++__result.__seg_; + __b2 = *__result.__seg_ & ~__m; + *__result.__seg_ &= __m; + *__result.__seg_ |= __b1 >> __clz_r; + *__first.__seg_ |= __b2 << __clz_r; + } + // do last word + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1 << __result.__ctz_; + *__first.__seg_ |= __b2 >> __result.__ctz_; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1 >> __dn; + *__first.__seg_ |= __b2 << __dn; + __result.__ctz_ = static_cast(__n); + } + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__bit_iterator<__C2, false> +swap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1, + __bit_iterator<__C2, false> __first2) +{ + if (__first1.__ctz_ == __first2.__ctz_) + return __swap_ranges_aligned(__first1, __last1, __first2); + return __swap_ranges_unaligned(__first1, __last1, __first2); +} + +// rotate + +template +struct __bit_array +{ + typedef typename _Cp::difference_type difference_type; + typedef typename _Cp::__storage_type __storage_type; + typedef typename _Cp::__storage_pointer __storage_pointer; + typedef typename _Cp::iterator iterator; + static const unsigned __bits_per_word = _Cp::__bits_per_word; + static const unsigned _Np = 4; + + difference_type __size_; + __storage_type __word_[_Np]; + + _LIBCPP_INLINE_VISIBILITY static difference_type capacity() + {return static_cast(_Np * __bits_per_word);} + _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {} + _LIBCPP_INLINE_VISIBILITY iterator begin() + { + return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0); + } + _LIBCPP_INLINE_VISIBILITY iterator end() + { + return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word, + static_cast(__size_ % __bits_per_word)); + } +}; + +template +__bit_iterator<_Cp, false> +rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last) +{ + typedef __bit_iterator<_Cp, false> _I1; + typedef typename _I1::difference_type difference_type; + difference_type __d1 = __middle - __first; + difference_type __d2 = __last - __middle; + _I1 __r = __first + __d2; + while (__d1 != 0 && __d2 != 0) + { + if (__d1 <= __d2) + { + if (__d1 <= __bit_array<_Cp>::capacity()) + { + __bit_array<_Cp> __b(__d1); + _VSTD::copy(__first, __middle, __b.begin()); + _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first)); + break; + } + else + { + __bit_iterator<_Cp, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle); + __first = __middle; + __middle = __mp; + __d2 -= __d1; + } + } + else + { + if (__d2 <= __bit_array<_Cp>::capacity()) + { + __bit_array<_Cp> __b(__d2); + _VSTD::copy(__middle, __last, __b.begin()); + _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last)); + break; + } + else + { + __bit_iterator<_Cp, false> __mp = __first + __d2; + _VSTD::swap_ranges(__first, __mp, __middle); + __first = __mp; + __d1 -= __d2; + } + } + } + return __r; +} + +// equal + +template +bool +__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, + __bit_iterator<_Cp, _IC2> __first2) +{ + typedef __bit_iterator<_Cp, _IC1> _It; + typedef typename _It::difference_type difference_type; + typedef typename _It::__storage_type __storage_type; + static const unsigned __bits_per_word = _It::__bits_per_word; + difference_type __n = __last1 - __first1; + if (__n > 0) + { + // do first word + if (__first1.__ctz_ != 0) + { + unsigned __clz_f = __bits_per_word - __first1.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz_f), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = *__first1.__seg_ & __m; + unsigned __clz_r = __bits_per_word - __first2.__ctz_; + __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); + __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); + if (__first2.__ctz_ > __first1.__ctz_) + { + if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_))) + return false; + } + else + { + if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_))) + return false; + } + __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word; + __first2.__ctz_ = static_cast((__ddn + __first2.__ctz_) % __bits_per_word); + __dn -= __ddn; + if (__dn > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __dn); + if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn))) + return false; + __first2.__ctz_ = static_cast(__dn); + } + ++__first1.__seg_; + // __first1.__ctz_ = 0; + } + // __first1.__ctz_ == 0; + // do middle words + unsigned __clz_r = __bits_per_word - __first2.__ctz_; + __storage_type __m = ~__storage_type(0) << __first2.__ctz_; + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) + { + __storage_type __b = *__first1.__seg_; + if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) + return false; + ++__first2.__seg_; + if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r)) + return false; + } + // do last word + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first1.__seg_ & __m; + __storage_type __dn = _VSTD::min(__n, static_cast(__clz_r)); + __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); + if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) + return false; + __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word; + __first2.__ctz_ = static_cast((__dn + __first2.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) + { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + if ((*__first2.__seg_ & __m) != (__b >> __dn)) + return false; + } + } + } + return true; +} + +template +bool +__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, + __bit_iterator<_Cp, _IC2> __first2) +{ + typedef __bit_iterator<_Cp, _IC1> _It; + typedef typename _It::difference_type difference_type; + typedef typename _It::__storage_type __storage_type; + static const unsigned __bits_per_word = _It::__bits_per_word; + difference_type __n = __last1 - __first1; + if (__n > 0) + { + // do first word + if (__first1.__ctz_ != 0) + { + unsigned __clz = __bits_per_word - __first1.__ctz_; + difference_type __dn = _VSTD::min(static_cast(__clz), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); + if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) + return false; + ++__first2.__seg_; + ++__first1.__seg_; + // __first1.__ctz_ = 0; + // __first2.__ctz_ = 0; + } + // __first1.__ctz_ == 0; + // __first2.__ctz_ == 0; + // do middle words + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_) + if (*__first2.__seg_ != *__first1.__seg_) + return false; + // do last word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) + return false; + } + } + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) +{ + if (__first1.__ctz_ == __first2.__ctz_) + return __equal_aligned(__first1, __last1, __first2); + return __equal_unaligned(__first1, __last1, __first2); +} + +template +class __bit_iterator +{ +public: + typedef typename _Cp::difference_type difference_type; + typedef bool value_type; + typedef __bit_iterator pointer; + typedef typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >::type reference; + typedef random_access_iterator_tag iterator_category; + +private: + typedef typename _Cp::__storage_type __storage_type; + typedef typename conditional<_IsConst, typename _Cp::__const_storage_pointer, + typename _Cp::__storage_pointer>::type __storage_pointer; + static const unsigned __bits_per_word = _Cp::__bits_per_word; + + __storage_pointer __seg_; + unsigned __ctz_; + +public: + _LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT +#if _LIBCPP_STD_VER > 11 + : __seg_(nullptr), __ctz_(0) +#endif + {} + + _LIBCPP_INLINE_VISIBILITY + __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT + : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} + + _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT + {return reference(__seg_, __storage_type(1) << __ctz_);} + + _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++() + { + if (__ctz_ != __bits_per_word-1) + ++__ctz_; + else + { + __ctz_ = 0; + ++__seg_; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY __bit_iterator operator++(int) + { + __bit_iterator __tmp = *this; + ++(*this); + return __tmp; + } + + _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator--() + { + if (__ctz_ != 0) + --__ctz_; + else + { + __ctz_ = __bits_per_word - 1; + --__seg_; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY __bit_iterator operator--(int) + { + __bit_iterator __tmp = *this; + --(*this); + return __tmp; + } + + _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator+=(difference_type __n) + { + if (__n >= 0) + __seg_ += (__n + __ctz_) / __bits_per_word; + else + __seg_ += static_cast(__n - __bits_per_word + __ctz_ + 1) + / static_cast(__bits_per_word); + __n &= (__bits_per_word - 1); + __ctz_ = static_cast((__n + __ctz_) % __bits_per_word); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator-=(difference_type __n) + { + return *this += -__n; + } + + _LIBCPP_INLINE_VISIBILITY __bit_iterator operator+(difference_type __n) const + { + __bit_iterator __t(*this); + __t += __n; + return __t; + } + + _LIBCPP_INLINE_VISIBILITY __bit_iterator operator-(difference_type __n) const + { + __bit_iterator __t(*this); + __t -= __n; + return __t; + } + + _LIBCPP_INLINE_VISIBILITY + friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;} + + _LIBCPP_INLINE_VISIBILITY + friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y) + {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;} + + _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const {return *(*this + __n);} + + _LIBCPP_INLINE_VISIBILITY friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y) + {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;} + + _LIBCPP_INLINE_VISIBILITY friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y) + {return !(__x == __y);} + + _LIBCPP_INLINE_VISIBILITY friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y) + {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);} + + _LIBCPP_INLINE_VISIBILITY friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y) + {return __y < __x;} + + _LIBCPP_INLINE_VISIBILITY friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y) + {return !(__y < __x);} + + _LIBCPP_INLINE_VISIBILITY friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y) + {return !(__x < __y);} + +private: + _LIBCPP_INLINE_VISIBILITY + __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT + : __seg_(__s), __ctz_(__ctz) {} + +#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC) + friend typename _Cp::__self; +#else + friend class _Cp::__self; +#endif + friend class __bit_reference<_Cp>; + friend class __bit_const_reference<_Cp>; + friend class __bit_iterator<_Cp, true>; + template friend struct __bit_array; + template friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); + template friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); + template friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>, + __bit_iterator<__C1, false>, + __bit_iterator<__C2, false>); + template friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>, + __bit_iterator<__C1, false>, + __bit_iterator<__C2, false>); + template friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>, + __bit_iterator<__C1, false>, + __bit_iterator<__C2, false>); + template friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>, + __bit_iterator<_Dp, false>, + __bit_iterator<_Dp, false>); + template friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC2>); + template friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC2>); + template friend bool equal(__bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC2>); + template friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>, + typename _Dp::size_type); + template friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>, + typename _Dp::size_type); + template friend typename __bit_iterator<_Dp, _IC>::difference_type + __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); + template friend typename __bit_iterator<_Dp, _IC>::difference_type + __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_REFERENCE diff --git a/headers/libs/libc++/__config b/headers/libs/libc++/__config new file mode 100644 index 0000000000..7f6fbf07b5 --- /dev/null +++ b/headers/libs/libc++/__config @@ -0,0 +1,825 @@ +// -*- C++ -*- +//===--------------------------- __config ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CONFIG +#define _LIBCPP_CONFIG + +#if defined(_MSC_VER) && !defined(__clang__) +#define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#endif + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +#ifdef __cplusplus + +#ifdef __GNUC__ +#define _GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__) +#else +#define _GNUC_VER 0 +#endif + +#define _LIBCPP_VERSION 3800 + +#ifndef _LIBCPP_ABI_VERSION +#define _LIBCPP_ABI_VERSION 1 +#endif + +#if defined(_LIBCPP_ABI_UNSTABLE) || _LIBCPP_ABI_VERSION >= 2 +// Change short string represention so that string data starts at offset 0, +// improving its alignment in some cases. +#define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +// Fix deque iterator type in order to support incomplete types. +#define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE +#endif + +#define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y +#define _LIBCPP_CONCAT(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) + +#define _LIBCPP_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION) + + +#ifndef __has_attribute +#define __has_attribute(__x) 0 +#endif +#ifndef __has_builtin +#define __has_builtin(__x) 0 +#endif +#ifndef __has_extension +#define __has_extension(__x) 0 +#endif +#ifndef __has_feature +#define __has_feature(__x) 0 +#endif +// '__is_identifier' returns '0' if '__x' is a reserved identifier provided by +// the compiler and '1' otherwise. +#ifndef __is_identifier +#define __is_identifier(__x) 1 +#endif + + +#ifdef __LITTLE_ENDIAN__ +#if __LITTLE_ENDIAN__ +#define _LIBCPP_LITTLE_ENDIAN 1 +#define _LIBCPP_BIG_ENDIAN 0 +#endif // __LITTLE_ENDIAN__ +#endif // __LITTLE_ENDIAN__ + +#ifdef __BIG_ENDIAN__ +#if __BIG_ENDIAN__ +#define _LIBCPP_LITTLE_ENDIAN 0 +#define _LIBCPP_BIG_ENDIAN 1 +#endif // __BIG_ENDIAN__ +#endif // __BIG_ENDIAN__ + +#ifdef __BYTE_ORDER__ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define _LIBCPP_LITTLE_ENDIAN 1 +#define _LIBCPP_BIG_ENDIAN 0 +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define _LIBCPP_LITTLE_ENDIAN 0 +#define _LIBCPP_BIG_ENDIAN 1 +#endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#endif // __BYTE_ORDER__ + +#ifdef __FreeBSD__ +# include +# if _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN 1 +# define _LIBCPP_BIG_ENDIAN 0 +# else // _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN 0 +# define _LIBCPP_BIG_ENDIAN 1 +# endif // _BYTE_ORDER == _LITTLE_ENDIAN +# ifndef __LONG_LONG_SUPPORTED +# define _LIBCPP_HAS_NO_LONG_LONG +# endif // __LONG_LONG_SUPPORTED +#endif // __FreeBSD__ + +#ifdef __NetBSD__ +# include +# if _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN 1 +# define _LIBCPP_BIG_ENDIAN 0 +# else // _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN 0 +# define _LIBCPP_BIG_ENDIAN 1 +# endif // _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_HAS_QUICK_EXIT +#endif // __NetBSD__ + +#ifdef _WIN32 +# define _LIBCPP_LITTLE_ENDIAN 1 +# define _LIBCPP_BIG_ENDIAN 0 +// Compiler intrinsics (MSVC) +#if defined(_MSC_VER) && _MSC_VER >= 1400 +# define _LIBCPP_HAS_IS_BASE_OF +# endif +# if defined(_MSC_VER) && !defined(__clang__) +# define _LIBCPP_MSVC // Using Microsoft Visual C++ compiler +# define _LIBCPP_TOSTRING2(x) #x +# define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x) +# define _LIBCPP_WARNING(x) __pragma(message(__FILE__ "(" _LIBCPP_TOSTRING(__LINE__) ") : warning note: " x)) +# endif +# // If mingw not explicitly detected, assume using MS C runtime only. +# ifndef __MINGW32__ +# define _LIBCPP_MSVCRT // Using Microsoft's C Runtime library +# endif +#endif // _WIN32 + +#ifdef __sun__ +# include +# ifdef _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN 1 +# define _LIBCPP_BIG_ENDIAN 0 +# else +# define _LIBCPP_LITTLE_ENDIAN 0 +# define _LIBCPP_BIG_ENDIAN 1 +# endif +#endif // __sun__ + +#if defined(__CloudABI__) + // Certain architectures provide arc4random(). Prefer using + // arc4random() over /dev/{u,}random to make it possible to obtain + // random data even when using sandboxing mechanisms such as chroots, + // Capsicum, etc. +# define _LIBCPP_USING_ARC4_RANDOM +#elif defined(__native_client__) + // NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access, + // including accesses to the special files under /dev. C++11's + // std::random_device is instead exposed through a NaCl syscall. +# define _LIBCPP_USING_NACL_RANDOM +#elif defined(_WIN32) +# define _LIBCPP_USING_WIN32_RANDOM +#else +# define _LIBCPP_USING_DEV_RANDOM +#endif + +#if !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN) +# include +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN 1 +# define _LIBCPP_BIG_ENDIAN 0 +# elif __BYTE_ORDER == __BIG_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN 0 +# define _LIBCPP_BIG_ENDIAN 1 +# else // __BYTE_ORDER == __BIG_ENDIAN +# error unable to determine endian +# endif +#endif // !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN) + +#ifdef _WIN32 + +// only really useful for a DLL +#ifdef _LIBCPP_DLL // this should be a compiler builtin define ideally... +# ifdef cxx_EXPORTS +# define _LIBCPP_HIDDEN +# define _LIBCPP_FUNC_VIS __declspec(dllexport) +# define _LIBCPP_TYPE_VIS __declspec(dllexport) +# else +# define _LIBCPP_HIDDEN +# define _LIBCPP_FUNC_VIS __declspec(dllimport) +# define _LIBCPP_TYPE_VIS __declspec(dllimport) +# endif +#else +# define _LIBCPP_HIDDEN +# define _LIBCPP_FUNC_VIS +# define _LIBCPP_TYPE_VIS +#endif + +#define _LIBCPP_TYPE_VIS_ONLY +#define _LIBCPP_FUNC_VIS_ONLY + +#ifndef _LIBCPP_INLINE_VISIBILITY +# ifdef _LIBCPP_MSVC +# define _LIBCPP_INLINE_VISIBILITY __forceinline +# else // MinGW GCC and Clang +# define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__always_inline__)) +# endif +#endif + +#ifndef _LIBCPP_EXCEPTION_ABI +#define _LIBCPP_EXCEPTION_ABI _LIBCPP_TYPE_VIS +#endif + +#ifndef _LIBCPP_ALWAYS_INLINE +# ifdef _LIBCPP_MSVC +# define _LIBCPP_ALWAYS_INLINE __forceinline +# endif +#endif + +#endif // _WIN32 + +#ifndef _LIBCPP_HIDDEN +#define _LIBCPP_HIDDEN __attribute__ ((__visibility__("hidden"))) +#endif + +#ifndef _LIBCPP_FUNC_VIS +#define _LIBCPP_FUNC_VIS __attribute__ ((__visibility__("default"))) +#endif + +#ifndef _LIBCPP_TYPE_VIS +# if __has_attribute(__type_visibility__) +# define _LIBCPP_TYPE_VIS __attribute__ ((__type_visibility__("default"))) +# else +# define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default"))) +# endif +#endif + +#ifndef _LIBCPP_TYPE_VIS_ONLY +# define _LIBCPP_TYPE_VIS_ONLY _LIBCPP_TYPE_VIS +#endif + +#ifndef _LIBCPP_FUNC_VIS_ONLY +# define _LIBCPP_FUNC_VIS_ONLY _LIBCPP_FUNC_VIS +#endif + +#ifndef _LIBCPP_INLINE_VISIBILITY +#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__)) +#endif + +#ifndef _LIBCPP_EXCEPTION_ABI +#define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__("default"))) +#endif + +#ifndef _LIBCPP_ALWAYS_INLINE +#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__visibility__("hidden"), __always_inline__)) +#endif + +#if defined(__clang__) + +// _LIBCPP_ALTERNATE_STRING_LAYOUT is an old name for +// _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT left here for backward compatibility. +#if (defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && \ + !defined(__arm__)) || \ + defined(_LIBCPP_ALTERNATE_STRING_LAYOUT) +#define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +#endif + +#if __has_feature(cxx_alignas) +# define _ALIGNAS_TYPE(x) alignas(x) +# define _ALIGNAS(x) alignas(x) +#else +# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) +# define _ALIGNAS(x) __attribute__((__aligned__(x))) +#endif + +#if !__has_feature(cxx_alias_templates) +#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#endif + +#if __cplusplus < 201103L +typedef __char16_t char16_t; +typedef __char32_t char32_t; +#endif + +#if !(__has_feature(cxx_exceptions)) +#define _LIBCPP_NO_EXCEPTIONS +#endif + +#if !(__has_feature(cxx_rtti)) +#define _LIBCPP_NO_RTTI +#endif + +#if !(__has_feature(cxx_strong_enums)) +#define _LIBCPP_HAS_NO_STRONG_ENUMS +#endif + +#if !(__has_feature(cxx_decltype)) +#define _LIBCPP_HAS_NO_DECLTYPE +#endif + +#if __has_feature(cxx_attributes) +# define _LIBCPP_NORETURN [[noreturn]] +#else +# define _LIBCPP_NORETURN __attribute__ ((noreturn)) +#endif + +#define _LIBCPP_UNUSED __attribute__((__unused__)) + +#if !(__has_feature(cxx_defaulted_functions)) +#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#endif // !(__has_feature(cxx_defaulted_functions)) + +#if !(__has_feature(cxx_deleted_functions)) +#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS +#endif // !(__has_feature(cxx_deleted_functions)) + +#if !(__has_feature(cxx_lambdas)) +#define _LIBCPP_HAS_NO_LAMBDAS +#endif + +#if !(__has_feature(cxx_nullptr)) +#define _LIBCPP_HAS_NO_NULLPTR +#endif + +#if !(__has_feature(cxx_rvalue_references)) +#define _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif + +#if !(__has_feature(cxx_static_assert)) +#define _LIBCPP_HAS_NO_STATIC_ASSERT +#endif + +#if !(__has_feature(cxx_auto_type)) +#define _LIBCPP_HAS_NO_AUTO_TYPE +#endif + +#if !(__has_feature(cxx_access_control_sfinae)) || !__has_feature(cxx_trailing_return) +#define _LIBCPP_HAS_NO_ADVANCED_SFINAE +#endif + +#if !(__has_feature(cxx_variadic_templates)) +#define _LIBCPP_HAS_NO_VARIADICS +#endif + +#if !(__has_feature(cxx_trailing_return)) +#define _LIBCPP_HAS_NO_TRAILING_RETURN +#endif + +#if !(__has_feature(cxx_generalized_initializers)) +#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS +#endif + +#if __has_feature(is_base_of) +# define _LIBCPP_HAS_IS_BASE_OF +#endif + +#if __has_feature(is_final) +# define _LIBCPP_HAS_IS_FINAL +#endif + +// Objective-C++ features (opt-in) +#if __has_feature(objc_arc) +#define _LIBCPP_HAS_OBJC_ARC +#endif + +#if __has_feature(objc_arc_weak) +#define _LIBCPP_HAS_OBJC_ARC_WEAK +#define _LIBCPP_HAS_NO_STRONG_ENUMS +#endif + +#if !(__has_feature(cxx_constexpr)) +#define _LIBCPP_HAS_NO_CONSTEXPR +#endif + +#if !(__has_feature(cxx_relaxed_constexpr)) +#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR +#endif + +#if !(__has_feature(cxx_variable_templates)) +#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES +#endif + +#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L +#if defined(__FreeBSD__) +#define _LIBCPP_HAS_QUICK_EXIT +#define _LIBCPP_HAS_C11_FEATURES +#elif defined(__ANDROID__) +#define _LIBCPP_HAS_QUICK_EXIT +#elif defined(__linux__) +#include +#if __GLIBC_PREREQ(2, 15) +#define _LIBCPP_HAS_QUICK_EXIT +#endif +#if __GLIBC_PREREQ(2, 17) +#define _LIBCPP_HAS_C11_FEATURES +#endif +#endif +#endif + +#if (__has_feature(cxx_noexcept)) +# define _NOEXCEPT noexcept +# define _NOEXCEPT_(x) noexcept(x) +# define _NOEXCEPT_OR_FALSE(x) noexcept(x) +#else +# define _NOEXCEPT throw() +# define _NOEXCEPT_(x) +# define _NOEXCEPT_OR_FALSE(x) false +#endif + +#if __has_feature(underlying_type) +# define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T) +#endif + +#if __has_feature(is_literal) +# define _LIBCPP_IS_LITERAL(T) __is_literal(T) +#endif + +// Inline namespaces are available in Clang regardless of C++ dialect. +#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE { +#define _LIBCPP_END_NAMESPACE_STD } } +#define _VSTD std::_LIBCPP_NAMESPACE + +namespace std { + inline namespace _LIBCPP_NAMESPACE { + } +} + +#if !defined(_LIBCPP_HAS_NO_ASAN) && !__has_feature(address_sanitizer) +#define _LIBCPP_HAS_NO_ASAN +#endif + +#elif defined(__GNUC__) + +#define _ALIGNAS(x) __attribute__((__aligned__(x))) +#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) + +#define _LIBCPP_NORETURN __attribute__((noreturn)) + +#define _LIBCPP_UNUSED __attribute__((__unused__)) + +#if _GNUC_VER >= 407 +#define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T) +#define _LIBCPP_IS_LITERAL(T) __is_literal_type(T) +#define _LIBCPP_HAS_IS_FINAL +#endif + +#if defined(__GNUC__) && _GNUC_VER >= 403 +# define _LIBCPP_HAS_IS_BASE_OF +#endif + +#if !__EXCEPTIONS +#define _LIBCPP_NO_EXCEPTIONS +#endif + +#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES + +// constexpr was added to GCC in 4.6. +#if _GNUC_VER < 406 +#define _LIBCPP_HAS_NO_CONSTEXPR +// Can only use constexpr in c++11 mode. +#elif !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L +#define _LIBCPP_HAS_NO_CONSTEXPR +#endif + +// Determine if GCC supports relaxed constexpr +#if !defined(__cpp_constexpr) || __cpp_constexpr < 201304L +#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR +#endif + +// GCC 5 will support variable templates +#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES + +#define _NOEXCEPT throw() +#define _NOEXCEPT_(x) +#define _NOEXCEPT_OR_FALSE(x) false + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ + +#define _LIBCPP_HAS_NO_ADVANCED_SFINAE +#define _LIBCPP_HAS_NO_DECLTYPE +#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS +#define _LIBCPP_HAS_NO_NULLPTR +#define _LIBCPP_HAS_NO_STATIC_ASSERT +#define _LIBCPP_HAS_NO_UNICODE_CHARS +#define _LIBCPP_HAS_NO_VARIADICS +#define _LIBCPP_HAS_NO_RVALUE_REFERENCES +#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS +#define _LIBCPP_HAS_NO_STRONG_ENUMS + +#else // __GXX_EXPERIMENTAL_CXX0X__ + +#define _LIBCPP_HAS_NO_TRAILING_RETURN +#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS + +#if _GNUC_VER < 403 +#define _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif + +#if _GNUC_VER < 403 +#define _LIBCPP_HAS_NO_STATIC_ASSERT +#endif + +#if _GNUC_VER < 404 +#define _LIBCPP_HAS_NO_DECLTYPE +#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS +#define _LIBCPP_HAS_NO_UNICODE_CHARS +#define _LIBCPP_HAS_NO_VARIADICS +#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS +#endif // _GNUC_VER < 404 + +#if _GNUC_VER < 406 +#define _LIBCPP_HAS_NO_NULLPTR +#endif + +#if _GNUC_VER < 407 +#define _LIBCPP_HAS_NO_ADVANCED_SFINAE +#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#endif + +#endif // __GXX_EXPERIMENTAL_CXX0X__ + +#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { namespace _LIBCPP_NAMESPACE { +#define _LIBCPP_END_NAMESPACE_STD } } +#define _VSTD std::_LIBCPP_NAMESPACE + +namespace std { +namespace _LIBCPP_NAMESPACE { +} +using namespace _LIBCPP_NAMESPACE __attribute__((__strong__)); +} + +#if !defined(_LIBCPP_HAS_NO_ASAN) && !defined(__SANITIZE_ADDRESS__) +#define _LIBCPP_HAS_NO_ASAN +#endif + +#elif defined(_LIBCPP_MSVC) + +#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#define _LIBCPP_HAS_NO_CONSTEXPR +#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR +#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES +#define _LIBCPP_HAS_NO_UNICODE_CHARS +#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS +#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#define __alignof__ __alignof +#define _LIBCPP_NORETURN __declspec(noreturn) +#define _LIBCPP_UNUSED +#define _ALIGNAS(x) __declspec(align(x)) +#define _LIBCPP_HAS_NO_VARIADICS + +#define _NOEXCEPT throw () +#define _NOEXCEPT_(x) +#define _NOEXCEPT_OR_FALSE(x) false + +#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { +#define _LIBCPP_END_NAMESPACE_STD } +#define _VSTD std + +# define _LIBCPP_WEAK +namespace std { +} + +#define _LIBCPP_HAS_NO_ASAN + +#elif defined(__IBMCPP__) + +#define _ALIGNAS(x) __attribute__((__aligned__(x))) +#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) +#define _ATTRIBUTE(x) __attribute__((x)) +#define _LIBCPP_NORETURN __attribute__((noreturn)) +#define _LIBCPP_UNUSED + +#define _NOEXCEPT throw() +#define _NOEXCEPT_(x) +#define _NOEXCEPT_OR_FALSE(x) false + +#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#define _LIBCPP_HAS_NO_ADVANCED_SFINAE +#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS +#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS +#define _LIBCPP_HAS_NO_NULLPTR +#define _LIBCPP_HAS_NO_UNICODE_CHARS +#define _LIBCPP_HAS_IS_BASE_OF +#define _LIBCPP_HAS_IS_FINAL +#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES + +#if defined(_AIX) +#define __MULTILOCALE_API +#endif + +#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE { +#define _LIBCPP_END_NAMESPACE_STD } } +#define _VSTD std::_LIBCPP_NAMESPACE + +namespace std { + inline namespace _LIBCPP_NAMESPACE { + } +} + +#define _LIBCPP_HAS_NO_ASAN + +#endif // __clang__ || __GNUC__ || _MSC_VER || __IBMCPP__ + +#ifdef _LIBCPP_HAS_NO_UNICODE_CHARS +typedef unsigned short char16_t; +typedef unsigned int char32_t; +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + +#ifndef __SIZEOF_INT128__ +#define _LIBCPP_HAS_NO_INT128 +#endif + +#ifdef _LIBCPP_HAS_NO_STATIC_ASSERT + +extern "C++" { +template struct __static_assert_test; +template <> struct __static_assert_test {}; +template struct __static_assert_check {}; +} +#define static_assert(__b, __m) \ + typedef __static_assert_check)> \ + _LIBCPP_CONCAT(__t, __LINE__) + +#endif // _LIBCPP_HAS_NO_STATIC_ASSERT + +#ifdef _LIBCPP_HAS_NO_DECLTYPE +// GCC 4.6 provides __decltype in all standard modes. +#if !__is_identifier(__decltype) || _GNUC_VER >= 406 +# define decltype(__x) __decltype(__x) +#else +# define decltype(__x) __typeof__(__x) +#endif +#endif + +#ifdef _LIBCPP_HAS_NO_CONSTEXPR +#define _LIBCPP_CONSTEXPR +#else +#define _LIBCPP_CONSTEXPR constexpr +#endif + +#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#define _LIBCPP_DEFAULT {} +#else +#define _LIBCPP_DEFAULT = default; +#endif + +#ifdef __GNUC__ +#define _NOALIAS __attribute__((__malloc__)) +#else +#define _NOALIAS +#endif + +#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__) +# define _LIBCPP_EXPLICIT explicit +#else +# define _LIBCPP_EXPLICIT +#endif + +#if !__has_builtin(__builtin_operator_new) || !__has_builtin(__builtin_operator_delete) +# define _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE +#endif + +#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS +#define _LIBCPP_DECLARE_STRONG_ENUM(x) struct _LIBCPP_TYPE_VIS x { enum __lx +#define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \ + __lx __v_; \ + _LIBCPP_ALWAYS_INLINE x(__lx __v) : __v_(__v) {} \ + _LIBCPP_ALWAYS_INLINE explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \ + _LIBCPP_ALWAYS_INLINE operator int() const {return __v_;} \ + }; +#else // _LIBCPP_HAS_NO_STRONG_ENUMS +#define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_TYPE_VIS x +#define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) +#endif // _LIBCPP_HAS_NO_STRONG_ENUMS + +#ifdef _LIBCPP_DEBUG +# if _LIBCPP_DEBUG == 0 +# define _LIBCPP_DEBUG_LEVEL 1 +# elif _LIBCPP_DEBUG == 1 +# define _LIBCPP_DEBUG_LEVEL 2 +# else +# error Supported values for _LIBCPP_DEBUG are 0 and 1 +# endif +# define _LIBCPP_EXTERN_TEMPLATE(...) +#endif + +#ifndef _LIBCPP_EXTERN_TEMPLATE +#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__; +#endif + +#ifndef _LIBCPP_EXTERN_TEMPLATE2 +#define _LIBCPP_EXTERN_TEMPLATE2(...) extern template __VA_ARGS__; +#endif + +#if defined(__APPLE__) && defined(__LP64__) && !defined(__x86_64__) +#define _LIBCPP_NONUNIQUE_RTTI_BIT (1ULL << 63) +#endif + +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || \ + defined(__sun__) || defined(__NetBSD__) || defined(__CloudABI__) +#define _LIBCPP_LOCALE__L_EXTENSIONS 1 +#endif + +#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(_NEWLIB_VERSION) && \ + !defined(__CloudABI__) +#define _LIBCPP_HAS_CATOPEN 1 +#endif + +#ifdef __FreeBSD__ +#define _DECLARE_C99_LDBL_MATH 1 +#endif + +#if defined(__APPLE__) || defined(__FreeBSD__) +#define _LIBCPP_HAS_DEFAULTRUNELOCALE +#endif + +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__) +#define _LIBCPP_WCTYPE_IS_MASK +#endif + +#ifndef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR +# define _LIBCPP_TRIVIAL_PAIR_COPY_CTOR 1 +#endif + +#ifndef _LIBCPP_STD_VER +# if __cplusplus <= 201103L +# define _LIBCPP_STD_VER 11 +# elif __cplusplus <= 201402L +# define _LIBCPP_STD_VER 14 +# else +# define _LIBCPP_STD_VER 15 // current year, or date of c++17 ratification +# endif +#endif // _LIBCPP_STD_VER + +#if _LIBCPP_STD_VER > 11 +#define _LIBCPP_DEPRECATED [[deprecated]] +#else +#define _LIBCPP_DEPRECATED +#endif + +#if _LIBCPP_STD_VER <= 11 +#define _LIBCPP_EXPLICIT_AFTER_CXX11 +#define _LIBCPP_DEPRECATED_AFTER_CXX11 +#else +#define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit +#define _LIBCPP_DEPRECATED_AFTER_CXX11 [[deprecated]] +#endif + +#if _LIBCPP_STD_VER > 11 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +#define _LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr +#else +#define _LIBCPP_CONSTEXPR_AFTER_CXX11 +#endif + +#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES +# define _LIBCPP_EXPLICIT_MOVE(x) _VSTD::move(x) +#else +# define _LIBCPP_EXPLICIT_MOVE(x) (x) +#endif + +#ifndef _LIBCPP_HAS_NO_ASAN +extern "C" void __sanitizer_annotate_contiguous_container( + const void *, const void *, const void *, const void *); +#endif + +// Try to find out if RTTI is disabled. +// g++ and cl.exe have RTTI on by default and define a macro when it is. +// g++ only defines the macro in 4.3.2 and onwards. +#if !defined(_LIBCPP_NO_RTTI) +# if defined(__GNUC__) && ((__GNUC__ >= 5) || (__GNUC__ == 4 && \ + (__GNUC_MINOR__ >= 3 || __GNUC_PATCHLEVEL__ >= 2))) && !defined(__GXX_RTTI) +# define _LIBCPP_NO_RTTI +# elif (defined(_MSC_VER) && !defined(__clang__)) && !defined(_CPPRTTI) +# define _LIBCPP_NO_RTTI +# endif +#endif + +#ifndef _LIBCPP_WEAK +# define _LIBCPP_WEAK __attribute__((__weak__)) +#endif + +#if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(_LIBCPP_HAS_NO_THREADS) +# error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \ + _LIBCPP_HAS_NO_THREADS is defined. +#endif + +// Systems that use capability-based security (FreeBSD with Capsicum, +// Nuxi CloudABI) may only provide local filesystem access (using *at()). +// Functions like open(), rename(), unlink() and stat() should not be +// used, as they attempt to access the global filesystem namespace. +#ifdef __CloudABI__ +#define _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +#endif + +// CloudABI is intended for running networked services. Processes do not +// have standard input and output channels. +#ifdef __CloudABI__ +#define _LIBCPP_HAS_NO_STDIN +#define _LIBCPP_HAS_NO_STDOUT +#endif + +#if defined(__ANDROID__) || defined(__CloudABI__) +#define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE +#endif + +// Thread-unsafe functions such as strtok(), mbtowc() and localtime() +// are not available. +#ifdef __CloudABI__ +#define _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS +#endif + +#if __has_feature(cxx_atomic) || __has_extension(c_atomic) +#define _LIBCPP_HAS_C_ATOMIC_IMP +#elif _GNUC_VER > 407 +#define _LIBCPP_HAS_GCC_ATOMIC_IMP +#endif + +#if (!defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)) \ + || defined(_LIBCPP_HAS_NO_THREADS) +#define _LIBCPP_HAS_NO_ATOMIC_HEADER +#endif + +#endif // __cplusplus + +#endif // _LIBCPP_CONFIG diff --git a/headers/libs/libc++/__config_site.in b/headers/libs/libc++/__config_site.in new file mode 100644 index 0000000000..7a1d739f72 --- /dev/null +++ b/headers/libs/libc++/__config_site.in @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CONFIG_SITE +#define _LIBCPP_CONFIG_SITE + +#cmakedefine _LIBCPP_ABI_VERSION @_LIBCPP_ABI_VERSION@ +#cmakedefine _LIBCPP_ABI_UNSTABLE +#cmakedefine _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +#cmakedefine _LIBCPP_HAS_NO_STDIN +#cmakedefine _LIBCPP_HAS_NO_STDOUT +#cmakedefine _LIBCPP_HAS_NO_THREADS +#cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK +#cmakedefine _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS + +#endif diff --git a/headers/libs/libc++/__debug b/headers/libs/libc++/__debug new file mode 100644 index 0000000000..a21f9a8988 --- /dev/null +++ b/headers/libs/libc++/__debug @@ -0,0 +1,222 @@ +// -*- C++ -*- +//===--------------------------- __debug ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_DEBUG_H +#define _LIBCPP_DEBUG_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#if _LIBCPP_DEBUG_LEVEL >= 1 +# include +# include +# include +# ifndef _LIBCPP_ASSERT +# define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (_VSTD::fprintf(stderr, "%s\n", m), _VSTD::abort())) +# endif +#endif + +#ifndef _LIBCPP_ASSERT +# define _LIBCPP_ASSERT(x, m) ((void)0) +#endif + +#if _LIBCPP_DEBUG_LEVEL >= 2 + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct _LIBCPP_TYPE_VIS __c_node; + +struct _LIBCPP_TYPE_VIS __i_node +{ + void* __i_; + __i_node* __next_; + __c_node* __c_; + +#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS + __i_node(const __i_node&) = delete; + __i_node& operator=(const __i_node&) = delete; +#else +private: + __i_node(const __i_node&); + __i_node& operator=(const __i_node&); +public: +#endif + _LIBCPP_INLINE_VISIBILITY + __i_node(void* __i, __i_node* __next, __c_node* __c) + : __i_(__i), __next_(__next), __c_(__c) {} + ~__i_node(); +}; + +struct _LIBCPP_TYPE_VIS __c_node +{ + void* __c_; + __c_node* __next_; + __i_node** beg_; + __i_node** end_; + __i_node** cap_; + +#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS + __c_node(const __c_node&) = delete; + __c_node& operator=(const __c_node&) = delete; +#else +private: + __c_node(const __c_node&); + __c_node& operator=(const __c_node&); +public: +#endif + _LIBCPP_INLINE_VISIBILITY + __c_node(void* __c, __c_node* __next) + : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {} + virtual ~__c_node(); + + virtual bool __dereferenceable(const void*) const = 0; + virtual bool __decrementable(const void*) const = 0; + virtual bool __addable(const void*, ptrdiff_t) const = 0; + virtual bool __subscriptable(const void*, ptrdiff_t) const = 0; + + void __add(__i_node* __i); + _LIBCPP_HIDDEN void __remove(__i_node* __i); +}; + +template +struct _C_node + : public __c_node +{ + _C_node(void* __c, __c_node* __n) + : __c_node(__c, __n) {} + + virtual bool __dereferenceable(const void*) const; + virtual bool __decrementable(const void*) const; + virtual bool __addable(const void*, ptrdiff_t) const; + virtual bool __subscriptable(const void*, ptrdiff_t) const; +}; + +template +bool +_C_node<_Cont>::__dereferenceable(const void* __i) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _Cp = static_cast<_Cont*>(__c_); + return _Cp->__dereferenceable(__j); +} + +template +bool +_C_node<_Cont>::__decrementable(const void* __i) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _Cp = static_cast<_Cont*>(__c_); + return _Cp->__decrementable(__j); +} + +template +bool +_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _Cp = static_cast<_Cont*>(__c_); + return _Cp->__addable(__j, __n); +} + +template +bool +_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _Cp = static_cast<_Cont*>(__c_); + return _Cp->__subscriptable(__j, __n); +} + +class _LIBCPP_TYPE_VIS __libcpp_db +{ + __c_node** __cbeg_; + __c_node** __cend_; + size_t __csz_; + __i_node** __ibeg_; + __i_node** __iend_; + size_t __isz_; + + __libcpp_db(); +public: +#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS + __libcpp_db(const __libcpp_db&) = delete; + __libcpp_db& operator=(const __libcpp_db&) = delete; +#else +private: + __libcpp_db(const __libcpp_db&); + __libcpp_db& operator=(const __libcpp_db&); +public: +#endif + ~__libcpp_db(); + + class __db_c_iterator; + class __db_c_const_iterator; + class __db_i_iterator; + class __db_i_const_iterator; + + __db_c_const_iterator __c_end() const; + __db_i_const_iterator __i_end() const; + + template + _LIBCPP_INLINE_VISIBILITY + void __insert_c(_Cont* __c) + { + __c_node* __n = __insert_c(static_cast(__c)); + ::new(__n) _C_node<_Cont>(__n->__c_, __n->__next_); + } + + void __insert_i(void* __i); + __c_node* __insert_c(void* __c); + void __erase_c(void* __c); + + void __insert_ic(void* __i, const void* __c); + void __iterator_copy(void* __i, const void* __i0); + void __erase_i(void* __i); + + void* __find_c_from_i(void* __i) const; + void __invalidate_all(void* __c); + __c_node* __find_c_and_lock(void* __c) const; + __c_node* __find_c(void* __c) const; + void unlock() const; + + void swap(void* __c1, void* __c2); + + + bool __dereferenceable(const void* __i) const; + bool __decrementable(const void* __i) const; + bool __addable(const void* __i, ptrdiff_t __n) const; + bool __subscriptable(const void* __i, ptrdiff_t __n) const; + bool __less_than_comparable(const void* __i, const void* __j) const; +private: + _LIBCPP_HIDDEN + __i_node* __insert_iterator(void* __i); + _LIBCPP_HIDDEN + __i_node* __find_iterator(const void* __i) const; + + friend _LIBCPP_FUNC_VIS __libcpp_db* __get_db(); +}; + +_LIBCPP_FUNC_VIS __libcpp_db* __get_db(); +_LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); + + +_LIBCPP_END_NAMESPACE_STD + +#endif + +#endif // _LIBCPP_DEBUG_H + diff --git a/headers/libs/libc++/__functional_03 b/headers/libs/libc++/__functional_03 new file mode 100644 index 0000000000..4edbb0996c --- /dev/null +++ b/headers/libs/libc++/__functional_03 @@ -0,0 +1,1576 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_FUNCTIONAL_03 +#define _LIBCPP_FUNCTIONAL_03 + +// manual variadic expansion for + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +namespace __function { + +template class __base; + +template +class __base<_Rp()> +{ + __base(const __base&); + __base& operator=(const __base&); +public: + __base() {} + virtual ~__base() {} + virtual __base* __clone() const = 0; + virtual void __clone(__base*) const = 0; + virtual void destroy() = 0; + virtual void destroy_deallocate() = 0; + virtual _Rp operator()() = 0; +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const = 0; + virtual const std::type_info& target_type() const = 0; +#endif // _LIBCPP_NO_RTTI +}; + +template +class __base<_Rp(_A0)> +{ + __base(const __base&); + __base& operator=(const __base&); +public: + __base() {} + virtual ~__base() {} + virtual __base* __clone() const = 0; + virtual void __clone(__base*) const = 0; + virtual void destroy() = 0; + virtual void destroy_deallocate() = 0; + virtual _Rp operator()(_A0) = 0; +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const = 0; + virtual const std::type_info& target_type() const = 0; +#endif // _LIBCPP_NO_RTTI +}; + +template +class __base<_Rp(_A0, _A1)> +{ + __base(const __base&); + __base& operator=(const __base&); +public: + __base() {} + virtual ~__base() {} + virtual __base* __clone() const = 0; + virtual void __clone(__base*) const = 0; + virtual void destroy() = 0; + virtual void destroy_deallocate() = 0; + virtual _Rp operator()(_A0, _A1) = 0; +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const = 0; + virtual const std::type_info& target_type() const = 0; +#endif // _LIBCPP_NO_RTTI +}; + +template +class __base<_Rp(_A0, _A1, _A2)> +{ + __base(const __base&); + __base& operator=(const __base&); +public: + __base() {} + virtual ~__base() {} + virtual __base* __clone() const = 0; + virtual void __clone(__base*) const = 0; + virtual void destroy() = 0; + virtual void destroy_deallocate() = 0; + virtual _Rp operator()(_A0, _A1, _A2) = 0; +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const = 0; + virtual const std::type_info& target_type() const = 0; +#endif // _LIBCPP_NO_RTTI +}; + +template class __func; + +template +class __func<_Fp, _Alloc, _Rp()> + : public __base<_Rp()> +{ + __compressed_pair<_Fp, _Alloc> __f_; +public: + explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} + explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} + virtual __base<_Rp()>* __clone() const; + virtual void __clone(__base<_Rp()>*) const; + virtual void destroy(); + virtual void destroy_deallocate(); + virtual _Rp operator()(); +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const; + virtual const std::type_info& target_type() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +__base<_Rp()>* +__func<_Fp, _Alloc, _Rp()>::__clone() const +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); + return __hold.release(); +} + +template +void +__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const +{ + ::new (__p) __func(__f_.first(), __f_.second()); +} + +template +void +__func<_Fp, _Alloc, _Rp()>::destroy() +{ + __f_.~__compressed_pair<_Fp, _Alloc>(); +} + +template +void +__func<_Fp, _Alloc, _Rp()>::destroy_deallocate() +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + __f_.~__compressed_pair<_Fp, _Alloc>(); + __a.deallocate(this, 1); +} + +template +_Rp +__func<_Fp, _Alloc, _Rp()>::operator()() +{ + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first()); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const void* +__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const +{ + if (__ti == typeid(_Fp)) + return &__f_.first(); + return (const void*)0; +} + +template +const std::type_info& +__func<_Fp, _Alloc, _Rp()>::target_type() const +{ + return typeid(_Fp); +} + +#endif // _LIBCPP_NO_RTTI + +template +class __func<_Fp, _Alloc, _Rp(_A0)> + : public __base<_Rp(_A0)> +{ + __compressed_pair<_Fp, _Alloc> __f_; +public: + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) + : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} + virtual __base<_Rp(_A0)>* __clone() const; + virtual void __clone(__base<_Rp(_A0)>*) const; + virtual void destroy(); + virtual void destroy_deallocate(); + virtual _Rp operator()(_A0); +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const; + virtual const std::type_info& target_type() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +__base<_Rp(_A0)>* +__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); + return __hold.release(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const +{ + ::new (__p) __func(__f_.first(), __f_.second()); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0)>::destroy() +{ + __f_.~__compressed_pair<_Fp, _Alloc>(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate() +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + __f_.~__compressed_pair<_Fp, _Alloc>(); + __a.deallocate(this, 1); +} + +template +_Rp +__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0) +{ + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first(), __a0); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const void* +__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const +{ + if (__ti == typeid(_Fp)) + return &__f_.first(); + return (const void*)0; +} + +template +const std::type_info& +__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const +{ + return typeid(_Fp); +} + +#endif // _LIBCPP_NO_RTTI + +template +class __func<_Fp, _Alloc, _Rp(_A0, _A1)> + : public __base<_Rp(_A0, _A1)> +{ + __compressed_pair<_Fp, _Alloc> __f_; +public: + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) + : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} + virtual __base<_Rp(_A0, _A1)>* __clone() const; + virtual void __clone(__base<_Rp(_A0, _A1)>*) const; + virtual void destroy(); + virtual void destroy_deallocate(); + virtual _Rp operator()(_A0, _A1); +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const; + virtual const std::type_info& target_type() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +__base<_Rp(_A0, _A1)>* +__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); + return __hold.release(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const +{ + ::new (__p) __func(__f_.first(), __f_.second()); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy() +{ + __f_.~__compressed_pair<_Fp, _Alloc>(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate() +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + __f_.~__compressed_pair<_Fp, _Alloc>(); + __a.deallocate(this, 1); +} + +template +_Rp +__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) +{ + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first(), __a0, __a1); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const void* +__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const +{ + if (__ti == typeid(_Fp)) + return &__f_.first(); + return (const void*)0; +} + +template +const std::type_info& +__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const +{ + return typeid(_Fp); +} + +#endif // _LIBCPP_NO_RTTI + +template +class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> + : public __base<_Rp(_A0, _A1, _A2)> +{ + __compressed_pair<_Fp, _Alloc> __f_; +public: + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) + : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} + virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const; + virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const; + virtual void destroy(); + virtual void destroy_deallocate(); + virtual _Rp operator()(_A0, _A1, _A2); +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const; + virtual const std::type_info& target_type() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +__base<_Rp(_A0, _A1, _A2)>* +__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); + return __hold.release(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const +{ + ::new (__p) __func(__f_.first(), __f_.second()); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy() +{ + __f_.~__compressed_pair<_Fp, _Alloc>(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate() +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + __f_.~__compressed_pair<_Fp, _Alloc>(); + __a.deallocate(this, 1); +} + +template +_Rp +__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) +{ + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first(), __a0, __a1, __a2); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const void* +__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const +{ + if (__ti == typeid(_Fp)) + return &__f_.first(); + return (const void*)0; +} + +template +const std::type_info& +__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const +{ + return typeid(_Fp); +} + +#endif // _LIBCPP_NO_RTTI + +} // __function + +template +class _LIBCPP_TYPE_VIS_ONLY function<_Rp()> +{ + typedef __function::__base<_Rp()> __base; + aligned_storage<3*sizeof(void*)>::type __buf_; + __base* __f_; + +public: + typedef _Rp result_type; + + // 20.7.16.2.1, construct/copy/destroy: + _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} + _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} + function(const function&); + template + function(_Fp, + typename enable_if::value>::type* = 0); + + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&) : __f_(0) {} + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} + template + function(allocator_arg_t, const _Alloc&, const function&); + template + function(allocator_arg_t, const _Alloc& __a, _Fp __f, + typename enable_if::value>::type* = 0); + + function& operator=(const function&); + function& operator=(nullptr_t); + template + typename enable_if + < + !is_integral<_Fp>::value, + function& + >::type + operator=(_Fp); + + ~function(); + + // 20.7.16.2.2, function modifiers: + void swap(function&); + template + _LIBCPP_INLINE_VISIBILITY + void assign(_Fp __f, const _Alloc& __a) + {function(allocator_arg, __a, __f).swap(*this);} + + // 20.7.16.2.3, function capacity: + _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} + +private: + // deleted overloads close possible hole in the type system + template + bool operator==(const function<_R2()>&) const;// = delete; + template + bool operator!=(const function<_R2()>&) const;// = delete; +public: + // 20.7.16.2.4, function invocation: + _Rp operator()() const; + +#ifndef _LIBCPP_NO_RTTI + // 20.7.16.2.5, function target access: + const std::type_info& target_type() const; + template _Tp* target(); + template const _Tp* target() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +function<_Rp()>::function(const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp()>::function(_Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new (__f_) _FF(__f); + } + else + { + typedef allocator<_FF> _Ap; + _Ap __a; + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); + __f_ = __hold.release(); + } + } +} + +template +template +function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + typedef allocator_traits<_Alloc> __alloc_traits; + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, _Alloc, _Rp()> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new (__f_) _FF(__f, __a0); + } + else + { + typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; + _Ap __a(__a0); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) _FF(__f, _Alloc(__a)); + __f_ = __hold.release(); + } + } +} + +template +function<_Rp()>& +function<_Rp()>::operator=(const function& __f) +{ + function(__f).swap(*this); + return *this; +} + +template +function<_Rp()>& +function<_Rp()>::operator=(nullptr_t) +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); + __f_ = 0; + return *this; +} + +template +template +typename enable_if +< + !is_integral<_Fp>::value, + function<_Rp()>& +>::type +function<_Rp()>::operator=(_Fp __f) +{ + function(_VSTD::move(__f)).swap(*this); + return *this; +} + +template +function<_Rp()>::~function() +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); +} + +template +void +function<_Rp()>::swap(function& __f) +{ + if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) + { + typename aligned_storage::type __tempbuf; + __base* __t = (__base*)&__tempbuf; + __f_->__clone(__t); + __f_->destroy(); + __f_ = 0; + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = 0; + __f_ = (__base*)&__buf_; + __t->__clone((__base*)&__f.__buf_); + __t->destroy(); + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f_ == (__base*)&__buf_) + { + __f_->__clone((__base*)&__f.__buf_); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = (__base*)&__buf_; + } + else + _VSTD::swap(__f_, __f.__f_); +} + +template +_Rp +function<_Rp()>::operator()() const +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + if (__f_ == 0) + throw bad_function_call(); +#endif // _LIBCPP_NO_EXCEPTIONS + return (*__f_)(); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const std::type_info& +function<_Rp()>::target_type() const +{ + if (__f_ == 0) + return typeid(void); + return __f_->target_type(); +} + +template +template +_Tp* +function<_Rp()>::target() +{ + if (__f_ == 0) + return (_Tp*)0; + return (_Tp*)__f_->target(typeid(_Tp)); +} + +template +template +const _Tp* +function<_Rp()>::target() const +{ + if (__f_ == 0) + return (const _Tp*)0; + return (const _Tp*)__f_->target(typeid(_Tp)); +} + +#endif // _LIBCPP_NO_RTTI + +template +class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0)> + : public unary_function<_A0, _Rp> +{ + typedef __function::__base<_Rp(_A0)> __base; + aligned_storage<3*sizeof(void*)>::type __buf_; + __base* __f_; + +public: + typedef _Rp result_type; + + // 20.7.16.2.1, construct/copy/destroy: + _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} + _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} + function(const function&); + template + function(_Fp, + typename enable_if::value>::type* = 0); + + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&) : __f_(0) {} + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} + template + function(allocator_arg_t, const _Alloc&, const function&); + template + function(allocator_arg_t, const _Alloc& __a, _Fp __f, + typename enable_if::value>::type* = 0); + + function& operator=(const function&); + function& operator=(nullptr_t); + template + typename enable_if + < + !is_integral<_Fp>::value, + function& + >::type + operator=(_Fp); + + ~function(); + + // 20.7.16.2.2, function modifiers: + void swap(function&); + template + _LIBCPP_INLINE_VISIBILITY + void assign(_Fp __f, const _Alloc& __a) + {function(allocator_arg, __a, __f).swap(*this);} + + // 20.7.16.2.3, function capacity: + _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} + +private: + // deleted overloads close possible hole in the type system + template + bool operator==(const function<_R2(_B0)>&) const;// = delete; + template + bool operator!=(const function<_R2(_B0)>&) const;// = delete; +public: + // 20.7.16.2.4, function invocation: + _Rp operator()(_A0) const; + +#ifndef _LIBCPP_NO_RTTI + // 20.7.16.2.5, function target access: + const std::type_info& target_type() const; + template _Tp* target(); + template const _Tp* target() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +function<_Rp(_A0)>::function(const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp(_A0)>::function(_Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new (__f_) _FF(__f); + } + else + { + typedef allocator<_FF> _Ap; + _Ap __a; + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); + __f_ = __hold.release(); + } + } +} + +template +template +function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + typedef allocator_traits<_Alloc> __alloc_traits; + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new (__f_) _FF(__f, __a0); + } + else + { + typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; + _Ap __a(__a0); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) _FF(__f, _Alloc(__a)); + __f_ = __hold.release(); + } + } +} + +template +function<_Rp(_A0)>& +function<_Rp(_A0)>::operator=(const function& __f) +{ + function(__f).swap(*this); + return *this; +} + +template +function<_Rp(_A0)>& +function<_Rp(_A0)>::operator=(nullptr_t) +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); + __f_ = 0; + return *this; +} + +template +template +typename enable_if +< + !is_integral<_Fp>::value, + function<_Rp(_A0)>& +>::type +function<_Rp(_A0)>::operator=(_Fp __f) +{ + function(_VSTD::move(__f)).swap(*this); + return *this; +} + +template +function<_Rp(_A0)>::~function() +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); +} + +template +void +function<_Rp(_A0)>::swap(function& __f) +{ + if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) + { + typename aligned_storage::type __tempbuf; + __base* __t = (__base*)&__tempbuf; + __f_->__clone(__t); + __f_->destroy(); + __f_ = 0; + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = 0; + __f_ = (__base*)&__buf_; + __t->__clone((__base*)&__f.__buf_); + __t->destroy(); + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f_ == (__base*)&__buf_) + { + __f_->__clone((__base*)&__f.__buf_); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = (__base*)&__buf_; + } + else + _VSTD::swap(__f_, __f.__f_); +} + +template +_Rp +function<_Rp(_A0)>::operator()(_A0 __a0) const +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + if (__f_ == 0) + throw bad_function_call(); +#endif // _LIBCPP_NO_EXCEPTIONS + return (*__f_)(__a0); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const std::type_info& +function<_Rp(_A0)>::target_type() const +{ + if (__f_ == 0) + return typeid(void); + return __f_->target_type(); +} + +template +template +_Tp* +function<_Rp(_A0)>::target() +{ + if (__f_ == 0) + return (_Tp*)0; + return (_Tp*)__f_->target(typeid(_Tp)); +} + +template +template +const _Tp* +function<_Rp(_A0)>::target() const +{ + if (__f_ == 0) + return (const _Tp*)0; + return (const _Tp*)__f_->target(typeid(_Tp)); +} + +#endif // _LIBCPP_NO_RTTI + +template +class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1)> + : public binary_function<_A0, _A1, _Rp> +{ + typedef __function::__base<_Rp(_A0, _A1)> __base; + aligned_storage<3*sizeof(void*)>::type __buf_; + __base* __f_; + +public: + typedef _Rp result_type; + + // 20.7.16.2.1, construct/copy/destroy: + _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} + _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} + function(const function&); + template + function(_Fp, + typename enable_if::value>::type* = 0); + + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&) : __f_(0) {} + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} + template + function(allocator_arg_t, const _Alloc&, const function&); + template + function(allocator_arg_t, const _Alloc& __a, _Fp __f, + typename enable_if::value>::type* = 0); + + function& operator=(const function&); + function& operator=(nullptr_t); + template + typename enable_if + < + !is_integral<_Fp>::value, + function& + >::type + operator=(_Fp); + + ~function(); + + // 20.7.16.2.2, function modifiers: + void swap(function&); + template + _LIBCPP_INLINE_VISIBILITY + void assign(_Fp __f, const _Alloc& __a) + {function(allocator_arg, __a, __f).swap(*this);} + + // 20.7.16.2.3, function capacity: + operator bool() const {return __f_;} + +private: + // deleted overloads close possible hole in the type system + template + bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete; + template + bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete; +public: + // 20.7.16.2.4, function invocation: + _Rp operator()(_A0, _A1) const; + +#ifndef _LIBCPP_NO_RTTI + // 20.7.16.2.5, function target access: + const std::type_info& target_type() const; + template _Tp* target(); + template const _Tp* target() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +function<_Rp(_A0, _A1)>::function(const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp(_A0, _A1)>::function(_Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new (__f_) _FF(__f); + } + else + { + typedef allocator<_FF> _Ap; + _Ap __a; + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); + __f_ = __hold.release(); + } + } +} + +template +template +function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + typedef allocator_traits<_Alloc> __alloc_traits; + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new (__f_) _FF(__f, __a0); + } + else + { + typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; + _Ap __a(__a0); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) _FF(__f, _Alloc(__a)); + __f_ = __hold.release(); + } + } +} + +template +function<_Rp(_A0, _A1)>& +function<_Rp(_A0, _A1)>::operator=(const function& __f) +{ + function(__f).swap(*this); + return *this; +} + +template +function<_Rp(_A0, _A1)>& +function<_Rp(_A0, _A1)>::operator=(nullptr_t) +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); + __f_ = 0; + return *this; +} + +template +template +typename enable_if +< + !is_integral<_Fp>::value, + function<_Rp(_A0, _A1)>& +>::type +function<_Rp(_A0, _A1)>::operator=(_Fp __f) +{ + function(_VSTD::move(__f)).swap(*this); + return *this; +} + +template +function<_Rp(_A0, _A1)>::~function() +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); +} + +template +void +function<_Rp(_A0, _A1)>::swap(function& __f) +{ + if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) + { + typename aligned_storage::type __tempbuf; + __base* __t = (__base*)&__tempbuf; + __f_->__clone(__t); + __f_->destroy(); + __f_ = 0; + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = 0; + __f_ = (__base*)&__buf_; + __t->__clone((__base*)&__f.__buf_); + __t->destroy(); + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f_ == (__base*)&__buf_) + { + __f_->__clone((__base*)&__f.__buf_); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = (__base*)&__buf_; + } + else + _VSTD::swap(__f_, __f.__f_); +} + +template +_Rp +function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + if (__f_ == 0) + throw bad_function_call(); +#endif // _LIBCPP_NO_EXCEPTIONS + return (*__f_)(__a0, __a1); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const std::type_info& +function<_Rp(_A0, _A1)>::target_type() const +{ + if (__f_ == 0) + return typeid(void); + return __f_->target_type(); +} + +template +template +_Tp* +function<_Rp(_A0, _A1)>::target() +{ + if (__f_ == 0) + return (_Tp*)0; + return (_Tp*)__f_->target(typeid(_Tp)); +} + +template +template +const _Tp* +function<_Rp(_A0, _A1)>::target() const +{ + if (__f_ == 0) + return (const _Tp*)0; + return (const _Tp*)__f_->target(typeid(_Tp)); +} + +#endif // _LIBCPP_NO_RTTI + +template +class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1, _A2)> +{ + typedef __function::__base<_Rp(_A0, _A1, _A2)> __base; + aligned_storage<3*sizeof(void*)>::type __buf_; + __base* __f_; + +public: + typedef _Rp result_type; + + // 20.7.16.2.1, construct/copy/destroy: + _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} + _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} + function(const function&); + template + function(_Fp, + typename enable_if::value>::type* = 0); + + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&) : __f_(0) {} + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} + template + function(allocator_arg_t, const _Alloc&, const function&); + template + function(allocator_arg_t, const _Alloc& __a, _Fp __f, + typename enable_if::value>::type* = 0); + + function& operator=(const function&); + function& operator=(nullptr_t); + template + typename enable_if + < + !is_integral<_Fp>::value, + function& + >::type + operator=(_Fp); + + ~function(); + + // 20.7.16.2.2, function modifiers: + void swap(function&); + template + _LIBCPP_INLINE_VISIBILITY + void assign(_Fp __f, const _Alloc& __a) + {function(allocator_arg, __a, __f).swap(*this);} + + // 20.7.16.2.3, function capacity: + _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} + +private: + // deleted overloads close possible hole in the type system + template + bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete; + template + bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete; +public: + // 20.7.16.2.4, function invocation: + _Rp operator()(_A0, _A1, _A2) const; + +#ifndef _LIBCPP_NO_RTTI + // 20.7.16.2.5, function target access: + const std::type_info& target_type() const; + template _Tp* target(); + template const _Tp* target() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +function<_Rp(_A0, _A1, _A2)>::function(const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&, + const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp(_A0, _A1, _A2)>::function(_Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new (__f_) _FF(__f); + } + else + { + typedef allocator<_FF> _Ap; + _Ap __a; + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); + __f_ = __hold.release(); + } + } +} + +template +template +function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + typedef allocator_traits<_Alloc> __alloc_traits; + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new (__f_) _FF(__f, __a0); + } + else + { + typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; + _Ap __a(__a0); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) _FF(__f, _Alloc(__a)); + __f_ = __hold.release(); + } + } +} + +template +function<_Rp(_A0, _A1, _A2)>& +function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f) +{ + function(__f).swap(*this); + return *this; +} + +template +function<_Rp(_A0, _A1, _A2)>& +function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t) +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); + __f_ = 0; + return *this; +} + +template +template +typename enable_if +< + !is_integral<_Fp>::value, + function<_Rp(_A0, _A1, _A2)>& +>::type +function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f) +{ + function(_VSTD::move(__f)).swap(*this); + return *this; +} + +template +function<_Rp(_A0, _A1, _A2)>::~function() +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); +} + +template +void +function<_Rp(_A0, _A1, _A2)>::swap(function& __f) +{ + if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) + { + typename aligned_storage::type __tempbuf; + __base* __t = (__base*)&__tempbuf; + __f_->__clone(__t); + __f_->destroy(); + __f_ = 0; + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = 0; + __f_ = (__base*)&__buf_; + __t->__clone((__base*)&__f.__buf_); + __t->destroy(); + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f_ == (__base*)&__buf_) + { + __f_->__clone((__base*)&__f.__buf_); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = (__base*)&__buf_; + } + else + _VSTD::swap(__f_, __f.__f_); +} + +template +_Rp +function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + if (__f_ == 0) + throw bad_function_call(); +#endif // _LIBCPP_NO_EXCEPTIONS + return (*__f_)(__a0, __a1, __a2); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const std::type_info& +function<_Rp(_A0, _A1, _A2)>::target_type() const +{ + if (__f_ == 0) + return typeid(void); + return __f_->target_type(); +} + +template +template +_Tp* +function<_Rp(_A0, _A1, _A2)>::target() +{ + if (__f_ == 0) + return (_Tp*)0; + return (_Tp*)__f_->target(typeid(_Tp)); +} + +template +template +const _Tp* +function<_Rp(_A0, _A1, _A2)>::target() const +{ + if (__f_ == 0) + return (const _Tp*)0; + return (const _Tp*)__f_->target(typeid(_Tp)); +} + +#endif // _LIBCPP_NO_RTTI + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const function<_Fp>& __f, nullptr_t) {return !__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(nullptr_t, const function<_Fp>& __f) {return !__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(function<_Fp>& __x, function<_Fp>& __y) +{return __x.swap(__y);} + +#endif // _LIBCPP_FUNCTIONAL_03 diff --git a/headers/libs/libc++/__functional_base b/headers/libs/libc++/__functional_base new file mode 100644 index 0000000000..ef9cc03235 --- /dev/null +++ b/headers/libs/libc++/__functional_base @@ -0,0 +1,793 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_FUNCTIONAL_BASE +#define _LIBCPP_FUNCTIONAL_BASE + +#include <__config> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TYPE_VIS_ONLY unary_function +{ + typedef _Arg argument_type; + typedef _Result result_type; +}; + +template +struct _LIBCPP_TYPE_VIS_ONLY binary_function +{ + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; +}; + +template struct _LIBCPP_TYPE_VIS_ONLY hash; + +template +struct __has_result_type +{ +private: + struct __two {char __lx; char __lxx;}; + template static __two __test(...); + template static char __test(typename _Up::result_type* = 0); +public: + static const bool value = sizeof(__test<_Tp>(0)) == 1; +}; + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY less : binary_function<_Tp, _Tp, bool> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x < __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY less +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +// addressof + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp* +addressof(_Tp& __x) _NOEXCEPT +{ + return (_Tp*)&reinterpret_cast(__x); +} + +#if defined(_LIBCPP_HAS_OBJC_ARC) && !defined(_LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF) +// Objective-C++ Automatic Reference Counting uses qualified pointers +// that require special addressof() signatures. When +// _LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF is defined, the compiler +// itself is providing these definitions. Otherwise, we provide them. +template +inline _LIBCPP_INLINE_VISIBILITY +__strong _Tp* +addressof(__strong _Tp& __x) _NOEXCEPT +{ + return &__x; +} + +#ifdef _LIBCPP_HAS_OBJC_ARC_WEAK +template +inline _LIBCPP_INLINE_VISIBILITY +__weak _Tp* +addressof(__weak _Tp& __x) _NOEXCEPT +{ + return &__x; +} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +__autoreleasing _Tp* +addressof(__autoreleasing _Tp& __x) _NOEXCEPT +{ + return &__x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__unsafe_unretained _Tp* +addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT +{ + return &__x; +} +#endif + + +// __weak_result_type + +template +struct __derives_from_unary_function +{ +private: + struct __two {char __lx; char __lxx;}; + static __two __test(...); + template + static unary_function<_Ap, _Rp> + __test(const volatile unary_function<_Ap, _Rp>*); +public: + static const bool value = !is_same::value; + typedef decltype(__test((_Tp*)0)) type; +}; + +template +struct __derives_from_binary_function +{ +private: + struct __two {char __lx; char __lxx;}; + static __two __test(...); + template + static binary_function<_A1, _A2, _Rp> + __test(const volatile binary_function<_A1, _A2, _Rp>*); +public: + static const bool value = !is_same::value; + typedef decltype(__test((_Tp*)0)) type; +}; + +template ::value> +struct __maybe_derive_from_unary_function // bool is true + : public __derives_from_unary_function<_Tp>::type +{ +}; + +template +struct __maybe_derive_from_unary_function<_Tp, false> +{ +}; + +template ::value> +struct __maybe_derive_from_binary_function // bool is true + : public __derives_from_binary_function<_Tp>::type +{ +}; + +template +struct __maybe_derive_from_binary_function<_Tp, false> +{ +}; + +template ::value> +struct __weak_result_type_imp // bool is true + : public __maybe_derive_from_unary_function<_Tp>, + public __maybe_derive_from_binary_function<_Tp> +{ + typedef typename _Tp::result_type result_type; +}; + +template +struct __weak_result_type_imp<_Tp, false> + : public __maybe_derive_from_unary_function<_Tp>, + public __maybe_derive_from_binary_function<_Tp> +{ +}; + +template +struct __weak_result_type + : public __weak_result_type_imp<_Tp> +{ +}; + +// 0 argument case + +template +struct __weak_result_type<_Rp ()> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (&)()> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (*)()> +{ + typedef _Rp result_type; +}; + +// 1 argument case + +template +struct __weak_result_type<_Rp (_A1)> + : public unary_function<_A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (&)(_A1)> + : public unary_function<_A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (*)(_A1)> + : public unary_function<_A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)()> + : public unary_function<_Cp*, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)() const> + : public unary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)() volatile> + : public unary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)() const volatile> + : public unary_function +{ +}; + +// 2 argument case + +template +struct __weak_result_type<_Rp (_A1, _A2)> + : public binary_function<_A1, _A2, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (*)(_A1, _A2)> + : public binary_function<_A1, _A2, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (&)(_A1, _A2)> + : public binary_function<_A1, _A2, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1)> + : public binary_function<_Cp*, _A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1) const> + : public binary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> + : public binary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> + : public binary_function +{ +}; + + +#ifndef _LIBCPP_HAS_NO_VARIADICS +// 3 or more arguments + +template +struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> +{ + typedef _Rp result_type; +}; + +#endif // _LIBCPP_HAS_NO_VARIADICS + +// __invoke + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +// bullets 1 and 2 + +template +inline _LIBCPP_INLINE_VISIBILITY +auto +__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) + -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)) +{ + return (_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto +__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) + -> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...)) +{ + return ((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...); +} + +// bullets 3 and 4 + +template +inline _LIBCPP_INLINE_VISIBILITY +auto +__invoke(_Fp&& __f, _A0&& __a0) + -> decltype(_VSTD::forward<_A0>(__a0).*__f) +{ + return _VSTD::forward<_A0>(__a0).*__f; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto +__invoke(_Fp&& __f, _A0&& __a0) + -> decltype((*_VSTD::forward<_A0>(__a0)).*__f) +{ + return (*_VSTD::forward<_A0>(__a0)).*__f; +} + +// bullet 5 + +template +inline _LIBCPP_INLINE_VISIBILITY +auto +__invoke(_Fp&& __f, _Args&& ...__args) + -> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)) +{ + return _VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...); +} +template +struct __invoke_return +{ + typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type; +}; + +#else // _LIBCPP_HAS_NO_VARIADICS + +#include <__functional_base_03> + +#endif // _LIBCPP_HAS_NO_VARIADICS + + +template +struct __invoke_void_return_wrapper +{ +#ifndef _LIBCPP_HAS_NO_VARIADICS + template + static _Ret __call(_Args&&... __args) { + return __invoke(_VSTD::forward<_Args>(__args)...); + } +#else + template + static _Ret __call(_Fn __f) { + return __invoke(__f); + } + + template + static _Ret __call(_Fn __f, _A0& __a0) { + return __invoke(__f, __a0); + } + + template + static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) { + return __invoke(__f, __a0, __a1); + } + + template + static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){ + return __invoke(__f, __a0, __a1, __a2); + } +#endif +}; + +template <> +struct __invoke_void_return_wrapper +{ +#ifndef _LIBCPP_HAS_NO_VARIADICS + template + static void __call(_Args&&... __args) { + __invoke(_VSTD::forward<_Args>(__args)...); + } +#else + template + static void __call(_Fn __f) { + __invoke(__f); + } + + template + static void __call(_Fn __f, _A0& __a0) { + __invoke(__f, __a0); + } + + template + static void __call(_Fn __f, _A0& __a0, _A1& __a1) { + __invoke(__f, __a0, __a1); + } + + template + static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) { + __invoke(__f, __a0, __a1, __a2); + } +#endif +}; + +template +class _LIBCPP_TYPE_VIS_ONLY reference_wrapper + : public __weak_result_type<_Tp> +{ +public: + // types + typedef _Tp type; +private: + type* __f_; + +public: + // construct/copy/destroy + _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT + : __f_(_VSTD::addressof(__f)) {} +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + private: reference_wrapper(type&&); public: // = delete; // do not bind to temps +#endif + + // access + _LIBCPP_INLINE_VISIBILITY operator type& () const _NOEXCEPT {return *__f_;} + _LIBCPP_INLINE_VISIBILITY type& get() const _NOEXCEPT {return *__f_;} + +#ifndef _LIBCPP_HAS_NO_VARIADICS + // invoke + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_of::type + operator() (_ArgTypes&&... __args) const { + return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...); + } +#else + + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return::type + operator() () const { + return __invoke(get()); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return0::type + operator() (_A0& __a0) const { + return __invoke(get(), __a0); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return0::type + operator() (_A0 const& __a0) const { + return __invoke(get(), __a0); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0& __a0, _A1& __a1) const { + return __invoke(get(), __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0 const& __a0, _A1& __a1) const { + return __invoke(get(), __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0& __a0, _A1 const& __a1) const { + return __invoke(get(), __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0 const& __a0, _A1 const& __a1) const { + return __invoke(get(), __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1& __a1, _A2& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const { + return __invoke(get(), __a0, __a1, __a2); + } +#endif // _LIBCPP_HAS_NO_VARIADICS +}; + +template struct __is_reference_wrapper_impl : public false_type {}; +template struct __is_reference_wrapper_impl > : public true_type {}; +template struct __is_reference_wrapper + : public __is_reference_wrapper_impl::type> {}; + +template +inline _LIBCPP_INLINE_VISIBILITY +reference_wrapper<_Tp> +ref(_Tp& __t) _NOEXCEPT +{ + return reference_wrapper<_Tp>(__t); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +reference_wrapper<_Tp> +ref(reference_wrapper<_Tp> __t) _NOEXCEPT +{ + return ref(__t.get()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +reference_wrapper +cref(const _Tp& __t) _NOEXCEPT +{ + return reference_wrapper(__t); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +reference_wrapper +cref(reference_wrapper<_Tp> __t) _NOEXCEPT +{ + return cref(__t.get()); +} + +#ifndef _LIBCPP_HAS_NO_VARIADICS +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS + +template void ref(const _Tp&&) = delete; +template void cref(const _Tp&&) = delete; + +#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS + +template void ref(const _Tp&&);// = delete; +template void cref(const _Tp&&);// = delete; + +#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +#endif // _LIBCPP_HAS_NO_VARIADICS + +#if _LIBCPP_STD_VER > 11 +template +struct __is_transparent +{ +private: + struct __two {char __lx; char __lxx;}; + template static __two __test(...); + template static char __test(typename _Up::is_transparent* = 0); +public: + static const bool value = sizeof(__test<_Tp1>(0)) == 1; +}; +#endif + +// allocator_arg_t + +struct _LIBCPP_TYPE_VIS_ONLY allocator_arg_t { }; + +#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MEMORY) +extern const allocator_arg_t allocator_arg; +#else +constexpr allocator_arg_t allocator_arg = allocator_arg_t(); +#endif + +// uses_allocator + +template +struct __has_allocator_type +{ +private: + struct __two {char __lx; char __lxx;}; + template static __two __test(...); + template static char __test(typename _Up::allocator_type* = 0); +public: + static const bool value = sizeof(__test<_Tp>(0)) == 1; +}; + +template ::value> +struct __uses_allocator + : public integral_constant::value> +{ +}; + +template +struct __uses_allocator<_Tp, _Alloc, false> + : public false_type +{ +}; + +template +struct _LIBCPP_TYPE_VIS_ONLY uses_allocator + : public __uses_allocator<_Tp, _Alloc> +{ +}; + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +// allocator construction + +template +struct __uses_alloc_ctor_imp +{ + static const bool __ua = uses_allocator<_Tp, _Alloc>::value; + static const bool __ic = + is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value; + static const int value = __ua ? 2 - __ic : 0; +}; + +template +struct __uses_alloc_ctor + : integral_constant::value> + {}; + +template +inline _LIBCPP_INLINE_VISIBILITY +void __user_alloc_construct_impl (integral_constant, _Tp *__storage, const _Allocator &, _Args &&... __args ) +{ + new (__storage) _Tp (_VSTD::forward<_Args>(__args)...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void __user_alloc_construct_impl (integral_constant, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) +{ + new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void __user_alloc_construct_impl (integral_constant, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) +{ + new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void __user_alloc_construct (_Tp *__storage, const _Allocator &__a, _Args &&... __args) +{ + __user_alloc_construct_impl( + __uses_alloc_ctor<_Tp, _Allocator>(), + __storage, __a, _VSTD::forward<_Args>(__args)... + ); +} +#endif // _LIBCPP_HAS_NO_VARIADICS + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_FUNCTIONAL_BASE diff --git a/headers/libs/libc++/__functional_base_03 b/headers/libs/libc++/__functional_base_03 new file mode 100644 index 0000000000..8407dcfa39 --- /dev/null +++ b/headers/libs/libc++/__functional_base_03 @@ -0,0 +1,224 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_FUNCTIONAL_BASE_03 +#define _LIBCPP_FUNCTIONAL_BASE_03 + +// manual variadic expansion for + +// __invoke + +template +struct __enable_invoke_imp; + +template +struct __enable_invoke_imp<_Ret, _T1, true, true> { + typedef _Ret _Bullet1; + typedef _Bullet1 type; +}; + +template +struct __enable_invoke_imp<_Ret, _T1, true, false> { + typedef _Ret _Bullet2; + typedef _Bullet2 type; +}; + +template +struct __enable_invoke_imp<_Ret, _T1, false, true> { + typedef typename add_lvalue_reference< + typename __apply_cv<_T1, _Ret>::type + >::type _Bullet3; + typedef _Bullet3 type; +}; + +template +struct __enable_invoke_imp<_Ret, _T1, false, false> { + typedef typename add_lvalue_reference< + typename __apply_cv()), _Ret>::type + >::type _Bullet4; + typedef _Bullet4 type; +}; + +template +struct __enable_invoke_imp<_Ret, _T1*, false, false> { + typedef typename add_lvalue_reference< + typename __apply_cv<_T1, _Ret>::type + >::type _Bullet4; + typedef _Bullet4 type; +}; + +template , + class _Ret = typename _Traits::_ReturnType, + class _Class = typename _Traits::_ClassType> +struct __enable_invoke : __enable_invoke_imp< + _Ret, _T1, + is_member_function_pointer<_Fn>::value, + is_base_of<_Class, typename remove_reference<_T1>::type>::value> +{ +}; + +__nat __invoke(__any, ...); + +// first bullet + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet1 +__invoke(_Fn __f, _T1& __t1) { + return (__t1.*__f)(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet1 +__invoke(_Fn __f, _T1& __t1, _A0& __a0) { + return (__t1.*__f)(__a0); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet1 +__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { + return (__t1.*__f)(__a0, __a1); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet1 +__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) { + return (__t1.*__f)(__a0, __a1, __a2); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet2 +__invoke(_Fn __f, _T1& __t1) { + return ((*__t1).*__f)(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet2 +__invoke(_Fn __f, _T1& __t1, _A0& __a0) { + return ((*__t1).*__f)(__a0); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet2 +__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { + return ((*__t1).*__f)(__a0, __a1); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet2 +__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) { + return ((*__t1).*__f)(__a0, __a1, __a2); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet3 +__invoke(_Fn __f, _T1& __t1) { + return __t1.*__f; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet4 +__invoke(_Fn __f, _T1& __t1) { + return (*__t1).*__f; +} + +// fifth bullet + +template +inline _LIBCPP_INLINE_VISIBILITY +decltype(_VSTD::declval<_Fp&>()()) +__invoke(_Fp& __f) +{ + return __f(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>())) +__invoke(_Fp& __f, _A0& __a0) +{ + return __f(__a0); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>())) +__invoke(_Fp& __f, _A0& __a0, _A1& __a1) +{ + return __f(__a0, __a1); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>(), _VSTD::declval<_A2&>())) +__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2) +{ + return __f(__a0, __a1, __a2); +} + +template >::value> +struct __invoke_return +{ + typedef typename __weak_result_type<_Fp>::result_type type; +}; + +template +struct __invoke_return<_Fp, false> +{ + typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type; +}; + +template +struct __invoke_return0 +{ + typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type; +}; + +template +struct __invoke_return0<_Rp _Tp::*, _A0> +{ + typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type; +}; + +template +struct __invoke_return1 +{ + typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), + _VSTD::declval<_A1&>())) type; +}; + +template +struct __invoke_return1<_Rp _Class::*, _A0, _A1> { + typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type; +}; + +template +struct __invoke_return2 +{ + typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), + _VSTD::declval<_A1&>(), + _VSTD::declval<_A2&>())) type; +}; + +template +struct __invoke_return2<_Ret _Class::*, _A0, _A1, _A2> { + typedef typename __enable_invoke<_Ret _Class::*, _A0>::type type; +}; +#endif // _LIBCPP_FUNCTIONAL_BASE_03 diff --git a/headers/libs/libc++/__hash_table b/headers/libs/libc++/__hash_table new file mode 100644 index 0000000000..6ea388bf30 --- /dev/null +++ b/headers/libs/libc++/__hash_table @@ -0,0 +1,2461 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP__HASH_TABLE +#define _LIBCPP__HASH_TABLE + +#include <__config> +#include +#include +#include +#include +#include + +#include <__undef_min_max> +#include <__undef___deallocate> + +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_FUNC_VIS +size_t __next_prime(size_t __n); + +template +struct __hash_node_base +{ + typedef __hash_node_base __first_node; + + _NodePtr __next_; + + _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {} +}; + +template +struct __hash_node + : public __hash_node_base + < + typename pointer_traits<_VoidPtr>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind<__hash_node<_Tp, _VoidPtr> > +#else + rebind<__hash_node<_Tp, _VoidPtr> >::other +#endif + > +{ + typedef _Tp value_type; + + size_t __hash_; + value_type __value_; +}; + +inline _LIBCPP_INLINE_VISIBILITY +bool +__is_hash_power2(size_t __bc) +{ + return __bc > 2 && !(__bc & (__bc - 1)); +} + +inline _LIBCPP_INLINE_VISIBILITY +size_t +__constrain_hash(size_t __h, size_t __bc) +{ + return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : __h % __bc; +} + +inline _LIBCPP_INLINE_VISIBILITY +size_t +__next_hash_pow2(size_t __n) +{ + return size_t(1) << (std::numeric_limits::digits - __clz(__n-1)); +} + +template class __hash_table; +template class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator; +template class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator; +template class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator; + +template +class _LIBCPP_TYPE_VIS_ONLY __hash_iterator +{ + typedef _NodePtr __node_pointer; + + __node_pointer __node_; + +public: + typedef forward_iterator_tag iterator_category; + typedef typename pointer_traits<__node_pointer>::element_type::value_type value_type; + typedef typename pointer_traits<__node_pointer>::difference_type difference_type; + typedef value_type& reference; + typedef typename pointer_traits<__node_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + pointer; + + _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT +#if _LIBCPP_STD_VER > 11 + : __node_(nullptr) +#endif + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_i(this); +#endif + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + __hash_iterator(const __hash_iterator& __i) + : __node_(__i.__node_) + { + __get_db()->__iterator_copy(this, &__i); + } + + _LIBCPP_INLINE_VISIBILITY + ~__hash_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_iterator& operator=(const __hash_iterator& __i) + { + if (this != &__i) + { + __get_db()->__iterator_copy(this, &__i); + __node_ = __i.__node_; + } + return *this; + } + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container iterator"); +#endif + return __node_->__value_; + } + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container iterator"); +#endif + return pointer_traits::pointer_to(__node_->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_iterator& operator++() + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable unordered container iterator"); +#endif + __node_ = __node_->__next_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __hash_iterator operator++(int) + { + __hash_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __hash_iterator& __x, const __hash_iterator& __y) + { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y) + {return !(__x == __y);} + +private: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_iterator(__node_pointer __node, const void* __c) _NOEXCEPT + : __node_(__node) + { + __get_db()->__insert_ic(this, __c); + } +#else + _LIBCPP_INLINE_VISIBILITY + __hash_iterator(__node_pointer __node) _NOEXCEPT + : __node_(__node) + {} +#endif + + template friend class __hash_table; + template friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator; + template friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator; + template friend class _LIBCPP_TYPE_VIS_ONLY unordered_map; + template friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap; +}; + +template +class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator +{ + typedef _ConstNodePtr __node_pointer; + + __node_pointer __node_; + + typedef typename remove_const< + typename pointer_traits<__node_pointer>::element_type + >::type __node; + +public: + typedef forward_iterator_tag iterator_category; + typedef typename __node::value_type value_type; + typedef typename pointer_traits<__node_pointer>::difference_type difference_type; + typedef const value_type& reference; + typedef typename pointer_traits<__node_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + pointer; + typedef typename pointer_traits<__node_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind<__node> +#else + rebind<__node>::other +#endif + __non_const_node_pointer; + typedef __hash_iterator<__non_const_node_pointer> __non_const_iterator; + + _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT +#if _LIBCPP_STD_VER > 11 + : __node_(nullptr) +#endif + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_i(this); +#endif + } + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT + : __node_(__x.__node_) + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__iterator_copy(this, &__x); +#endif + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator(const __hash_const_iterator& __i) + : __node_(__i.__node_) + { + __get_db()->__iterator_copy(this, &__i); + } + + _LIBCPP_INLINE_VISIBILITY + ~__hash_const_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator& operator=(const __hash_const_iterator& __i) + { + if (this != &__i) + { + __get_db()->__iterator_copy(this, &__i); + __node_ = __i.__node_; + } + return *this; + } + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_iterator"); +#endif + return __node_->__value_; + } + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_iterator"); +#endif + return pointer_traits::pointer_to(__node_->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator& operator++() + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable unordered container const_iterator"); +#endif + __node_ = __node_->__next_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator operator++(int) + { + __hash_const_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y) + { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y) + {return !(__x == __y);} + +private: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator(__node_pointer __node, const void* __c) _NOEXCEPT + : __node_(__node) + { + __get_db()->__insert_ic(this, __c); + } +#else + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator(__node_pointer __node) _NOEXCEPT + : __node_(__node) + {} +#endif + + template friend class __hash_table; + template friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator; + template friend class _LIBCPP_TYPE_VIS_ONLY unordered_map; + template friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap; +}; + +template class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator; + +template +class _LIBCPP_TYPE_VIS_ONLY __hash_local_iterator +{ + typedef _NodePtr __node_pointer; + + __node_pointer __node_; + size_t __bucket_; + size_t __bucket_count_; + + typedef pointer_traits<__node_pointer> __pointer_traits; +public: + typedef forward_iterator_tag iterator_category; + typedef typename __pointer_traits::element_type::value_type value_type; + typedef typename __pointer_traits::difference_type difference_type; + typedef value_type& reference; + typedef typename __pointer_traits::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + pointer; + + _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_i(this); +#endif + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator(const __hash_local_iterator& __i) + : __node_(__i.__node_), + __bucket_(__i.__bucket_), + __bucket_count_(__i.__bucket_count_) + { + __get_db()->__iterator_copy(this, &__i); + } + + _LIBCPP_INLINE_VISIBILITY + ~__hash_local_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator& operator=(const __hash_local_iterator& __i) + { + if (this != &__i) + { + __get_db()->__iterator_copy(this, &__i); + __node_ = __i.__node_; + __bucket_ = __i.__bucket_; + __bucket_count_ = __i.__bucket_count_; + } + return *this; + } + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container local_iterator"); +#endif + return __node_->__value_; + } + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container local_iterator"); +#endif + return pointer_traits::pointer_to(__node_->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator& operator++() + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable unordered container local_iterator"); +#endif + __node_ = __node_->__next_; + if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_) + __node_ = nullptr; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator operator++(int) + { + __hash_local_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y) + { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y) + {return !(__x == __y);} + +private: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator(__node_pointer __node, size_t __bucket, + size_t __bucket_count, const void* __c) _NOEXCEPT + : __node_(__node), + __bucket_(__bucket), + __bucket_count_(__bucket_count) + { + __get_db()->__insert_ic(this, __c); + if (__node_ != nullptr) + __node_ = __node_->__next_; + } +#else + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator(__node_pointer __node, size_t __bucket, + size_t __bucket_count) _NOEXCEPT + : __node_(__node), + __bucket_(__bucket), + __bucket_count_(__bucket_count) + { + if (__node_ != nullptr) + __node_ = __node_->__next_; + } +#endif + template friend class __hash_table; + template friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator; + template friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator; +}; + +template +class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator +{ + typedef _ConstNodePtr __node_pointer; + + __node_pointer __node_; + size_t __bucket_; + size_t __bucket_count_; + + typedef pointer_traits<__node_pointer> __pointer_traits; + typedef typename __pointer_traits::element_type __node; + typedef typename remove_const<__node>::type __non_const_node; + typedef typename pointer_traits<__node_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind<__non_const_node> +#else + rebind<__non_const_node>::other +#endif + __non_const_node_pointer; + typedef __hash_local_iterator<__non_const_node_pointer> + __non_const_iterator; +public: + typedef forward_iterator_tag iterator_category; + typedef typename remove_const< + typename __pointer_traits::element_type::value_type + >::type value_type; + typedef typename __pointer_traits::difference_type difference_type; + typedef const value_type& reference; + typedef typename __pointer_traits::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + pointer; + + _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_i(this); +#endif + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT + : __node_(__x.__node_), + __bucket_(__x.__bucket_), + __bucket_count_(__x.__bucket_count_) + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__iterator_copy(this, &__x); +#endif + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator(const __hash_const_local_iterator& __i) + : __node_(__i.__node_), + __bucket_(__i.__bucket_), + __bucket_count_(__i.__bucket_count_) + { + __get_db()->__iterator_copy(this, &__i); + } + + _LIBCPP_INLINE_VISIBILITY + ~__hash_const_local_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i) + { + if (this != &__i) + { + __get_db()->__iterator_copy(this, &__i); + __node_ = __i.__node_; + __bucket_ = __i.__bucket_; + __bucket_count_ = __i.__bucket_count_; + } + return *this; + } + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); +#endif + return __node_->__value_; + } + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); +#endif + return pointer_traits::pointer_to(__node_->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator& operator++() + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable unordered container const_local_iterator"); +#endif + __node_ = __node_->__next_; + if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_) + __node_ = nullptr; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator operator++(int) + { + __hash_const_local_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) + { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) + {return !(__x == __y);} + +private: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator(__node_pointer __node, size_t __bucket, + size_t __bucket_count, const void* __c) _NOEXCEPT + : __node_(__node), + __bucket_(__bucket), + __bucket_count_(__bucket_count) + { + __get_db()->__insert_ic(this, __c); + if (__node_ != nullptr) + __node_ = __node_->__next_; + } +#else + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator(__node_pointer __node, size_t __bucket, + size_t __bucket_count) _NOEXCEPT + : __node_(__node), + __bucket_(__bucket), + __bucket_count_(__bucket_count) + { + if (__node_ != nullptr) + __node_ = __node_->__next_; + } +#endif + template friend class __hash_table; + template friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator; +}; + +template +class __bucket_list_deallocator +{ + typedef _Alloc allocator_type; + typedef allocator_traits __alloc_traits; + typedef typename __alloc_traits::size_type size_type; + + __compressed_pair __data_; +public: + typedef typename __alloc_traits::pointer pointer; + + _LIBCPP_INLINE_VISIBILITY + __bucket_list_deallocator() + _NOEXCEPT_(is_nothrow_default_constructible::value) + : __data_(0) {} + + _LIBCPP_INLINE_VISIBILITY + __bucket_list_deallocator(const allocator_type& __a, size_type __size) + _NOEXCEPT_(is_nothrow_copy_constructible::value) + : __data_(__size, __a) {} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + + _LIBCPP_INLINE_VISIBILITY + __bucket_list_deallocator(__bucket_list_deallocator&& __x) + _NOEXCEPT_(is_nothrow_move_constructible::value) + : __data_(_VSTD::move(__x.__data_)) + { + __x.size() = 0; + } + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + _LIBCPP_INLINE_VISIBILITY + size_type& size() _NOEXCEPT {return __data_.first();} + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT {return __data_.first();} + + _LIBCPP_INLINE_VISIBILITY + allocator_type& __alloc() _NOEXCEPT {return __data_.second();} + _LIBCPP_INLINE_VISIBILITY + const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();} + + _LIBCPP_INLINE_VISIBILITY + void operator()(pointer __p) _NOEXCEPT + { + __alloc_traits::deallocate(__alloc(), __p, size()); + } +}; + +template class __hash_map_node_destructor; + +template +class __hash_node_destructor +{ + typedef _Alloc allocator_type; + typedef allocator_traits __alloc_traits; + typedef typename __alloc_traits::value_type::value_type value_type; +public: + typedef typename __alloc_traits::pointer pointer; +private: + + allocator_type& __na_; + + __hash_node_destructor& operator=(const __hash_node_destructor&); + +public: + bool __value_constructed; + + _LIBCPP_INLINE_VISIBILITY + explicit __hash_node_destructor(allocator_type& __na, + bool __constructed = false) _NOEXCEPT + : __na_(__na), + __value_constructed(__constructed) + {} + + _LIBCPP_INLINE_VISIBILITY + void operator()(pointer __p) _NOEXCEPT + { + if (__value_constructed) + __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_)); + if (__p) + __alloc_traits::deallocate(__na_, __p, 1); + } + + template friend class __hash_map_node_destructor; +}; + +template +class __hash_table +{ +public: + typedef _Tp value_type; + typedef _Hash hasher; + typedef _Equal key_equal; + typedef _Alloc allocator_type; + +private: + typedef allocator_traits __alloc_traits; +public: + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; + typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::difference_type difference_type; +public: + // Create __node + typedef __hash_node __node; + typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; + typedef allocator_traits<__node_allocator> __node_traits; + typedef typename __node_traits::pointer __node_pointer; + typedef typename __node_traits::pointer __node_const_pointer; + typedef __hash_node_base<__node_pointer> __first_node; + typedef typename pointer_traits<__node_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind<__first_node> +#else + rebind<__first_node>::other +#endif + __node_base_pointer; + +private: + + typedef typename __rebind_alloc_helper<__node_traits, __node_pointer>::type __pointer_allocator; + typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter; + typedef unique_ptr<__node_pointer[], __bucket_list_deleter> __bucket_list; + typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits; + typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; + + // --- Member data begin --- + __bucket_list __bucket_list_; + __compressed_pair<__first_node, __node_allocator> __p1_; + __compressed_pair __p2_; + __compressed_pair __p3_; + // --- Member data end --- + + _LIBCPP_INLINE_VISIBILITY + size_type& size() _NOEXCEPT {return __p2_.first();} +public: + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT {return __p2_.first();} + + _LIBCPP_INLINE_VISIBILITY + hasher& hash_function() _NOEXCEPT {return __p2_.second();} + _LIBCPP_INLINE_VISIBILITY + const hasher& hash_function() const _NOEXCEPT {return __p2_.second();} + + _LIBCPP_INLINE_VISIBILITY + float& max_load_factor() _NOEXCEPT {return __p3_.first();} + _LIBCPP_INLINE_VISIBILITY + float max_load_factor() const _NOEXCEPT {return __p3_.first();} + + _LIBCPP_INLINE_VISIBILITY + key_equal& key_eq() _NOEXCEPT {return __p3_.second();} + _LIBCPP_INLINE_VISIBILITY + const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();} + + _LIBCPP_INLINE_VISIBILITY + __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();} + _LIBCPP_INLINE_VISIBILITY + const __node_allocator& __node_alloc() const _NOEXCEPT + {return __p1_.second();} + +public: + typedef __hash_iterator<__node_pointer> iterator; + typedef __hash_const_iterator<__node_pointer> const_iterator; + typedef __hash_local_iterator<__node_pointer> local_iterator; + typedef __hash_const_local_iterator<__node_pointer> const_local_iterator; + + _LIBCPP_INLINE_VISIBILITY + __hash_table() + _NOEXCEPT_( + is_nothrow_default_constructible<__bucket_list>::value && + is_nothrow_default_constructible<__first_node>::value && + is_nothrow_default_constructible<__node_allocator>::value && + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value); + _LIBCPP_INLINE_VISIBILITY + __hash_table(const hasher& __hf, const key_equal& __eql); + __hash_table(const hasher& __hf, const key_equal& __eql, + const allocator_type& __a); + explicit __hash_table(const allocator_type& __a); + __hash_table(const __hash_table& __u); + __hash_table(const __hash_table& __u, const allocator_type& __a); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + __hash_table(__hash_table&& __u) + _NOEXCEPT_( + is_nothrow_move_constructible<__bucket_list>::value && + is_nothrow_move_constructible<__first_node>::value && + is_nothrow_move_constructible<__node_allocator>::value && + is_nothrow_move_constructible::value && + is_nothrow_move_constructible::value); + __hash_table(__hash_table&& __u, const allocator_type& __a); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + ~__hash_table(); + + __hash_table& operator=(const __hash_table& __u); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + __hash_table& operator=(__hash_table&& __u) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value); +#endif + template + void __assign_unique(_InputIterator __first, _InputIterator __last); + template + void __assign_multi(_InputIterator __first, _InputIterator __last); + + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT + { + return allocator_traits<__pointer_allocator>::max_size( + __bucket_list_.get_deleter().__alloc()); + } + + pair __node_insert_unique(__node_pointer __nd); + iterator __node_insert_multi(__node_pointer __nd); + iterator __node_insert_multi(const_iterator __p, + __node_pointer __nd); + +#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) + template + pair __emplace_unique(_Args&&... __args); + template + iterator __emplace_multi(_Args&&... __args); + template + iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); +#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + template + _LIBCPP_INLINE_VISIBILITY + pair __insert_unique_value(_ValueTp&& __x); +#else + _LIBCPP_INLINE_VISIBILITY + pair __insert_unique_value(const value_type& __x); +#endif + + pair __insert_unique(const value_type& __x); + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + pair __insert_unique(value_type&& __x); + template + pair __insert_unique(_Pp&& __x); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + template + iterator __insert_multi(_Pp&& __x); + template + iterator __insert_multi(const_iterator __p, _Pp&& __x); +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES + iterator __insert_multi(const value_type& __x); + iterator __insert_multi(const_iterator __p, const value_type& __x); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + void clear() _NOEXCEPT; + void rehash(size_type __n); + _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n) + {rehash(static_cast(ceil(__n / max_load_factor())));} + + _LIBCPP_INLINE_VISIBILITY + size_type bucket_count() const _NOEXCEPT + { + return __bucket_list_.get_deleter().size(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT; + + template + _LIBCPP_INLINE_VISIBILITY + size_type bucket(const _Key& __k) const + { + _LIBCPP_ASSERT(bucket_count() > 0, + "unordered container::bucket(key) called when bucket_count() == 0"); + return __constrain_hash(hash_function()(__k), bucket_count()); + } + + template + iterator find(const _Key& __x); + template + const_iterator find(const _Key& __x) const; + + typedef __hash_node_destructor<__node_allocator> _Dp; + typedef unique_ptr<__node, _Dp> __node_holder; + + iterator erase(const_iterator __p); + iterator erase(const_iterator __first, const_iterator __last); + template + size_type __erase_unique(const _Key& __k); + template + size_type __erase_multi(const _Key& __k); + __node_holder remove(const_iterator __p) _NOEXCEPT; + + template + _LIBCPP_INLINE_VISIBILITY + size_type __count_unique(const _Key& __k) const; + template + size_type __count_multi(const _Key& __k) const; + + template + pair + __equal_range_unique(const _Key& __k); + template + pair + __equal_range_unique(const _Key& __k) const; + + template + pair + __equal_range_multi(const _Key& __k); + template + pair + __equal_range_multi(const _Key& __k) const; + + void swap(__hash_table& __u) +#if _LIBCPP_STD_VER <= 11 + _NOEXCEPT_( + __is_nothrow_swappable::value && __is_nothrow_swappable::value + && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value + || __is_nothrow_swappable<__pointer_allocator>::value) + && (!__node_traits::propagate_on_container_swap::value + || __is_nothrow_swappable<__node_allocator>::value) + ); +#else + _NOEXCEPT_(__is_nothrow_swappable::value && __is_nothrow_swappable::value); +#endif + + _LIBCPP_INLINE_VISIBILITY + size_type max_bucket_count() const _NOEXCEPT + {return __pointer_alloc_traits::max_size(__bucket_list_.get_deleter().__alloc());} + size_type bucket_size(size_type __n) const; + _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT + { + size_type __bc = bucket_count(); + return __bc != 0 ? (float)size() / __bc : 0.f; + } + _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT + { + _LIBCPP_ASSERT(__mlf > 0, + "unordered container::max_load_factor(lf) called with lf <= 0"); + max_load_factor() = _VSTD::max(__mlf, load_factor()); + } + + _LIBCPP_INLINE_VISIBILITY + local_iterator + begin(size_type __n) + { + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::begin(n) called with n >= bucket_count()"); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return local_iterator(__bucket_list_[__n], __n, bucket_count(), this); +#else + return local_iterator(__bucket_list_[__n], __n, bucket_count()); +#endif + } + + _LIBCPP_INLINE_VISIBILITY + local_iterator + end(size_type __n) + { + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::end(n) called with n >= bucket_count()"); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return local_iterator(nullptr, __n, bucket_count(), this); +#else + return local_iterator(nullptr, __n, bucket_count()); +#endif + } + + _LIBCPP_INLINE_VISIBILITY + const_local_iterator + cbegin(size_type __n) const + { + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::cbegin(n) called with n >= bucket_count()"); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this); +#else + return const_local_iterator(__bucket_list_[__n], __n, bucket_count()); +#endif + } + + _LIBCPP_INLINE_VISIBILITY + const_local_iterator + cend(size_type __n) const + { + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::cend(n) called with n >= bucket_count()"); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_local_iterator(nullptr, __n, bucket_count(), this); +#else + return const_local_iterator(nullptr, __n, bucket_count()); +#endif + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 + + bool __dereferenceable(const const_iterator* __i) const; + bool __decrementable(const const_iterator* __i) const; + bool __addable(const const_iterator* __i, ptrdiff_t __n) const; + bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + +private: + void __rehash(size_type __n); + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + template + __node_holder __construct_node(_Args&& ...__args); +#endif // _LIBCPP_HAS_NO_VARIADICS + __node_holder __construct_node(value_type&& __v, size_t __hash); +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES + __node_holder __construct_node(const value_type& __v); +#endif + __node_holder __construct_node(const value_type& __v, size_t __hash); + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __hash_table& __u) + {__copy_assign_alloc(__u, integral_constant());} + void __copy_assign_alloc(const __hash_table& __u, true_type); + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __hash_table&, false_type) {} + + void __move_assign(__hash_table& __u, false_type); + void __move_assign(__hash_table& __u, true_type) + _NOEXCEPT_( + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value); + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__hash_table& __u) + _NOEXCEPT_( + !__node_traits::propagate_on_container_move_assignment::value || + (is_nothrow_move_assignable<__pointer_allocator>::value && + is_nothrow_move_assignable<__node_allocator>::value)) + {__move_assign_alloc(__u, integral_constant());} + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__hash_table& __u, true_type) + _NOEXCEPT_( + is_nothrow_move_assignable<__pointer_allocator>::value && + is_nothrow_move_assignable<__node_allocator>::value) + { + __bucket_list_.get_deleter().__alloc() = + _VSTD::move(__u.__bucket_list_.get_deleter().__alloc()); + __node_alloc() = _VSTD::move(__u.__node_alloc()); + } + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} + + void __deallocate(__node_pointer __np) _NOEXCEPT; + __node_pointer __detach() _NOEXCEPT; + + template friend class _LIBCPP_TYPE_VIS_ONLY unordered_map; + template friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap; +}; + +template +inline +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table() + _NOEXCEPT_( + is_nothrow_default_constructible<__bucket_list>::value && + is_nothrow_default_constructible<__first_node>::value && + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value) + : __p2_(0), + __p3_(1.0f) +{ +} + +template +inline +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, + const key_equal& __eql) + : __bucket_list_(nullptr, __bucket_list_deleter()), + __p1_(), + __p2_(0, __hf), + __p3_(1.0f, __eql) +{ +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, + const key_equal& __eql, + const allocator_type& __a) + : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), + __p1_(__node_allocator(__a)), + __p2_(0, __hf), + __p3_(1.0f, __eql) +{ +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a) + : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), + __p1_(__node_allocator(__a)), + __p2_(0), + __p3_(1.0f) +{ +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u) + : __bucket_list_(nullptr, + __bucket_list_deleter(allocator_traits<__pointer_allocator>:: + select_on_container_copy_construction( + __u.__bucket_list_.get_deleter().__alloc()), 0)), + __p1_(allocator_traits<__node_allocator>:: + select_on_container_copy_construction(__u.__node_alloc())), + __p2_(0, __u.hash_function()), + __p3_(__u.__p3_) +{ +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, + const allocator_type& __a) + : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), + __p1_(__node_allocator(__a)), + __p2_(0, __u.hash_function()), + __p3_(__u.__p3_) +{ +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) + _NOEXCEPT_( + is_nothrow_move_constructible<__bucket_list>::value && + is_nothrow_move_constructible<__first_node>::value && + is_nothrow_move_constructible::value && + is_nothrow_move_constructible::value) + : __bucket_list_(_VSTD::move(__u.__bucket_list_)), + __p1_(_VSTD::move(__u.__p1_)), + __p2_(_VSTD::move(__u.__p2_)), + __p3_(_VSTD::move(__u.__p3_)) +{ + if (size() > 0) + { + __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] = + static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + __u.__p1_.first().__next_ = nullptr; + __u.size() = 0; + } +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, + const allocator_type& __a) + : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), + __p1_(__node_allocator(__a)), + __p2_(0, _VSTD::move(__u.hash_function())), + __p3_(_VSTD::move(__u.__p3_)) +{ + if (__a == allocator_type(__u.__node_alloc())) + { + __bucket_list_.reset(__u.__bucket_list_.release()); + __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); + __u.__bucket_list_.get_deleter().size() = 0; + if (__u.size() > 0) + { + __p1_.first().__next_ = __u.__p1_.first().__next_; + __u.__p1_.first().__next_ = nullptr; + __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] = + static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + size() = __u.size(); + __u.size() = 0; + } + } +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() +{ + __deallocate(__p1_.first().__next_); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__erase_c(this); +#endif +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc( + const __hash_table& __u, true_type) +{ + if (__node_alloc() != __u.__node_alloc()) + { + clear(); + __bucket_list_.reset(); + __bucket_list_.get_deleter().size() = 0; + } + __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc(); + __node_alloc() = __u.__node_alloc(); +} + +template +__hash_table<_Tp, _Hash, _Equal, _Alloc>& +__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) +{ + if (this != &__u) + { + __copy_assign_alloc(__u); + hash_function() = __u.hash_function(); + key_eq() = __u.key_eq(); + max_load_factor() = __u.max_load_factor(); + __assign_multi(__u.begin(), __u.end()); + } + return *this; +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate(__node_pointer __np) + _NOEXCEPT +{ + __node_allocator& __na = __node_alloc(); + while (__np != nullptr) + { + __node_pointer __next = __np->__next_; +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + iterator* __i = static_cast((*__p)->__i_); + if (__i->__node_ == __np) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif + __node_traits::destroy(__na, _VSTD::addressof(__np->__value_)); + __node_traits::deallocate(__na, __np, 1); + __np = __next; + } +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_pointer +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT +{ + size_type __bc = bucket_count(); + for (size_type __i = 0; __i < __bc; ++__i) + __bucket_list_[__i] = nullptr; + size() = 0; + __node_pointer __cache = __p1_.first().__next_; + __p1_.first().__next_ = nullptr; + return __cache; +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( + __hash_table& __u, true_type) + _NOEXCEPT_( + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value) +{ + clear(); + __bucket_list_.reset(__u.__bucket_list_.release()); + __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); + __u.__bucket_list_.get_deleter().size() = 0; + __move_assign_alloc(__u); + size() = __u.size(); + hash_function() = _VSTD::move(__u.hash_function()); + max_load_factor() = __u.max_load_factor(); + key_eq() = _VSTD::move(__u.key_eq()); + __p1_.first().__next_ = __u.__p1_.first().__next_; + if (size() > 0) + { + __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] = + static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + __u.__p1_.first().__next_ = nullptr; + __u.size() = 0; + } +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->swap(this, &__u); +#endif +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( + __hash_table& __u, false_type) +{ + if (__node_alloc() == __u.__node_alloc()) + __move_assign(__u, true_type()); + else + { + hash_function() = _VSTD::move(__u.hash_function()); + key_eq() = _VSTD::move(__u.key_eq()); + max_load_factor() = __u.max_load_factor(); + if (bucket_count() != 0) + { + __node_pointer __cache = __detach(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + const_iterator __i = __u.begin(); + while (__cache != nullptr && __u.size() != 0) + { + __cache->__value_ = _VSTD::move(__u.remove(__i++)->__value_); + __node_pointer __next = __cache->__next_; + __node_insert_multi(__cache); + __cache = __next; + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __deallocate(__cache); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __deallocate(__cache); + } + const_iterator __i = __u.begin(); + while (__u.size() != 0) + { + __node_holder __h = + __construct_node(_VSTD::move(__u.remove(__i++)->__value_)); + __node_insert_multi(__h.get()); + __h.release(); + } + } +} + +template +inline +__hash_table<_Tp, _Hash, _Equal, _Alloc>& +__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value) +{ + __move_assign(__u, integral_constant()); + return *this; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, + _InputIterator __last) +{ + if (bucket_count() != 0) + { + __node_pointer __cache = __detach(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (; __cache != nullptr && __first != __last; ++__first) + { + __cache->__value_ = *__first; + __node_pointer __next = __cache->__next_; + __node_insert_unique(__cache); + __cache = __next; + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __deallocate(__cache); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __deallocate(__cache); + } + for (; __first != __last; ++__first) + __insert_unique(*__first); +} + +template +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, + _InputIterator __last) +{ + if (bucket_count() != 0) + { + __node_pointer __cache = __detach(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (; __cache != nullptr && __first != __last; ++__first) + { + __cache->__value_ = *__first; + __node_pointer __next = __cache->__next_; + __node_insert_multi(__cache); + __cache = __next; + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __deallocate(__cache); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __deallocate(__cache); + } + for (; __first != __last; ++__first) + __insert_multi(*__first); +} + +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__p1_.first().__next_, this); +#else + return iterator(__p1_.first().__next_); +#endif +} + +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(nullptr, this); +#else + return iterator(nullptr); +#endif +} + +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_iterator(__p1_.first().__next_, this); +#else + return const_iterator(__p1_.first().__next_); +#endif +} + +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_iterator(nullptr, this); +#else + return const_iterator(nullptr); +#endif +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT +{ + if (size() > 0) + { + __deallocate(__p1_.first().__next_); + __p1_.first().__next_ = nullptr; + size_type __bc = bucket_count(); + for (size_type __i = 0; __i < __bc; ++__i) + __bucket_list_[__i] = nullptr; + size() = 0; + } +} + +template +pair::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd) +{ + __nd->__hash_ = hash_function()(__nd->__value_); + size_type __bc = bucket_count(); + bool __inserted = false; + __node_pointer __ndptr; + size_t __chash; + if (__bc != 0) + { + __chash = __constrain_hash(__nd->__hash_, __bc); + __ndptr = __bucket_list_[__chash]; + if (__ndptr != nullptr) + { + for (__ndptr = __ndptr->__next_; __ndptr != nullptr && + __constrain_hash(__ndptr->__hash_, __bc) == __chash; + __ndptr = __ndptr->__next_) + { + if (key_eq()(__ndptr->__value_, __nd->__value_)) + goto __done; + } + } + } + { + if (size()+1 > __bc * max_load_factor() || __bc == 0) + { + rehash(_VSTD::max(2 * __bc + !__is_hash_power2(__bc), + size_type(ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + __chash = __constrain_hash(__nd->__hash_, __bc); + } + // insert_after __bucket_list_[__chash], or __first_node if bucket is null + __node_pointer __pn = __bucket_list_[__chash]; + if (__pn == nullptr) + { + __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + __nd->__next_ = __pn->__next_; + __pn->__next_ = __nd; + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__nd->__next_ != nullptr) + __bucket_list_[__constrain_hash(__nd->__next_->__hash_, __bc)] = __nd; + } + else + { + __nd->__next_ = __pn->__next_; + __pn->__next_ = __nd; + } + __ndptr = __nd; + // increment size + ++size(); + __inserted = true; + } +__done: +#if _LIBCPP_DEBUG_LEVEL >= 2 + return pair(iterator(__ndptr, this), __inserted); +#else + return pair(iterator(__ndptr), __inserted); +#endif +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp) +{ + __cp->__hash_ = hash_function()(__cp->__value_); + size_type __bc = bucket_count(); + if (size()+1 > __bc * max_load_factor() || __bc == 0) + { + rehash(_VSTD::max(2 * __bc + !__is_hash_power2(__bc), + size_type(ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + } + size_t __chash = __constrain_hash(__cp->__hash_, __bc); + __node_pointer __pn = __bucket_list_[__chash]; + if (__pn == nullptr) + { + __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + __cp->__next_ = __pn->__next_; + __pn->__next_ = __cp; + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__cp->__next_ != nullptr) + __bucket_list_[__constrain_hash(__cp->__next_->__hash_, __bc)] = __cp; + } + else + { + for (bool __found = false; __pn->__next_ != nullptr && + __constrain_hash(__pn->__next_->__hash_, __bc) == __chash; + __pn = __pn->__next_) + { + // __found key_eq() action + // false false loop + // true true loop + // false true set __found to true + // true false break + if (__found != (__pn->__next_->__hash_ == __cp->__hash_ && + key_eq()(__pn->__next_->__value_, __cp->__value_))) + { + if (!__found) + __found = true; + else + break; + } + } + __cp->__next_ = __pn->__next_; + __pn->__next_ = __cp; + if (__cp->__next_ != nullptr) + { + size_t __nhash = __constrain_hash(__cp->__next_->__hash_, __bc); + if (__nhash != __chash) + __bucket_list_[__nhash] = __cp; + } + } + ++size(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__cp, this); +#else + return iterator(__cp); +#endif +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( + const_iterator __p, __node_pointer __cp) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered container"); +#endif + if (__p != end() && key_eq()(*__p, __cp->__value_)) + { + __node_pointer __np = __p.__node_; + __cp->__hash_ = __np->__hash_; + size_type __bc = bucket_count(); + if (size()+1 > __bc * max_load_factor() || __bc == 0) + { + rehash(_VSTD::max(2 * __bc + !__is_hash_power2(__bc), + size_type(ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + } + size_t __chash = __constrain_hash(__cp->__hash_, __bc); + __node_pointer __pp = __bucket_list_[__chash]; + while (__pp->__next_ != __np) + __pp = __pp->__next_; + __cp->__next_ = __np; + __pp->__next_ = __cp; + ++size(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__cp, this); +#else + return iterator(__cp); +#endif + } + return __node_insert_multi(__cp); +} + +template +pair::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(const value_type& __x) +{ + return __insert_unique_value(__x); +} + + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +template +template +_LIBCPP_INLINE_VISIBILITY +pair::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique_value(_ValueTp&& __x) +#else +template +_LIBCPP_INLINE_VISIBILITY +pair::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique_value(const value_type& __x) +#endif +{ +#if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) + typedef const value_type& _ValueTp; +#endif + size_t __hash = hash_function()(__x); + size_type __bc = bucket_count(); + bool __inserted = false; + __node_pointer __nd; + size_t __chash; + if (__bc != 0) + { + __chash = __constrain_hash(__hash, __bc); + __nd = __bucket_list_[__chash]; + if (__nd != nullptr) + { + for (__nd = __nd->__next_; __nd != nullptr && + __constrain_hash(__nd->__hash_, __bc) == __chash; + __nd = __nd->__next_) + { + if (key_eq()(__nd->__value_, __x)) + goto __done; + } + } + } + { + __node_holder __h = __construct_node(_VSTD::forward<_ValueTp>(__x), __hash); + if (size()+1 > __bc * max_load_factor() || __bc == 0) + { + rehash(_VSTD::max(2 * __bc + !__is_hash_power2(__bc), + size_type(ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + __chash = __constrain_hash(__hash, __bc); + } + // insert_after __bucket_list_[__chash], or __first_node if bucket is null + __node_pointer __pn = __bucket_list_[__chash]; + if (__pn == nullptr) + { + __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + __h->__next_ = __pn->__next_; + __pn->__next_ = __h.get(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__h->__next_ != nullptr) + __bucket_list_[__constrain_hash(__h->__next_->__hash_, __bc)] = __h.get(); + } + else + { + __h->__next_ = __pn->__next_; + __pn->__next_ = __h.get(); + } + __nd = __h.release(); + // increment size + ++size(); + __inserted = true; + } +__done: +#if _LIBCPP_DEBUG_LEVEL >= 2 + return pair(iterator(__nd, this), __inserted); +#else + return pair(iterator(__nd), __inserted); +#endif +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + +template +template +pair::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique(_Args&&... __args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + pair __r = __node_insert_unique(__h.get()); + if (__r.second) + __h.release(); + return __r; +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + iterator __r = __node_insert_multi(__h.get()); + __h.release(); + return __r; +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( + const_iterator __p, _Args&&... __args) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered container"); +#endif + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + iterator __r = __node_insert_multi(__p, __h.get()); + __h.release(); + return __r; +} + +#endif // _LIBCPP_HAS_NO_VARIADICS + +template +pair::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(value_type&& __x) +{ + return __insert_unique_value(_VSTD::move(__x)); +} + +template +template +pair::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(_Pp&& __x) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x)); + pair __r = __node_insert_unique(__h.get()); + if (__r.second) + __h.release(); + return __r; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(_Pp&& __x) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x)); + iterator __r = __node_insert_multi(__h.get()); + __h.release(); + return __r; +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p, + _Pp&& __x) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered container::insert(const_iterator, rvalue) called with an iterator not" + " referring to this unordered container"); +#endif + __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x)); + iterator __r = __node_insert_multi(__p, __h.get()); + __h.release(); + return __r; +} + +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const value_type& __x) +{ + __node_holder __h = __construct_node(__x); + iterator __r = __node_insert_multi(__h.get()); + __h.release(); + return __r; +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p, + const value_type& __x) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered container::insert(const_iterator, lvalue) called with an iterator not" + " referring to this unordered container"); +#endif + __node_holder __h = __construct_node(__x); + iterator __r = __node_insert_multi(__p, __h.get()); + __h.release(); + return __r; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n) +{ + if (__n == 1) + __n = 2; + else if (__n & (__n - 1)) + __n = __next_prime(__n); + size_type __bc = bucket_count(); + if (__n > __bc) + __rehash(__n); + else if (__n < __bc) + { + __n = _VSTD::max + ( + __n, + __is_hash_power2(__bc) ? __next_hash_pow2(size_t(ceil(float(size()) / max_load_factor()))) : + __next_prime(size_t(ceil(float(size()) / max_load_factor()))) + ); + if (__n < __bc) + __rehash(__n); + } +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__invalidate_all(this); +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); + __bucket_list_.reset(__nbc > 0 ? + __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); + __bucket_list_.get_deleter().size() = __nbc; + if (__nbc > 0) + { + for (size_type __i = 0; __i < __nbc; ++__i) + __bucket_list_[__i] = nullptr; + __node_pointer __pp(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()))); + __node_pointer __cp = __pp->__next_; + if (__cp != nullptr) + { + size_type __chash = __constrain_hash(__cp->__hash_, __nbc); + __bucket_list_[__chash] = __pp; + size_type __phash = __chash; + for (__pp = __cp, __cp = __cp->__next_; __cp != nullptr; + __cp = __pp->__next_) + { + __chash = __constrain_hash(__cp->__hash_, __nbc); + if (__chash == __phash) + __pp = __cp; + else + { + if (__bucket_list_[__chash] == nullptr) + { + __bucket_list_[__chash] = __pp; + __pp = __cp; + __phash = __chash; + } + else + { + __node_pointer __np = __cp; + for (; __np->__next_ != nullptr && + key_eq()(__cp->__value_, __np->__next_->__value_); + __np = __np->__next_) + ; + __pp->__next_ = __np->__next_; + __np->__next_ = __bucket_list_[__chash]->__next_; + __bucket_list_[__chash]->__next_ = __cp; + + } + } + } + } + } +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) +{ + size_t __hash = hash_function()(__k); + size_type __bc = bucket_count(); + if (__bc != 0) + { + size_t __chash = __constrain_hash(__hash, __bc); + __node_pointer __nd = __bucket_list_[__chash]; + if (__nd != nullptr) + { + for (__nd = __nd->__next_; __nd != nullptr && + __constrain_hash(__nd->__hash_, __bc) == __chash; + __nd = __nd->__next_) + { + if (key_eq()(__nd->__value_, __k)) +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__nd, this); +#else + return iterator(__nd); +#endif + } + } + } + return end(); +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const +{ + size_t __hash = hash_function()(__k); + size_type __bc = bucket_count(); + if (__bc != 0) + { + size_t __chash = __constrain_hash(__hash, __bc); + __node_const_pointer __nd = __bucket_list_[__chash]; + if (__nd != nullptr) + { + for (__nd = __nd->__next_; __nd != nullptr && + __constrain_hash(__nd->__hash_, __bc) == __chash; + __nd = __nd->__next_) + { + if (key_eq()(__nd->__value_, __k)) +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_iterator(__nd, this); +#else + return const_iterator(__nd); +#endif + } + } + + } + return end(); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args) +{ + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...); + __h.get_deleter().__value_constructed = true; + __h->__hash_ = hash_function()(__h->__value_); + __h->__next_ = nullptr; + return __h; +} + +#endif // _LIBCPP_HAS_NO_VARIADICS + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(value_type&& __v, + size_t __hash) +{ + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); + __h.get_deleter().__value_constructed = true; + __h->__hash_ = __hash; + __h->__next_ = nullptr; + return __h; +} + +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const value_type& __v) +{ + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v); + __h.get_deleter().__value_constructed = true; + __h->__hash_ = hash_function()(__h->__value_); + __h->__next_ = nullptr; + return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const value_type& __v, + size_t __hash) +{ + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v); + __h.get_deleter().__value_constructed = true; + __h->__hash_ = __hash; + __h->__next_ = nullptr; + return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) +{ + __node_pointer __np = __p.__node_; +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered container erase(iterator) called with an iterator not" + " referring to this container"); + _LIBCPP_ASSERT(__p != end(), + "unordered container erase(iterator) called with a non-dereferenceable iterator"); + iterator __r(__np, this); +#else + iterator __r(__np); +#endif + ++__r; + remove(__p); + return __r; +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, + const_iterator __last) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, + "unodered container::erase(iterator, iterator) called with an iterator not" + " referring to this unodered container"); + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this, + "unodered container::erase(iterator, iterator) called with an iterator not" + " referring to this unodered container"); +#endif + for (const_iterator __p = __first; __first != __last; __p = __first) + { + ++__first; + erase(__p); + } + __node_pointer __np = __last.__node_; +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator (__np, this); +#else + return iterator (__np); +#endif +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k) +{ + iterator __i = find(__k); + if (__i == end()) + return 0; + erase(__i); + return 1; +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k) +{ + size_type __r = 0; + iterator __i = find(__k); + if (__i != end()) + { + iterator __e = end(); + do + { + erase(__i++); + ++__r; + } while (__i != __e && key_eq()(*__i, __k)); + } + return __r; +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder +__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT +{ + // current node + __node_pointer __cn = __p.__node_; + size_type __bc = bucket_count(); + size_t __chash = __constrain_hash(__cn->__hash_, __bc); + // find previous node + __node_pointer __pn = __bucket_list_[__chash]; + for (; __pn->__next_ != __cn; __pn = __pn->__next_) + ; + // Fix up __bucket_list_ + // if __pn is not in same bucket (before begin is not in same bucket) && + // if __cn->__next_ is not in same bucket (nullptr is not in same bucket) + if (__pn == static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())) + || __constrain_hash(__pn->__hash_, __bc) != __chash) + { + if (__cn->__next_ == nullptr || __constrain_hash(__cn->__next_->__hash_, __bc) != __chash) + __bucket_list_[__chash] = nullptr; + } + // if __cn->__next_ is not in same bucket (nullptr is in same bucket) + if (__cn->__next_ != nullptr) + { + size_t __nhash = __constrain_hash(__cn->__next_->__hash_, __bc); + if (__nhash != __chash) + __bucket_list_[__nhash] = __pn; + } + // remove __cn + __pn->__next_ = __cn->__next_; + __cn->__next_ = nullptr; + --size(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + iterator* __i = static_cast((*__p)->__i_); + if (__i->__node_ == __cn) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif + return __node_holder(__cn, _Dp(__node_alloc(), true)); +} + +template +template +inline +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const +{ + return static_cast(find(__k) != end()); +} + +template +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const +{ + size_type __r = 0; + const_iterator __i = find(__k); + if (__i != end()) + { + const_iterator __e = end(); + do + { + ++__i; + ++__r; + } while (__i != __e && key_eq()(*__i, __k)); + } + return __r; +} + +template +template +pair::iterator, + typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( + const _Key& __k) +{ + iterator __i = find(__k); + iterator __j = __i; + if (__i != end()) + ++__j; + return pair(__i, __j); +} + +template +template +pair::const_iterator, + typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( + const _Key& __k) const +{ + const_iterator __i = find(__k); + const_iterator __j = __i; + if (__i != end()) + ++__j; + return pair(__i, __j); +} + +template +template +pair::iterator, + typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( + const _Key& __k) +{ + iterator __i = find(__k); + iterator __j = __i; + if (__i != end()) + { + iterator __e = end(); + do + { + ++__j; + } while (__j != __e && key_eq()(*__j, __k)); + } + return pair(__i, __j); +} + +template +template +pair::const_iterator, + typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( + const _Key& __k) const +{ + const_iterator __i = find(__k); + const_iterator __j = __i; + if (__i != end()) + { + const_iterator __e = end(); + do + { + ++__j; + } while (__j != __e && key_eq()(*__j, __k)); + } + return pair(__i, __j); +} + +template +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) +#if _LIBCPP_STD_VER <= 11 + _NOEXCEPT_( + __is_nothrow_swappable::value && __is_nothrow_swappable::value + && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value + || __is_nothrow_swappable<__pointer_allocator>::value) + && (!__node_traits::propagate_on_container_swap::value + || __is_nothrow_swappable<__node_allocator>::value) + ) +#else + _NOEXCEPT_(__is_nothrow_swappable::value && __is_nothrow_swappable::value) +#endif +{ + { + __node_pointer_pointer __npp = __bucket_list_.release(); + __bucket_list_.reset(__u.__bucket_list_.release()); + __u.__bucket_list_.reset(__npp); + } + _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size()); + __swap_allocator(__bucket_list_.get_deleter().__alloc(), + __u.__bucket_list_.get_deleter().__alloc()); + __swap_allocator(__node_alloc(), __u.__node_alloc()); + _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_); + __p2_.swap(__u.__p2_); + __p3_.swap(__u.__p3_); + if (size() > 0) + __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] = + static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + if (__u.size() > 0) + __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash_, __u.bucket_count())] = + static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__u.__p1_.first())); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->swap(this, &__u); +#endif +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const +{ + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::bucket_size(n) called with n >= bucket_count()"); + __node_const_pointer __np = __bucket_list_[__n]; + size_type __bc = bucket_count(); + size_type __r = 0; + if (__np != nullptr) + { + for (__np = __np->__next_; __np != nullptr && + __constrain_hash(__np->__hash_, __bc) == __n; + __np = __np->__next_, ++__r) + ; + } + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, + __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + +#if _LIBCPP_DEBUG_LEVEL >= 2 + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const +{ + return __i->__node_ != nullptr; +} + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const +{ + return false; +} + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const +{ + return false; +} + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const +{ + return false; +} + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP__HASH_TABLE diff --git a/headers/libs/libc++/__locale b/headers/libs/libc++/__locale new file mode 100644 index 0000000000..19895582ca --- /dev/null +++ b/headers/libs/libc++/__locale @@ -0,0 +1,1475 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___LOCALE +#define _LIBCPP___LOCALE + +#include <__config> +#include +#include +#include +#include +#include +#include +#include +#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) +# include +#elif defined(_AIX) +# include +#elif defined(__ANDROID__) +// Android gained the locale aware functions in L (API level 21) +# include +# if __ANDROID_API__ <= 20 +# include +# endif +#elif defined(__sun__) +# include +# include +#elif defined(_NEWLIB_VERSION) +# include +#elif (defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__) \ + || defined(__EMSCRIPTEN__) || defined(__IBMCPP__)) +# include +#endif // __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || __EMSCRIPTEN__ || __IBMCPP__ + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +class _LIBCPP_TYPE_VIS locale; + +template +_LIBCPP_INLINE_VISIBILITY +bool +has_facet(const locale&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY +const _Facet& +use_facet(const locale&); + +class _LIBCPP_TYPE_VIS locale +{ +public: + // types: + class _LIBCPP_TYPE_VIS facet; + class _LIBCPP_TYPE_VIS id; + + typedef int category; + static const category // values assigned here are for exposition only + none = 0, + collate = LC_COLLATE_MASK, + ctype = LC_CTYPE_MASK, + monetary = LC_MONETARY_MASK, + numeric = LC_NUMERIC_MASK, + time = LC_TIME_MASK, + messages = LC_MESSAGES_MASK, + all = collate | ctype | monetary | numeric | time | messages; + + // construct/copy/destroy: + locale() _NOEXCEPT; + locale(const locale&) _NOEXCEPT; + explicit locale(const char*); + explicit locale(const string&); + locale(const locale&, const char*, category); + locale(const locale&, const string&, category); + template + _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*); + locale(const locale&, const locale&, category); + + ~locale(); + + const locale& operator=(const locale&) _NOEXCEPT; + + template locale combine(const locale&) const; + + // locale operations: + string name() const; + bool operator==(const locale&) const; + bool operator!=(const locale& __y) const {return !(*this == __y);} + template + bool operator()(const basic_string<_CharT, _Traits, _Allocator>&, + const basic_string<_CharT, _Traits, _Allocator>&) const; + + // global locale objects: + static locale global(const locale&); + static const locale& classic(); + +private: + class __imp; + __imp* __locale_; + + void __install_ctor(const locale&, facet*, long); + static locale& __global(); + bool has_facet(id&) const; + const facet* use_facet(id&) const; + + template friend bool has_facet(const locale&) _NOEXCEPT; + template friend const _Facet& use_facet(const locale&); +}; + +class _LIBCPP_TYPE_VIS locale::facet + : public __shared_count +{ +protected: + _LIBCPP_INLINE_VISIBILITY + explicit facet(size_t __refs = 0) + : __shared_count(static_cast(__refs)-1) {} + + virtual ~facet(); + +// facet(const facet&) = delete; // effectively done in __shared_count +// void operator=(const facet&) = delete; +private: + virtual void __on_zero_shared() _NOEXCEPT; +}; + +class _LIBCPP_TYPE_VIS locale::id +{ + once_flag __flag_; + int32_t __id_; + + static int32_t __next_id; +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {} +private: + void __init(); + void operator=(const id&); // = delete; + id(const id&); // = delete; +public: // only needed for tests + long __get(); + + friend class locale; + friend class locale::__imp; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +locale::locale(const locale& __other, _Facet* __f) +{ + __install_ctor(__other, __f, __f ? __f->id.__get() : 0); +} + +template +locale +locale::combine(const locale& __other) const +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + if (!_VSTD::has_facet<_Facet>(__other)) + throw runtime_error("locale::combine: locale missing facet"); +#endif // _LIBCPP_NO_EXCEPTIONS + return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +has_facet(const locale& __l) _NOEXCEPT +{ + return __l.has_facet(_Facet::id); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +const _Facet& +use_facet(const locale& __l) +{ + return static_cast(*__l.use_facet(_Facet::id)); +} + +// template class collate; + +template +class _LIBCPP_TYPE_VIS_ONLY collate + : public locale::facet +{ +public: + typedef _CharT char_type; + typedef basic_string string_type; + + _LIBCPP_INLINE_VISIBILITY + explicit collate(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_INLINE_VISIBILITY + int compare(const char_type* __lo1, const char_type* __hi1, + const char_type* __lo2, const char_type* __hi2) const + { + return do_compare(__lo1, __hi1, __lo2, __hi2); + } + + _LIBCPP_INLINE_VISIBILITY + string_type transform(const char_type* __lo, const char_type* __hi) const + { + return do_transform(__lo, __hi); + } + + _LIBCPP_INLINE_VISIBILITY + long hash(const char_type* __lo, const char_type* __hi) const + { + return do_hash(__lo, __hi); + } + + static locale::id id; + +protected: + ~collate(); + virtual int do_compare(const char_type* __lo1, const char_type* __hi1, + const char_type* __lo2, const char_type* __hi2) const; + virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const + {return string_type(__lo, __hi);} + virtual long do_hash(const char_type* __lo, const char_type* __hi) const; +}; + +template locale::id collate<_CharT>::id; + +template +collate<_CharT>::~collate() +{ +} + +template +int +collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1, + const char_type* __lo2, const char_type* __hi2) const +{ + for (; __lo2 != __hi2; ++__lo1, ++__lo2) + { + if (__lo1 == __hi1 || *__lo1 < *__lo2) + return -1; + if (*__lo2 < *__lo1) + return 1; + } + return __lo1 != __hi1; +} + +template +long +collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const +{ + size_t __h = 0; + const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8; + const size_t __mask = size_t(0xF) << (__sr + 4); + for(const char_type* __p = __lo; __p != __hi; ++__p) + { + __h = (__h << 4) + static_cast(*__p); + size_t __g = __h & __mask; + __h ^= __g | (__g >> __sr); + } + return static_cast(__h); +} + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate) + +// template class collate_byname; + +template class _LIBCPP_TYPE_VIS_ONLY collate_byname; + +template <> +class _LIBCPP_TYPE_VIS collate_byname + : public collate +{ + locale_t __l; +public: + typedef char char_type; + typedef basic_string string_type; + + explicit collate_byname(const char* __n, size_t __refs = 0); + explicit collate_byname(const string& __n, size_t __refs = 0); + +protected: + ~collate_byname(); + virtual int do_compare(const char_type* __lo1, const char_type* __hi1, + const char_type* __lo2, const char_type* __hi2) const; + virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const; +}; + +template <> +class _LIBCPP_TYPE_VIS collate_byname + : public collate +{ + locale_t __l; +public: + typedef wchar_t char_type; + typedef basic_string string_type; + + explicit collate_byname(const char* __n, size_t __refs = 0); + explicit collate_byname(const string& __n, size_t __refs = 0); + +protected: + ~collate_byname(); + + virtual int do_compare(const char_type* __lo1, const char_type* __hi1, + const char_type* __lo2, const char_type* __hi2) const; + virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const; +}; + +template +bool +locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x, + const basic_string<_CharT, _Traits, _Allocator>& __y) const +{ + return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare( + __x.data(), __x.data() + __x.size(), + __y.data(), __y.data() + __y.size()) < 0; +} + +// template class ctype + +class _LIBCPP_TYPE_VIS ctype_base +{ +public: +#ifdef __GLIBC__ + typedef unsigned short mask; + static const mask space = _ISspace; + static const mask print = _ISprint; + static const mask cntrl = _IScntrl; + static const mask upper = _ISupper; + static const mask lower = _ISlower; + static const mask alpha = _ISalpha; + static const mask digit = _ISdigit; + static const mask punct = _ISpunct; + static const mask xdigit = _ISxdigit; + static const mask blank = _ISblank; +#elif defined(_WIN32) + typedef unsigned short mask; + static const mask space = _SPACE; + static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT; + static const mask cntrl = _CONTROL; + static const mask upper = _UPPER; + static const mask lower = _LOWER; + static const mask alpha = _ALPHA; + static const mask digit = _DIGIT; + static const mask punct = _PUNCT; + static const mask xdigit = _HEX; + static const mask blank = _BLANK; +# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) +# ifdef __APPLE__ + typedef __uint32_t mask; +# elif defined(__FreeBSD__) + typedef unsigned long mask; +# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__) + typedef unsigned short mask; +# endif + static const mask space = _CTYPE_S; + static const mask print = _CTYPE_R; + static const mask cntrl = _CTYPE_C; + static const mask upper = _CTYPE_U; + static const mask lower = _CTYPE_L; + static const mask alpha = _CTYPE_A; + static const mask digit = _CTYPE_D; + static const mask punct = _CTYPE_P; + static const mask xdigit = _CTYPE_X; + +# if defined(__NetBSD__) + static const mask blank = _CTYPE_BL; +# else + static const mask blank = _CTYPE_B; +# endif +#elif defined(__sun__) || defined(_AIX) + typedef unsigned int mask; + static const mask space = _ISSPACE; + static const mask print = _ISPRINT; + static const mask cntrl = _ISCNTRL; + static const mask upper = _ISUPPER; + static const mask lower = _ISLOWER; + static const mask alpha = _ISALPHA; + static const mask digit = _ISDIGIT; + static const mask punct = _ISPUNCT; + static const mask xdigit = _ISXDIGIT; + static const mask blank = _ISBLANK; +#elif defined(_NEWLIB_VERSION) + // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h. + typedef char mask; + static const mask space = _S; + static const mask print = _P | _U | _L | _N | _B; + static const mask cntrl = _C; + static const mask upper = _U; + static const mask lower = _L; + static const mask alpha = _U | _L; + static const mask digit = _N; + static const mask punct = _P; + static const mask xdigit = _X | _N; + static const mask blank = _B; +# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT +# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA +# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT +#else + typedef unsigned long mask; + static const mask space = 1<<0; + static const mask print = 1<<1; + static const mask cntrl = 1<<2; + static const mask upper = 1<<3; + static const mask lower = 1<<4; + static const mask alpha = 1<<5; + static const mask digit = 1<<6; + static const mask punct = 1<<7; + static const mask xdigit = 1<<8; + static const mask blank = 1<<9; +#endif + static const mask alnum = alpha | digit; + static const mask graph = alnum | punct; + + _LIBCPP_ALWAYS_INLINE ctype_base() {} +}; + +template class _LIBCPP_TYPE_VIS_ONLY ctype; + +template <> +class _LIBCPP_TYPE_VIS ctype + : public locale::facet, + public ctype_base +{ +public: + typedef wchar_t char_type; + + _LIBCPP_ALWAYS_INLINE + explicit ctype(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_ALWAYS_INLINE + bool is(mask __m, char_type __c) const + { + return do_is(__m, __c); + } + + _LIBCPP_ALWAYS_INLINE + const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const + { + return do_is(__low, __high, __vec); + } + + _LIBCPP_ALWAYS_INLINE + const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const + { + return do_scan_is(__m, __low, __high); + } + + _LIBCPP_ALWAYS_INLINE + const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const + { + return do_scan_not(__m, __low, __high); + } + + _LIBCPP_ALWAYS_INLINE + char_type toupper(char_type __c) const + { + return do_toupper(__c); + } + + _LIBCPP_ALWAYS_INLINE + const char_type* toupper(char_type* __low, const char_type* __high) const + { + return do_toupper(__low, __high); + } + + _LIBCPP_ALWAYS_INLINE + char_type tolower(char_type __c) const + { + return do_tolower(__c); + } + + _LIBCPP_ALWAYS_INLINE + const char_type* tolower(char_type* __low, const char_type* __high) const + { + return do_tolower(__low, __high); + } + + _LIBCPP_ALWAYS_INLINE + char_type widen(char __c) const + { + return do_widen(__c); + } + + _LIBCPP_ALWAYS_INLINE + const char* widen(const char* __low, const char* __high, char_type* __to) const + { + return do_widen(__low, __high, __to); + } + + _LIBCPP_ALWAYS_INLINE + char narrow(char_type __c, char __dfault) const + { + return do_narrow(__c, __dfault); + } + + _LIBCPP_ALWAYS_INLINE + const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const + { + return do_narrow(__low, __high, __dfault, __to); + } + + static locale::id id; + +protected: + ~ctype(); + virtual bool do_is(mask __m, char_type __c) const; + virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const; + virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const; + virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const; + virtual char_type do_toupper(char_type) const; + virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; + virtual char_type do_tolower(char_type) const; + virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; + virtual char_type do_widen(char) const; + virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const; + virtual char do_narrow(char_type, char __dfault) const; + virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const; +}; + +template <> +class _LIBCPP_TYPE_VIS ctype + : public locale::facet, public ctype_base +{ + const mask* __tab_; + bool __del_; +public: + typedef char char_type; + + explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0); + + _LIBCPP_ALWAYS_INLINE + bool is(mask __m, char_type __c) const + { + return isascii(__c) ? (__tab_[static_cast(__c)] & __m) !=0 : false; + } + + _LIBCPP_ALWAYS_INLINE + const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const + { + for (; __low != __high; ++__low, ++__vec) + *__vec = isascii(*__low) ? __tab_[static_cast(*__low)] : 0; + return __low; + } + + _LIBCPP_ALWAYS_INLINE + const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const + { + for (; __low != __high; ++__low) + if (isascii(*__low) && (__tab_[static_cast(*__low)] & __m)) + break; + return __low; + } + + _LIBCPP_ALWAYS_INLINE + const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const + { + for (; __low != __high; ++__low) + if (!(isascii(*__low) && (__tab_[static_cast(*__low)] & __m))) + break; + return __low; + } + + _LIBCPP_ALWAYS_INLINE + char_type toupper(char_type __c) const + { + return do_toupper(__c); + } + + _LIBCPP_ALWAYS_INLINE + const char_type* toupper(char_type* __low, const char_type* __high) const + { + return do_toupper(__low, __high); + } + + _LIBCPP_ALWAYS_INLINE + char_type tolower(char_type __c) const + { + return do_tolower(__c); + } + + _LIBCPP_ALWAYS_INLINE + const char_type* tolower(char_type* __low, const char_type* __high) const + { + return do_tolower(__low, __high); + } + + _LIBCPP_ALWAYS_INLINE + char_type widen(char __c) const + { + return do_widen(__c); + } + + _LIBCPP_ALWAYS_INLINE + const char* widen(const char* __low, const char* __high, char_type* __to) const + { + return do_widen(__low, __high, __to); + } + + _LIBCPP_ALWAYS_INLINE + char narrow(char_type __c, char __dfault) const + { + return do_narrow(__c, __dfault); + } + + _LIBCPP_ALWAYS_INLINE + const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const + { + return do_narrow(__low, __high, __dfault, __to); + } + + static locale::id id; + +#ifdef _CACHED_RUNES + static const size_t table_size = _CACHED_RUNES; +#else + static const size_t table_size = 256; // FIXME: Don't hardcode this. +#endif + _LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;} + static const mask* classic_table() _NOEXCEPT; +#if defined(__GLIBC__) || defined(__EMSCRIPTEN__) + static const int* __classic_upper_table() _NOEXCEPT; + static const int* __classic_lower_table() _NOEXCEPT; +#endif +#if defined(__NetBSD__) + static const short* __classic_upper_table() _NOEXCEPT; + static const short* __classic_lower_table() _NOEXCEPT; +#endif + +protected: + ~ctype(); + virtual char_type do_toupper(char_type __c) const; + virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; + virtual char_type do_tolower(char_type __c) const; + virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; + virtual char_type do_widen(char __c) const; + virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const; + virtual char do_narrow(char_type __c, char __dfault) const; + virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const; +}; + +// template class ctype_byname; + +template class _LIBCPP_TYPE_VIS_ONLY ctype_byname; + +template <> +class _LIBCPP_TYPE_VIS ctype_byname + : public ctype +{ + locale_t __l; + +public: + explicit ctype_byname(const char*, size_t = 0); + explicit ctype_byname(const string&, size_t = 0); + +protected: + ~ctype_byname(); + virtual char_type do_toupper(char_type) const; + virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; + virtual char_type do_tolower(char_type) const; + virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; +}; + +template <> +class _LIBCPP_TYPE_VIS ctype_byname + : public ctype +{ + locale_t __l; + +public: + explicit ctype_byname(const char*, size_t = 0); + explicit ctype_byname(const string&, size_t = 0); + +protected: + ~ctype_byname(); + virtual bool do_is(mask __m, char_type __c) const; + virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const; + virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const; + virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const; + virtual char_type do_toupper(char_type) const; + virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; + virtual char_type do_tolower(char_type) const; + virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; + virtual char_type do_widen(char) const; + virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const; + virtual char do_narrow(char_type, char __dfault) const; + virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isspace(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::space, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isprint(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::print, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +iscntrl(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::cntrl, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isupper(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::upper, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +islower(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::lower, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isalpha(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::alpha, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isdigit(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::digit, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +ispunct(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::punct, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isxdigit(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::xdigit, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isalnum(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::alnum, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +isgraph(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).is(ctype_base::graph, __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_CharT +toupper(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).toupper(__c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_CharT +tolower(_CharT __c, const locale& __loc) +{ + return use_facet >(__loc).tolower(__c); +} + +// codecvt_base + +class _LIBCPP_TYPE_VIS codecvt_base +{ +public: + _LIBCPP_ALWAYS_INLINE codecvt_base() {} + enum result {ok, partial, error, noconv}; +}; + +// template class codecvt; + +template class _LIBCPP_TYPE_VIS_ONLY codecvt; + +// template <> class codecvt + +template <> +class _LIBCPP_TYPE_VIS codecvt + : public locale::facet, + public codecvt_base +{ +public: + typedef char intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit codecvt(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_ALWAYS_INLINE + result out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_ALWAYS_INLINE + result unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_unshift(__st, __to, __to_end, __to_nxt); + } + + _LIBCPP_ALWAYS_INLINE + result in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const + { + return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_ALWAYS_INLINE + int encoding() const _NOEXCEPT + { + return do_encoding(); + } + + _LIBCPP_ALWAYS_INLINE + bool always_noconv() const _NOEXCEPT + { + return do_always_noconv(); + } + + _LIBCPP_ALWAYS_INLINE + int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const + { + return do_length(__st, __frm, __end, __mx); + } + + _LIBCPP_ALWAYS_INLINE + int max_length() const _NOEXCEPT + { + return do_max_length(); + } + + static locale::id id; + +protected: + _LIBCPP_ALWAYS_INLINE + explicit codecvt(const char*, size_t __refs = 0) + : locale::facet(__refs) {} + + ~codecvt(); + + virtual result do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; + virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const; + virtual int do_max_length() const _NOEXCEPT; +}; + +// template <> class codecvt + +template <> +class _LIBCPP_TYPE_VIS codecvt + : public locale::facet, + public codecvt_base +{ + locale_t __l; +public: + typedef wchar_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + explicit codecvt(size_t __refs = 0); + + _LIBCPP_ALWAYS_INLINE + result out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_ALWAYS_INLINE + result unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_unshift(__st, __to, __to_end, __to_nxt); + } + + _LIBCPP_ALWAYS_INLINE + result in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const + { + return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_ALWAYS_INLINE + int encoding() const _NOEXCEPT + { + return do_encoding(); + } + + _LIBCPP_ALWAYS_INLINE + bool always_noconv() const _NOEXCEPT + { + return do_always_noconv(); + } + + _LIBCPP_ALWAYS_INLINE + int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const + { + return do_length(__st, __frm, __end, __mx); + } + + _LIBCPP_ALWAYS_INLINE + int max_length() const _NOEXCEPT + { + return do_max_length(); + } + + static locale::id id; + +protected: + explicit codecvt(const char*, size_t __refs = 0); + + ~codecvt(); + + virtual result do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; + virtual int do_max_length() const _NOEXCEPT; +}; + +// template <> class codecvt + +template <> +class _LIBCPP_TYPE_VIS codecvt + : public locale::facet, + public codecvt_base +{ +public: + typedef char16_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit codecvt(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_ALWAYS_INLINE + result out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_ALWAYS_INLINE + result unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_unshift(__st, __to, __to_end, __to_nxt); + } + + _LIBCPP_ALWAYS_INLINE + result in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const + { + return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_ALWAYS_INLINE + int encoding() const _NOEXCEPT + { + return do_encoding(); + } + + _LIBCPP_ALWAYS_INLINE + bool always_noconv() const _NOEXCEPT + { + return do_always_noconv(); + } + + _LIBCPP_ALWAYS_INLINE + int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const + { + return do_length(__st, __frm, __end, __mx); + } + + _LIBCPP_ALWAYS_INLINE + int max_length() const _NOEXCEPT + { + return do_max_length(); + } + + static locale::id id; + +protected: + _LIBCPP_ALWAYS_INLINE + explicit codecvt(const char*, size_t __refs = 0) + : locale::facet(__refs) {} + + ~codecvt(); + + virtual result do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; + virtual int do_max_length() const _NOEXCEPT; +}; + +// template <> class codecvt + +template <> +class _LIBCPP_TYPE_VIS codecvt + : public locale::facet, + public codecvt_base +{ +public: + typedef char32_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit codecvt(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_ALWAYS_INLINE + result out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_ALWAYS_INLINE + result unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_unshift(__st, __to, __to_end, __to_nxt); + } + + _LIBCPP_ALWAYS_INLINE + result in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const + { + return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_ALWAYS_INLINE + int encoding() const _NOEXCEPT + { + return do_encoding(); + } + + _LIBCPP_ALWAYS_INLINE + bool always_noconv() const _NOEXCEPT + { + return do_always_noconv(); + } + + _LIBCPP_ALWAYS_INLINE + int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const + { + return do_length(__st, __frm, __end, __mx); + } + + _LIBCPP_ALWAYS_INLINE + int max_length() const _NOEXCEPT + { + return do_max_length(); + } + + static locale::id id; + +protected: + _LIBCPP_ALWAYS_INLINE + explicit codecvt(const char*, size_t __refs = 0) + : locale::facet(__refs) {} + + ~codecvt(); + + virtual result do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; + virtual int do_max_length() const _NOEXCEPT; +}; + +// template class codecvt_byname + +template +class _LIBCPP_TYPE_VIS_ONLY codecvt_byname + : public codecvt<_InternT, _ExternT, _StateT> +{ +public: + _LIBCPP_ALWAYS_INLINE + explicit codecvt_byname(const char* __nm, size_t __refs = 0) + : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {} + _LIBCPP_ALWAYS_INLINE + explicit codecvt_byname(const string& __nm, size_t __refs = 0) + : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {} +protected: + ~codecvt_byname(); +}; + +template +codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname() +{ +} + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname) + +_LIBCPP_FUNC_VIS void __throw_runtime_error(const char*); + +template +struct __narrow_to_utf8 +{ + template + _OutputIterator + operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const; +}; + +template <> +struct __narrow_to_utf8<8> +{ + template + _LIBCPP_ALWAYS_INLINE + _OutputIterator + operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const + { + for (; __wb < __we; ++__wb, ++__s) + *__s = *__wb; + return __s; + } +}; + +template <> +struct __narrow_to_utf8<16> + : public codecvt +{ + _LIBCPP_ALWAYS_INLINE + __narrow_to_utf8() : codecvt(1) {} + + ~__narrow_to_utf8(); + + template + _LIBCPP_ALWAYS_INLINE + _OutputIterator + operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const + { + result __r = ok; + mbstate_t __mb; + while (__wb < __we && __r != error) + { + const int __sz = 32; + char __buf[__sz]; + char* __bn; + const char16_t* __wn = (const char16_t*)__wb; + __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn, + __buf, __buf+__sz, __bn); + if (__r == codecvt_base::error || __wn == (const char16_t*)__wb) + __throw_runtime_error("locale not supported"); + for (const char* __p = __buf; __p < __bn; ++__p, ++__s) + *__s = *__p; + __wb = (const _CharT*)__wn; + } + return __s; + } +}; + +template <> +struct __narrow_to_utf8<32> + : public codecvt +{ + _LIBCPP_ALWAYS_INLINE + __narrow_to_utf8() : codecvt(1) {} + + ~__narrow_to_utf8(); + + template + _LIBCPP_ALWAYS_INLINE + _OutputIterator + operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const + { + result __r = ok; + mbstate_t __mb; + while (__wb < __we && __r != error) + { + const int __sz = 32; + char __buf[__sz]; + char* __bn; + const char32_t* __wn = (const char32_t*)__wb; + __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn, + __buf, __buf+__sz, __bn); + if (__r == codecvt_base::error || __wn == (const char32_t*)__wb) + __throw_runtime_error("locale not supported"); + for (const char* __p = __buf; __p < __bn; ++__p, ++__s) + *__s = *__p; + __wb = (const _CharT*)__wn; + } + return __s; + } +}; + +template +struct __widen_from_utf8 +{ + template + _OutputIterator + operator()(_OutputIterator __s, const char* __nb, const char* __ne) const; +}; + +template <> +struct __widen_from_utf8<8> +{ + template + _LIBCPP_ALWAYS_INLINE + _OutputIterator + operator()(_OutputIterator __s, const char* __nb, const char* __ne) const + { + for (; __nb < __ne; ++__nb, ++__s) + *__s = *__nb; + return __s; + } +}; + +template <> +struct __widen_from_utf8<16> + : public codecvt +{ + _LIBCPP_ALWAYS_INLINE + __widen_from_utf8() : codecvt(1) {} + + ~__widen_from_utf8(); + + template + _LIBCPP_ALWAYS_INLINE + _OutputIterator + operator()(_OutputIterator __s, const char* __nb, const char* __ne) const + { + result __r = ok; + mbstate_t __mb; + while (__nb < __ne && __r != error) + { + const int __sz = 32; + char16_t __buf[__sz]; + char16_t* __bn; + const char* __nn = __nb; + __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, + __buf, __buf+__sz, __bn); + if (__r == codecvt_base::error || __nn == __nb) + __throw_runtime_error("locale not supported"); + for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s) + *__s = (wchar_t)*__p; + __nb = __nn; + } + return __s; + } +}; + +template <> +struct __widen_from_utf8<32> + : public codecvt +{ + _LIBCPP_ALWAYS_INLINE + __widen_from_utf8() : codecvt(1) {} + + ~__widen_from_utf8(); + + template + _LIBCPP_ALWAYS_INLINE + _OutputIterator + operator()(_OutputIterator __s, const char* __nb, const char* __ne) const + { + result __r = ok; + mbstate_t __mb; + while (__nb < __ne && __r != error) + { + const int __sz = 32; + char32_t __buf[__sz]; + char32_t* __bn; + const char* __nn = __nb; + __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, + __buf, __buf+__sz, __bn); + if (__r == codecvt_base::error || __nn == __nb) + __throw_runtime_error("locale not supported"); + for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s) + *__s = (wchar_t)*__p; + __nb = __nn; + } + return __s; + } +}; + +// template class numpunct + +template class _LIBCPP_TYPE_VIS_ONLY numpunct; + +template <> +class _LIBCPP_TYPE_VIS numpunct + : public locale::facet +{ +public: + typedef char char_type; + typedef basic_string string_type; + + explicit numpunct(size_t __refs = 0); + + _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();} + _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();} + _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();} + _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();} + _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();} + + static locale::id id; + +protected: + ~numpunct(); + virtual char_type do_decimal_point() const; + virtual char_type do_thousands_sep() const; + virtual string do_grouping() const; + virtual string_type do_truename() const; + virtual string_type do_falsename() const; + + char_type __decimal_point_; + char_type __thousands_sep_; + string __grouping_; +}; + +template <> +class _LIBCPP_TYPE_VIS numpunct + : public locale::facet +{ +public: + typedef wchar_t char_type; + typedef basic_string string_type; + + explicit numpunct(size_t __refs = 0); + + _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();} + _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();} + _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();} + _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();} + _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();} + + static locale::id id; + +protected: + ~numpunct(); + virtual char_type do_decimal_point() const; + virtual char_type do_thousands_sep() const; + virtual string do_grouping() const; + virtual string_type do_truename() const; + virtual string_type do_falsename() const; + + char_type __decimal_point_; + char_type __thousands_sep_; + string __grouping_; +}; + +// template class numpunct_byname + +template class _LIBCPP_TYPE_VIS_ONLY numpunct_byname; + +template <> +class _LIBCPP_TYPE_VIS numpunct_byname +: public numpunct +{ +public: + typedef char char_type; + typedef basic_string string_type; + + explicit numpunct_byname(const char* __nm, size_t __refs = 0); + explicit numpunct_byname(const string& __nm, size_t __refs = 0); + +protected: + ~numpunct_byname(); + +private: + void __init(const char*); +}; + +template <> +class _LIBCPP_TYPE_VIS numpunct_byname +: public numpunct +{ +public: + typedef wchar_t char_type; + typedef basic_string string_type; + + explicit numpunct_byname(const char* __nm, size_t __refs = 0); + explicit numpunct_byname(const string& __nm, size_t __refs = 0); + +protected: + ~numpunct_byname(); + +private: + void __init(const char*); +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___LOCALE diff --git a/headers/libs/libc++/__mutex_base b/headers/libs/libc++/__mutex_base new file mode 100644 index 0000000000..b019b4760d --- /dev/null +++ b/headers/libs/libc++/__mutex_base @@ -0,0 +1,410 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___MUTEX_BASE +#define _LIBCPP___MUTEX_BASE + +#include <__config> +#include +#include +#ifndef _LIBCPP_HAS_NO_THREADS +#include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_HAS_NO_THREADS + +class _LIBCPP_TYPE_VIS mutex +{ + pthread_mutex_t __m_; + +public: + _LIBCPP_INLINE_VISIBILITY +#ifndef _LIBCPP_HAS_NO_CONSTEXPR + constexpr mutex() _NOEXCEPT : __m_(PTHREAD_MUTEX_INITIALIZER) {} +#else + mutex() _NOEXCEPT {__m_ = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;} +#endif + ~mutex(); + +private: + mutex(const mutex&);// = delete; + mutex& operator=(const mutex&);// = delete; + +public: + void lock(); + bool try_lock() _NOEXCEPT; + void unlock() _NOEXCEPT; + + typedef pthread_mutex_t* native_handle_type; + _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;} +}; + +struct _LIBCPP_TYPE_VIS defer_lock_t {}; +struct _LIBCPP_TYPE_VIS try_to_lock_t {}; +struct _LIBCPP_TYPE_VIS adopt_lock_t {}; + +#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MUTEX) + +extern const defer_lock_t defer_lock; +extern const try_to_lock_t try_to_lock; +extern const adopt_lock_t adopt_lock; + +#else + +constexpr defer_lock_t defer_lock = defer_lock_t(); +constexpr try_to_lock_t try_to_lock = try_to_lock_t(); +constexpr adopt_lock_t adopt_lock = adopt_lock_t(); + +#endif + +template +class _LIBCPP_TYPE_VIS_ONLY lock_guard +{ +public: + typedef _Mutex mutex_type; + +private: + mutex_type& __m_; +public: + + _LIBCPP_INLINE_VISIBILITY + explicit lock_guard(mutex_type& __m) + : __m_(__m) {__m_.lock();} + _LIBCPP_INLINE_VISIBILITY + lock_guard(mutex_type& __m, adopt_lock_t) + : __m_(__m) {} + _LIBCPP_INLINE_VISIBILITY + ~lock_guard() {__m_.unlock();} + +private: + lock_guard(lock_guard const&);// = delete; + lock_guard& operator=(lock_guard const&);// = delete; +}; + +template +class _LIBCPP_TYPE_VIS_ONLY unique_lock +{ +public: + typedef _Mutex mutex_type; + +private: + mutex_type* __m_; + bool __owns_; + +public: + _LIBCPP_INLINE_VISIBILITY + unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {} + _LIBCPP_INLINE_VISIBILITY + explicit unique_lock(mutex_type& __m) + : __m_(&__m), __owns_(true) {__m_->lock();} + _LIBCPP_INLINE_VISIBILITY + unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT + : __m_(&__m), __owns_(false) {} + _LIBCPP_INLINE_VISIBILITY + unique_lock(mutex_type& __m, try_to_lock_t) + : __m_(&__m), __owns_(__m.try_lock()) {} + _LIBCPP_INLINE_VISIBILITY + unique_lock(mutex_type& __m, adopt_lock_t) + : __m_(&__m), __owns_(true) {} + template + _LIBCPP_INLINE_VISIBILITY + unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t) + : __m_(&__m), __owns_(__m.try_lock_until(__t)) {} + template + _LIBCPP_INLINE_VISIBILITY + unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d) + : __m_(&__m), __owns_(__m.try_lock_for(__d)) {} + _LIBCPP_INLINE_VISIBILITY + ~unique_lock() + { + if (__owns_) + __m_->unlock(); + } + +private: + unique_lock(unique_lock const&); // = delete; + unique_lock& operator=(unique_lock const&); // = delete; + +public: +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + unique_lock(unique_lock&& __u) _NOEXCEPT + : __m_(__u.__m_), __owns_(__u.__owns_) + {__u.__m_ = nullptr; __u.__owns_ = false;} + _LIBCPP_INLINE_VISIBILITY + unique_lock& operator=(unique_lock&& __u) _NOEXCEPT + { + if (__owns_) + __m_->unlock(); + __m_ = __u.__m_; + __owns_ = __u.__owns_; + __u.__m_ = nullptr; + __u.__owns_ = false; + return *this; + } + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + void lock(); + bool try_lock(); + + template + bool try_lock_for(const chrono::duration<_Rep, _Period>& __d); + template + bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); + + void unlock(); + + _LIBCPP_INLINE_VISIBILITY + void swap(unique_lock& __u) _NOEXCEPT + { + _VSTD::swap(__m_, __u.__m_); + _VSTD::swap(__owns_, __u.__owns_); + } + _LIBCPP_INLINE_VISIBILITY + mutex_type* release() _NOEXCEPT + { + mutex_type* __m = __m_; + __m_ = nullptr; + __owns_ = false; + return __m; + } + + _LIBCPP_INLINE_VISIBILITY + bool owns_lock() const _NOEXCEPT {return __owns_;} + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_EXPLICIT + operator bool () const _NOEXCEPT {return __owns_;} + _LIBCPP_INLINE_VISIBILITY + mutex_type* mutex() const _NOEXCEPT {return __m_;} +}; + +template +void +unique_lock<_Mutex>::lock() +{ + if (__m_ == nullptr) + __throw_system_error(EPERM, "unique_lock::lock: references null mutex"); + if (__owns_) + __throw_system_error(EDEADLK, "unique_lock::lock: already locked"); + __m_->lock(); + __owns_ = true; +} + +template +bool +unique_lock<_Mutex>::try_lock() +{ + if (__m_ == nullptr) + __throw_system_error(EPERM, "unique_lock::try_lock: references null mutex"); + if (__owns_) + __throw_system_error(EDEADLK, "unique_lock::try_lock: already locked"); + __owns_ = __m_->try_lock(); + return __owns_; +} + +template +template +bool +unique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d) +{ + if (__m_ == nullptr) + __throw_system_error(EPERM, "unique_lock::try_lock_for: references null mutex"); + if (__owns_) + __throw_system_error(EDEADLK, "unique_lock::try_lock_for: already locked"); + __owns_ = __m_->try_lock_for(__d); + return __owns_; +} + +template +template +bool +unique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) +{ + if (__m_ == nullptr) + __throw_system_error(EPERM, "unique_lock::try_lock_until: references null mutex"); + if (__owns_) + __throw_system_error(EDEADLK, "unique_lock::try_lock_until: already locked"); + __owns_ = __m_->try_lock_until(__t); + return __owns_; +} + +template +void +unique_lock<_Mutex>::unlock() +{ + if (!__owns_) + __throw_system_error(EPERM, "unique_lock::unlock: not locked"); + __m_->unlock(); + __owns_ = false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT + {__x.swap(__y);} + +//enum class cv_status +_LIBCPP_DECLARE_STRONG_ENUM(cv_status) +{ + no_timeout, + timeout +}; +_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status) + +class _LIBCPP_TYPE_VIS condition_variable +{ + pthread_cond_t __cv_; +public: + _LIBCPP_INLINE_VISIBILITY +#ifndef _LIBCPP_HAS_NO_CONSTEXPR + constexpr condition_variable() : __cv_(PTHREAD_COND_INITIALIZER) {} +#else + condition_variable() {__cv_ = (pthread_cond_t)PTHREAD_COND_INITIALIZER;} +#endif + ~condition_variable(); + +private: + condition_variable(const condition_variable&); // = delete; + condition_variable& operator=(const condition_variable&); // = delete; + +public: + void notify_one() _NOEXCEPT; + void notify_all() _NOEXCEPT; + + void wait(unique_lock& __lk) _NOEXCEPT; + template + void wait(unique_lock& __lk, _Predicate __pred); + + template + cv_status + wait_until(unique_lock& __lk, + const chrono::time_point<_Clock, _Duration>& __t); + + template + bool + wait_until(unique_lock& __lk, + const chrono::time_point<_Clock, _Duration>& __t, + _Predicate __pred); + + template + cv_status + wait_for(unique_lock& __lk, + const chrono::duration<_Rep, _Period>& __d); + + template + bool + _LIBCPP_INLINE_VISIBILITY + wait_for(unique_lock& __lk, + const chrono::duration<_Rep, _Period>& __d, + _Predicate __pred); + + typedef pthread_cond_t* native_handle_type; + _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;} + +private: + void __do_timed_wait(unique_lock& __lk, + chrono::time_point) _NOEXCEPT; +}; +#endif // !_LIBCPP_HAS_NO_THREADS + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + chrono::__is_duration<_To>::value, + _To +>::type +__ceil(chrono::duration<_Rep, _Period> __d) +{ + using namespace chrono; + _To __r = duration_cast<_To>(__d); + if (__r < __d) + ++__r; + return __r; +} + +#ifndef _LIBCPP_HAS_NO_THREADS +template +void +condition_variable::wait(unique_lock& __lk, _Predicate __pred) +{ + while (!__pred()) + wait(__lk); +} + +template +cv_status +condition_variable::wait_until(unique_lock& __lk, + const chrono::time_point<_Clock, _Duration>& __t) +{ + using namespace chrono; + wait_for(__lk, __t - _Clock::now()); + return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout; +} + +template +bool +condition_variable::wait_until(unique_lock& __lk, + const chrono::time_point<_Clock, _Duration>& __t, + _Predicate __pred) +{ + while (!__pred()) + { + if (wait_until(__lk, __t) == cv_status::timeout) + return __pred(); + } + return true; +} + +template +cv_status +condition_variable::wait_for(unique_lock& __lk, + const chrono::duration<_Rep, _Period>& __d) +{ + using namespace chrono; + if (__d <= __d.zero()) + return cv_status::timeout; + typedef time_point > __sys_tpf; + typedef time_point __sys_tpi; + __sys_tpf _Max = __sys_tpi::max(); + system_clock::time_point __s_now = system_clock::now(); + steady_clock::time_point __c_now = steady_clock::now(); + if (_Max - __d > __s_now) + __do_timed_wait(__lk, __s_now + __ceil(__d)); + else + __do_timed_wait(__lk, __sys_tpi::max()); + return steady_clock::now() - __c_now < __d ? cv_status::no_timeout : + cv_status::timeout; +} + +template +inline +bool +condition_variable::wait_for(unique_lock& __lk, + const chrono::duration<_Rep, _Period>& __d, + _Predicate __pred) +{ + return wait_until(__lk, chrono::steady_clock::now() + __d, + _VSTD::move(__pred)); +} + +#endif // !_LIBCPP_HAS_NO_THREADS + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MUTEX_BASE diff --git a/headers/libs/libc++/__nullptr b/headers/libs/libc++/__nullptr new file mode 100644 index 0000000000..95415a6325 --- /dev/null +++ b/headers/libs/libc++/__nullptr @@ -0,0 +1,66 @@ +// -*- C++ -*- +//===--------------------------- __nullptr --------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_NULLPTR +#define _LIBCPP_NULLPTR + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifdef _LIBCPP_HAS_NO_NULLPTR + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct _LIBCPP_TYPE_VIS_ONLY nullptr_t +{ + void* __lx; + + struct __nat {int __for_bool_;}; + + _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {} + _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {} + + _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;} + + template + _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR + operator _Tp* () const {return 0;} + + template + _LIBCPP_ALWAYS_INLINE + operator _Tp _Up::* () const {return 0;} + + friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;} + friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;} + friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator<(nullptr_t, nullptr_t) {return false;} + friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator<=(nullptr_t, nullptr_t) {return true;} + friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator>(nullptr_t, nullptr_t) {return false;} + friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator>=(nullptr_t, nullptr_t) {return true;} +}; + +inline _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);} + +#define nullptr _VSTD::__get_nullptr_t() + +_LIBCPP_END_NAMESPACE_STD + +#else // _LIBCPP_HAS_NO_NULLPTR + +namespace std +{ + typedef decltype(nullptr) nullptr_t; +} + +#endif // _LIBCPP_HAS_NO_NULLPTR + +#endif // _LIBCPP_NULLPTR diff --git a/headers/libs/libc++/__refstring b/headers/libs/libc++/__refstring new file mode 100644 index 0000000000..61ccc75122 --- /dev/null +++ b/headers/libs/libc++/__refstring @@ -0,0 +1,139 @@ +//===------------------------ __refstring ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___REFSTRING +#define _LIBCPP___REFSTRING + +#include <__config> +#include +#include +#ifdef __APPLE__ +#include +#include +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +class _LIBCPP_HIDDEN __libcpp_refstring +{ +private: + const char* str_; + + typedef int count_t; + + struct _Rep_base + { + std::size_t len; + std::size_t cap; + count_t count; + }; + + static + _Rep_base* + rep_from_data(const char *data_) _NOEXCEPT + { + char *data = const_cast(data_); + return reinterpret_cast<_Rep_base *>(data - sizeof(_Rep_base)); + } + static + char * + data_from_rep(_Rep_base *rep) _NOEXCEPT + { + char *data = reinterpret_cast(rep); + return data + sizeof(*rep); + } + +#ifdef __APPLE__ + static + const char* + compute_gcc_empty_string_storage() _NOEXCEPT + { + void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD); + if (handle == nullptr) + return nullptr; + void* sym = dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE"); + if (sym == nullptr) + return nullptr; + return data_from_rep(reinterpret_cast<_Rep_base *>(sym)); + } + + static + const char* + get_gcc_empty_string_storage() _NOEXCEPT + { + static const char* p = compute_gcc_empty_string_storage(); + return p; + } + + bool + uses_refcount() const + { + return str_ != get_gcc_empty_string_storage(); + } +#else + bool + uses_refcount() const + { + return true; + } +#endif + +public: + explicit __libcpp_refstring(const char* msg) { + std::size_t len = strlen(msg); + _Rep_base* rep = static_cast<_Rep_base *>(::operator new(sizeof(*rep) + len + 1)); + rep->len = len; + rep->cap = len; + rep->count = 0; + char *data = data_from_rep(rep); + std::memcpy(data, msg, len + 1); + str_ = data; + } + + __libcpp_refstring(const __libcpp_refstring& s) _NOEXCEPT : str_(s.str_) + { + if (uses_refcount()) + __sync_add_and_fetch(&rep_from_data(str_)->count, 1); + } + + __libcpp_refstring& operator=(const __libcpp_refstring& s) _NOEXCEPT + { + bool adjust_old_count = uses_refcount(); + struct _Rep_base *old_rep = rep_from_data(str_); + str_ = s.str_; + if (uses_refcount()) + __sync_add_and_fetch(&rep_from_data(str_)->count, 1); + if (adjust_old_count) + { + if (__sync_add_and_fetch(&old_rep->count, count_t(-1)) < 0) + { + ::operator delete(old_rep); + } + } + return *this; + } + + ~__libcpp_refstring() + { + if (uses_refcount()) + { + _Rep_base* rep = rep_from_data(str_); + if (__sync_add_and_fetch(&rep->count, count_t(-1)) < 0) + { + ::operator delete(rep); + } + } + } + + const char* c_str() const _NOEXCEPT {return str_;} +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif //_LIBCPP___REFSTRING diff --git a/headers/libs/libc++/__split_buffer b/headers/libs/libc++/__split_buffer new file mode 100644 index 0000000000..79d1aa1d7c --- /dev/null +++ b/headers/libs/libc++/__split_buffer @@ -0,0 +1,640 @@ +// -*- C++ -*- +#ifndef _LIBCPP_SPLIT_BUFFER +#define _LIBCPP_SPLIT_BUFFER + +#include <__config> +#include +#include + +#include <__undef_min_max> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class __split_buffer_common +{ +protected: + void __throw_length_error() const; + void __throw_out_of_range() const; +}; + +template > +struct __split_buffer + : private __split_buffer_common +{ +private: + __split_buffer(const __split_buffer&); + __split_buffer& operator=(const __split_buffer&); +public: + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename remove_reference::type __alloc_rr; + typedef allocator_traits<__alloc_rr> __alloc_traits; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::difference_type difference_type; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; + typedef pointer iterator; + typedef const_pointer const_iterator; + + pointer __first_; + pointer __begin_; + pointer __end_; + __compressed_pair __end_cap_; + + typedef typename add_lvalue_reference::type __alloc_ref; + typedef typename add_lvalue_reference::type __alloc_const_ref; + + _LIBCPP_INLINE_VISIBILITY __alloc_rr& __alloc() _NOEXCEPT {return __end_cap_.second();} + _LIBCPP_INLINE_VISIBILITY const __alloc_rr& __alloc() const _NOEXCEPT {return __end_cap_.second();} + _LIBCPP_INLINE_VISIBILITY pointer& __end_cap() _NOEXCEPT {return __end_cap_.first();} + _LIBCPP_INLINE_VISIBILITY const pointer& __end_cap() const _NOEXCEPT {return __end_cap_.first();} + + _LIBCPP_INLINE_VISIBILITY + __split_buffer() + _NOEXCEPT_(is_nothrow_default_constructible::value); + _LIBCPP_INLINE_VISIBILITY + explicit __split_buffer(__alloc_rr& __a); + _LIBCPP_INLINE_VISIBILITY + explicit __split_buffer(const __alloc_rr& __a); + __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a); + ~__split_buffer(); + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + __split_buffer(__split_buffer&& __c) + _NOEXCEPT_(is_nothrow_move_constructible::value); + __split_buffer(__split_buffer&& __c, const __alloc_rr& __a); + __split_buffer& operator=(__split_buffer&& __c) + _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value) || + !__alloc_traits::propagate_on_container_move_assignment::value); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + _LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT {return __begin_;} + _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __begin_;} + _LIBCPP_INLINE_VISIBILITY iterator end() _NOEXCEPT {return __end_;} + _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT {return __end_;} + + _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT + {__destruct_at_end(__begin_);} + _LIBCPP_INLINE_VISIBILITY size_type size() const {return static_cast(__end_ - __begin_);} + _LIBCPP_INLINE_VISIBILITY bool empty() const {return __end_ == __begin_;} + _LIBCPP_INLINE_VISIBILITY size_type capacity() const {return static_cast(__end_cap() - __first_);} + _LIBCPP_INLINE_VISIBILITY size_type __front_spare() const {return static_cast(__begin_ - __first_);} + _LIBCPP_INLINE_VISIBILITY size_type __back_spare() const {return static_cast(__end_cap() - __end_);} + + _LIBCPP_INLINE_VISIBILITY reference front() {return *__begin_;} + _LIBCPP_INLINE_VISIBILITY const_reference front() const {return *__begin_;} + _LIBCPP_INLINE_VISIBILITY reference back() {return *(__end_ - 1);} + _LIBCPP_INLINE_VISIBILITY const_reference back() const {return *(__end_ - 1);} + + void reserve(size_type __n); + void shrink_to_fit() _NOEXCEPT; + void push_front(const_reference __x); + _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x); +#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) + void push_front(value_type&& __x); + void push_back(value_type&& __x); +#if !defined(_LIBCPP_HAS_NO_VARIADICS) + template + void emplace_back(_Args&&... __args); +#endif // !defined(_LIBCPP_HAS_NO_VARIADICS) +#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) + + _LIBCPP_INLINE_VISIBILITY void pop_front() {__destruct_at_begin(__begin_+1);} + _LIBCPP_INLINE_VISIBILITY void pop_back() {__destruct_at_end(__end_-1);} + + void __construct_at_end(size_type __n); + void __construct_at_end(size_type __n, const_reference __x); + template + typename enable_if + < + __is_input_iterator<_InputIter>::value && + !__is_forward_iterator<_InputIter>::value, + void + >::type + __construct_at_end(_InputIter __first, _InputIter __last); + template + typename enable_if + < + __is_forward_iterator<_ForwardIterator>::value, + void + >::type + __construct_at_end(_ForwardIterator __first, _ForwardIterator __last); + + _LIBCPP_INLINE_VISIBILITY void __destruct_at_begin(pointer __new_begin) + {__destruct_at_begin(__new_begin, is_trivially_destructible());} + _LIBCPP_INLINE_VISIBILITY + void __destruct_at_begin(pointer __new_begin, false_type); + _LIBCPP_INLINE_VISIBILITY + void __destruct_at_begin(pointer __new_begin, true_type); + + _LIBCPP_INLINE_VISIBILITY + void __destruct_at_end(pointer __new_last) _NOEXCEPT + {__destruct_at_end(__new_last, false_type());} + _LIBCPP_INLINE_VISIBILITY + void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT; + + void swap(__split_buffer& __x) + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value|| + __is_nothrow_swappable<__alloc_rr>::value); + + bool __invariants() const; + +private: + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__split_buffer& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value) + { + __alloc() = _VSTD::move(__c.__alloc()); + } + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT + {} +}; + +template +bool +__split_buffer<_Tp, _Allocator>::__invariants() const +{ + if (__first_ == nullptr) + { + if (__begin_ != nullptr) + return false; + if (__end_ != nullptr) + return false; + if (__end_cap() != nullptr) + return false; + } + else + { + if (__begin_ < __first_) + return false; + if (__end_ < __begin_) + return false; + if (__end_cap() < __end_) + return false; + } + return true; +} + +// Default constructs __n objects starting at __end_ +// throws if construction throws +// Precondition: __n > 0 +// Precondition: size() + __n <= capacity() +// Postcondition: size() == size() + __n +template +void +__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n) +{ + __alloc_rr& __a = this->__alloc(); + do + { + __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_)); + ++this->__end_; + --__n; + } while (__n > 0); +} + +// Copy constructs __n objects starting at __end_ from __x +// throws if construction throws +// Precondition: __n > 0 +// Precondition: size() + __n <= capacity() +// Postcondition: size() == old size() + __n +// Postcondition: [i] == __x for all i in [size() - __n, __n) +template +void +__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) +{ + __alloc_rr& __a = this->__alloc(); + do + { + __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x); + ++this->__end_; + --__n; + } while (__n > 0); +} + +template +template +typename enable_if +< + __is_input_iterator<_InputIter>::value && + !__is_forward_iterator<_InputIter>::value, + void +>::type +__split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last) +{ + __alloc_rr& __a = this->__alloc(); + for (; __first != __last; ++__first) + { + if (__end_ == __end_cap()) + { + size_type __old_cap = __end_cap() - __first_; + size_type __new_cap = _VSTD::max(2 * __old_cap, 8); + __split_buffer __buf(__new_cap, 0, __a); + for (pointer __p = __begin_; __p != __end_; ++__p, ++__buf.__end_) + __alloc_traits::construct(__buf.__alloc(), + _VSTD::__to_raw_pointer(__buf.__end_), _VSTD::move(*__p)); + swap(__buf); + } + __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first); + ++this->__end_; + } +} + +template +template +typename enable_if +< + __is_forward_iterator<_ForwardIterator>::value, + void +>::type +__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) +{ + __alloc_rr& __a = this->__alloc(); + for (; __first != __last; ++__first) + { + __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first); + ++this->__end_; + } +} + +template +inline +void +__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type) +{ + while (__begin_ != __new_begin) + __alloc_traits::destroy(__alloc(), __to_raw_pointer(__begin_++)); +} + +template +inline +void +__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type) +{ + __begin_ = __new_begin; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT +{ + while (__new_last != __end_) + __alloc_traits::destroy(__alloc(), __to_raw_pointer(--__end_)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type) _NOEXCEPT +{ + __end_ = __new_last; +} + +template +__split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a) + : __end_cap_(nullptr, __a) +{ + __first_ = __cap != 0 ? __alloc_traits::allocate(__alloc(), __cap) : nullptr; + __begin_ = __end_ = __first_ + __start; + __end_cap() = __first_ + __cap; +} + +template +inline +__split_buffer<_Tp, _Allocator>::__split_buffer() + _NOEXCEPT_(is_nothrow_default_constructible::value) + : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr) +{ +} + +template +inline +__split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a) + : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) +{ +} + +template +inline +__split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a) + : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) +{ +} + +template +__split_buffer<_Tp, _Allocator>::~__split_buffer() +{ + clear(); + if (__first_) + __alloc_traits::deallocate(__alloc(), __first_, capacity()); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c) + _NOEXCEPT_(is_nothrow_move_constructible::value) + : __first_(_VSTD::move(__c.__first_)), + __begin_(_VSTD::move(__c.__begin_)), + __end_(_VSTD::move(__c.__end_)), + __end_cap_(_VSTD::move(__c.__end_cap_)) +{ + __c.__first_ = nullptr; + __c.__begin_ = nullptr; + __c.__end_ = nullptr; + __c.__end_cap() = nullptr; +} + +template +__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a) + : __end_cap_(__a) +{ + if (__a == __c.__alloc()) + { + __first_ = __c.__first_; + __begin_ = __c.__begin_; + __end_ = __c.__end_; + __end_cap() = __c.__end_cap(); + __c.__first_ = nullptr; + __c.__begin_ = nullptr; + __c.__end_ = nullptr; + __c.__end_cap() = nullptr; + } + else + { + size_type __cap = __c.size(); + __first_ = __alloc_traits::allocate(__alloc(), __cap); + __begin_ = __end_ = __first_; + __end_cap() = __first_ + __cap; + typedef move_iterator _Ip; + __construct_at_end(_Ip(__c.begin()), _Ip(__c.end())); + } +} + +template +__split_buffer<_Tp, _Allocator>& +__split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c) + _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value) || + !__alloc_traits::propagate_on_container_move_assignment::value) +{ + clear(); + shrink_to_fit(); + __first_ = __c.__first_; + __begin_ = __c.__begin_; + __end_ = __c.__end_; + __end_cap() = __c.__end_cap(); + __move_assign_alloc(__c, + integral_constant()); + __c.__first_ = __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr; + return *this; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +__split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x) + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value|| + __is_nothrow_swappable<__alloc_rr>::value) +{ + _VSTD::swap(__first_, __x.__first_); + _VSTD::swap(__begin_, __x.__begin_); + _VSTD::swap(__end_, __x.__end_); + _VSTD::swap(__end_cap(), __x.__end_cap()); + __swap_allocator(__alloc(), __x.__alloc()); +} + +template +void +__split_buffer<_Tp, _Allocator>::reserve(size_type __n) +{ + if (__n < capacity()) + { + __split_buffer __t(__n, 0, __alloc()); + __t.__construct_at_end(move_iterator(__begin_), + move_iterator(__end_)); + _VSTD::swap(__first_, __t.__first_); + _VSTD::swap(__begin_, __t.__begin_); + _VSTD::swap(__end_, __t.__end_); + _VSTD::swap(__end_cap(), __t.__end_cap()); + } +} + +template +void +__split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT +{ + if (capacity() > size()) + { +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + __split_buffer __t(size(), 0, __alloc()); + __t.__construct_at_end(move_iterator(__begin_), + move_iterator(__end_)); + __t.__end_ = __t.__begin_ + (__end_ - __begin_); + _VSTD::swap(__first_, __t.__first_); + _VSTD::swap(__begin_, __t.__begin_); + _VSTD::swap(__end_, __t.__end_); + _VSTD::swap(__end_cap(), __t.__end_cap()); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCPP_NO_EXCEPTIONS + } +} + +template +void +__split_buffer<_Tp, _Allocator>::push_front(const_reference __x) +{ + if (__begin_ == __first_) + { + if (__end_ < __end_cap()) + { + difference_type __d = __end_cap() - __end_; + __d = (__d + 1) / 2; + __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d); + __end_ += __d; + } + else + { + size_type __c = max(2 * static_cast(__end_cap() - __first_), 1); + __split_buffer __t(__c, (__c + 3) / 4, __alloc()); + __t.__construct_at_end(move_iterator(__begin_), + move_iterator(__end_)); + _VSTD::swap(__first_, __t.__first_); + _VSTD::swap(__begin_, __t.__begin_); + _VSTD::swap(__end_, __t.__end_); + _VSTD::swap(__end_cap(), __t.__end_cap()); + } + } + __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), __x); + --__begin_; +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +__split_buffer<_Tp, _Allocator>::push_front(value_type&& __x) +{ + if (__begin_ == __first_) + { + if (__end_ < __end_cap()) + { + difference_type __d = __end_cap() - __end_; + __d = (__d + 1) / 2; + __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d); + __end_ += __d; + } + else + { + size_type __c = max(2 * static_cast(__end_cap() - __first_), 1); + __split_buffer __t(__c, (__c + 3) / 4, __alloc()); + __t.__construct_at_end(move_iterator(__begin_), + move_iterator(__end_)); + _VSTD::swap(__first_, __t.__first_); + _VSTD::swap(__begin_, __t.__begin_); + _VSTD::swap(__end_, __t.__end_); + _VSTD::swap(__end_cap(), __t.__end_cap()); + } + } + __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), + _VSTD::move(__x)); + --__begin_; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +void +__split_buffer<_Tp, _Allocator>::push_back(const_reference __x) +{ + if (__end_ == __end_cap()) + { + if (__begin_ > __first_) + { + difference_type __d = __begin_ - __first_; + __d = (__d + 1) / 2; + __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); + __begin_ -= __d; + } + else + { + size_type __c = max(2 * static_cast(__end_cap() - __first_), 1); + __split_buffer __t(__c, __c / 4, __alloc()); + __t.__construct_at_end(move_iterator(__begin_), + move_iterator(__end_)); + _VSTD::swap(__first_, __t.__first_); + _VSTD::swap(__begin_, __t.__begin_); + _VSTD::swap(__end_, __t.__end_); + _VSTD::swap(__end_cap(), __t.__end_cap()); + } + } + __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), __x); + ++__end_; +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +__split_buffer<_Tp, _Allocator>::push_back(value_type&& __x) +{ + if (__end_ == __end_cap()) + { + if (__begin_ > __first_) + { + difference_type __d = __begin_ - __first_; + __d = (__d + 1) / 2; + __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); + __begin_ -= __d; + } + else + { + size_type __c = max(2 * static_cast(__end_cap() - __first_), 1); + __split_buffer __t(__c, __c / 4, __alloc()); + __t.__construct_at_end(move_iterator(__begin_), + move_iterator(__end_)); + _VSTD::swap(__first_, __t.__first_); + _VSTD::swap(__begin_, __t.__begin_); + _VSTD::swap(__end_, __t.__end_); + _VSTD::swap(__end_cap(), __t.__end_cap()); + } + } + __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), + _VSTD::move(__x)); + ++__end_; +} + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +template +template +void +__split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args) +{ + if (__end_ == __end_cap()) + { + if (__begin_ > __first_) + { + difference_type __d = __begin_ - __first_; + __d = (__d + 1) / 2; + __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); + __begin_ -= __d; + } + else + { + size_type __c = max(2 * static_cast(__end_cap() - __first_), 1); + __split_buffer __t(__c, __c / 4, __alloc()); + __t.__construct_at_end(move_iterator(__begin_), + move_iterator(__end_)); + _VSTD::swap(__first_, __t.__first_); + _VSTD::swap(__begin_, __t.__begin_); + _VSTD::swap(__end_, __t.__end_); + _VSTD::swap(__end_cap(), __t.__end_cap()); + } + } + __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), + _VSTD::forward<_Args>(__args)...); + ++__end_; +} + +#endif // _LIBCPP_HAS_NO_VARIADICS + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_SPLIT_BUFFER diff --git a/headers/libs/libc++/__sso_allocator b/headers/libs/libc++/__sso_allocator new file mode 100644 index 0000000000..ca3b937c01 --- /dev/null +++ b/headers/libs/libc++/__sso_allocator @@ -0,0 +1,79 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___SSO_ALLOCATOR +#define _LIBCPP___SSO_ALLOCATOR + +#include <__config> +#include +#include + +#include <__undef___deallocate> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template class _LIBCPP_HIDDEN __sso_allocator; + +template +class _LIBCPP_HIDDEN __sso_allocator +{ +public: + typedef const void* const_pointer; + typedef void value_type; +}; + +template +class _LIBCPP_HIDDEN __sso_allocator +{ + typename aligned_storage::type buf_; + bool __allocated_; +public: + typedef size_t size_type; + typedef _Tp* pointer; + typedef _Tp value_type; + + _LIBCPP_INLINE_VISIBILITY __sso_allocator() throw() : __allocated_(false) {} + _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator&) throw() : __allocated_(false) {} + template _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator<_Up, _Np>&) throw() + : __allocated_(false) {} +private: + __sso_allocator& operator=(const __sso_allocator&); +public: + _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, typename __sso_allocator::const_pointer = 0) + { + if (!__allocated_ && __n <= _Np) + { + __allocated_ = true; + return (pointer)&buf_; + } + return static_cast(_VSTD::__allocate(__n * sizeof(_Tp))); + } + _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) + { + if (__p == (pointer)&buf_) + __allocated_ = false; + else + _VSTD::__deallocate(__p); + } + _LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);} + + _LIBCPP_INLINE_VISIBILITY + bool operator==(__sso_allocator& __a) const {return &buf_ == &__a.buf_;} + _LIBCPP_INLINE_VISIBILITY + bool operator!=(__sso_allocator& __a) const {return &buf_ != &__a.buf_;} +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___SSO_ALLOCATOR diff --git a/headers/libs/libc++/__std_stream b/headers/libs/libc++/__std_stream new file mode 100644 index 0000000000..f867cd23bd --- /dev/null +++ b/headers/libs/libc++/__std_stream @@ -0,0 +1,358 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___STD_STREAM +#define _LIBCPP___STD_STREAM + +#include <__config> +#include +#include +#include <__locale> +#include + +#include <__undef_min_max> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +static const int __limit = 8; + +// __stdinbuf + +template +class _LIBCPP_HIDDEN __stdinbuf + : public basic_streambuf<_CharT, char_traits<_CharT> > +{ +public: + typedef _CharT char_type; + typedef char_traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + typedef typename traits_type::state_type state_type; + + __stdinbuf(FILE* __fp, state_type* __st); + +protected: + virtual int_type underflow(); + virtual int_type uflow(); + virtual int_type pbackfail(int_type __c = traits_type::eof()); + virtual void imbue(const locale& __loc); + +private: + + FILE* __file_; + const codecvt* __cv_; + state_type* __st_; + int __encoding_; + int_type __last_consumed_; + bool __last_consumed_is_next_; + bool __always_noconv_; + + __stdinbuf(const __stdinbuf&); + __stdinbuf& operator=(const __stdinbuf&); + + int_type __getchar(bool __consume); +}; + +template +__stdinbuf<_CharT>::__stdinbuf(FILE* __fp, state_type* __st) + : __file_(__fp), + __st_(__st), + __last_consumed_(traits_type::eof()), + __last_consumed_is_next_(false) +{ + imbue(this->getloc()); +} + +template +void +__stdinbuf<_CharT>::imbue(const locale& __loc) +{ + __cv_ = &use_facet >(__loc); + __encoding_ = __cv_->encoding(); + __always_noconv_ = __cv_->always_noconv(); + if (__encoding_ > __limit) + __throw_runtime_error("unsupported locale for standard input"); +} + +template +typename __stdinbuf<_CharT>::int_type +__stdinbuf<_CharT>::underflow() +{ + return __getchar(false); +} + +template +typename __stdinbuf<_CharT>::int_type +__stdinbuf<_CharT>::uflow() +{ + return __getchar(true); +} + +template +typename __stdinbuf<_CharT>::int_type +__stdinbuf<_CharT>::__getchar(bool __consume) +{ + if (__last_consumed_is_next_) + { + int_type __result = __last_consumed_; + if (__consume) + { + __last_consumed_ = traits_type::eof(); + __last_consumed_is_next_ = false; + } + return __result; + } + char __extbuf[__limit]; + int __nread = _VSTD::max(1, __encoding_); + for (int __i = 0; __i < __nread; ++__i) + { + int __c = getc(__file_); + if (__c == EOF) + return traits_type::eof(); + __extbuf[__i] = static_cast(__c); + } + char_type __1buf; + if (__always_noconv_) + __1buf = static_cast(__extbuf[0]); + else + { + const char* __enxt; + char_type* __inxt; + codecvt_base::result __r; + do + { + state_type __sv_st = *__st_; + __r = __cv_->in(*__st_, __extbuf, __extbuf + __nread, __enxt, + &__1buf, &__1buf + 1, __inxt); + switch (__r) + { + case _VSTD::codecvt_base::ok: + break; + case codecvt_base::partial: + *__st_ = __sv_st; + if (__nread == sizeof(__extbuf)) + return traits_type::eof(); + { + int __c = getc(__file_); + if (__c == EOF) + return traits_type::eof(); + __extbuf[__nread] = static_cast(__c); + } + ++__nread; + break; + case codecvt_base::error: + return traits_type::eof(); + case _VSTD::codecvt_base::noconv: + __1buf = static_cast(__extbuf[0]); + break; + } + } while (__r == _VSTD::codecvt_base::partial); + } + if (!__consume) + { + for (int __i = __nread; __i > 0;) + { + if (ungetc(traits_type::to_int_type(__extbuf[--__i]), __file_) == EOF) + return traits_type::eof(); + } + } + else + __last_consumed_ = traits_type::to_int_type(__1buf); + return traits_type::to_int_type(__1buf); +} + +template +typename __stdinbuf<_CharT>::int_type +__stdinbuf<_CharT>::pbackfail(int_type __c) +{ + if (traits_type::eq_int_type(__c, traits_type::eof())) + { + if (!__last_consumed_is_next_) + { + __c = __last_consumed_; + __last_consumed_is_next_ = !traits_type::eq_int_type(__last_consumed_, + traits_type::eof()); + } + return __c; + } + if (__last_consumed_is_next_) + { + char __extbuf[__limit]; + char* __enxt; + const char_type __ci = traits_type::to_char_type(__last_consumed_); + const char_type* __inxt; + switch (__cv_->out(*__st_, &__ci, &__ci + 1, __inxt, + __extbuf, __extbuf + sizeof(__extbuf), __enxt)) + { + case _VSTD::codecvt_base::ok: + break; + case _VSTD::codecvt_base::noconv: + __extbuf[0] = static_cast(__last_consumed_); + __enxt = __extbuf + 1; + break; + case codecvt_base::partial: + case codecvt_base::error: + return traits_type::eof(); + } + while (__enxt > __extbuf) + if (ungetc(*--__enxt, __file_) == EOF) + return traits_type::eof(); + } + __last_consumed_ = __c; + __last_consumed_is_next_ = true; + return __c; +} + +// __stdoutbuf + +template +class _LIBCPP_HIDDEN __stdoutbuf + : public basic_streambuf<_CharT, char_traits<_CharT> > +{ +public: + typedef _CharT char_type; + typedef char_traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + typedef typename traits_type::state_type state_type; + + __stdoutbuf(FILE* __fp, state_type* __st); + +protected: + virtual int_type overflow (int_type __c = traits_type::eof()); + virtual streamsize xsputn(const char_type* __s, streamsize __n); + virtual int sync(); + virtual void imbue(const locale& __loc); + +private: + FILE* __file_; + const codecvt* __cv_; + state_type* __st_; + bool __always_noconv_; + + __stdoutbuf(const __stdoutbuf&); + __stdoutbuf& operator=(const __stdoutbuf&); +}; + +template +__stdoutbuf<_CharT>::__stdoutbuf(FILE* __fp, state_type* __st) + : __file_(__fp), + __cv_(&use_facet >(this->getloc())), + __st_(__st), + __always_noconv_(__cv_->always_noconv()) +{ +} + +template +typename __stdoutbuf<_CharT>::int_type +__stdoutbuf<_CharT>::overflow(int_type __c) +{ + char __extbuf[__limit]; + char_type __1buf; + if (!traits_type::eq_int_type(__c, traits_type::eof())) + { + __1buf = traits_type::to_char_type(__c); + if (__always_noconv_) + { + if (fwrite(&__1buf, sizeof(char_type), 1, __file_) != 1) + return traits_type::eof(); + } + else + { + char* __extbe = __extbuf; + codecvt_base::result __r; + char_type* pbase = &__1buf; + char_type* pptr = pbase + 1; + do + { + const char_type* __e; + __r = __cv_->out(*__st_, pbase, pptr, __e, + __extbuf, + __extbuf + sizeof(__extbuf), + __extbe); + if (__e == pbase) + return traits_type::eof(); + if (__r == codecvt_base::noconv) + { + if (fwrite(pbase, 1, 1, __file_) != 1) + return traits_type::eof(); + } + else if (__r == codecvt_base::ok || __r == codecvt_base::partial) + { + size_t __nmemb = static_cast(__extbe - __extbuf); + if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb) + return traits_type::eof(); + if (__r == codecvt_base::partial) + { + pbase = (char_type*)__e; + } + } + else + return traits_type::eof(); + } while (__r == codecvt_base::partial); + } + } + return traits_type::not_eof(__c); +} + +template +streamsize +__stdoutbuf<_CharT>::xsputn(const char_type* __s, streamsize __n) +{ + if (__always_noconv_) + return fwrite(__s, sizeof(char_type), __n, __file_); + streamsize __i = 0; + for (; __i < __n; ++__i, ++__s) + if (overflow(traits_type::to_int_type(*__s)) == traits_type::eof()) + break; + return __i; +} + +template +int +__stdoutbuf<_CharT>::sync() +{ + char __extbuf[__limit]; + codecvt_base::result __r; + do + { + char* __extbe; + __r = __cv_->unshift(*__st_, __extbuf, + __extbuf + sizeof(__extbuf), + __extbe); + size_t __nmemb = static_cast(__extbe - __extbuf); + if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb) + return -1; + } while (__r == codecvt_base::partial); + if (__r == codecvt_base::error) + return -1; + if (fflush(__file_)) + return -1; + return 0; +} + +template +void +__stdoutbuf<_CharT>::imbue(const locale& __loc) +{ + sync(); + __cv_ = &use_facet >(__loc); + __always_noconv_ = __cv_->always_noconv(); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___STD_STREAM diff --git a/headers/libs/libc++/__tree b/headers/libs/libc++/__tree new file mode 100644 index 0000000000..6391609b39 --- /dev/null +++ b/headers/libs/libc++/__tree @@ -0,0 +1,2297 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TREE +#define _LIBCPP___TREE + +#include <__config> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template class __tree; +template + class _LIBCPP_TYPE_VIS_ONLY __tree_iterator; +template + class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator; + +/* + +_NodePtr algorithms + +The algorithms taking _NodePtr are red black tree algorithms. Those +algorithms taking a parameter named __root should assume that __root +points to a proper red black tree (unless otherwise specified). + +Each algorithm herein assumes that __root->__parent_ points to a non-null +structure which has a member __left_ which points back to __root. No other +member is read or written to at __root->__parent_. + +__root->__parent_ will be referred to below (in comments only) as end_node. +end_node->__left_ is an externably accessible lvalue for __root, and can be +changed by node insertion and removal (without explicit reference to end_node). + +All nodes (with the exception of end_node), even the node referred to as +__root, have a non-null __parent_ field. + +*/ + +// Returns: true if __x is a left child of its parent, else false +// Precondition: __x != nullptr. +template +inline _LIBCPP_INLINE_VISIBILITY +bool +__tree_is_left_child(_NodePtr __x) _NOEXCEPT +{ + return __x == __x->__parent_->__left_; +} + +// Determintes if the subtree rooted at __x is a proper red black subtree. If +// __x is a proper subtree, returns the black height (null counts as 1). If +// __x is an improper subtree, returns 0. +template +unsigned +__tree_sub_invariant(_NodePtr __x) +{ + if (__x == nullptr) + return 1; + // parent consistency checked by caller + // check __x->__left_ consistency + if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x) + return 0; + // check __x->__right_ consistency + if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x) + return 0; + // check __x->__left_ != __x->__right_ unless both are nullptr + if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr) + return 0; + // If this is red, neither child can be red + if (!__x->__is_black_) + { + if (__x->__left_ && !__x->__left_->__is_black_) + return 0; + if (__x->__right_ && !__x->__right_->__is_black_) + return 0; + } + unsigned __h = __tree_sub_invariant(__x->__left_); + if (__h == 0) + return 0; // invalid left subtree + if (__h != __tree_sub_invariant(__x->__right_)) + return 0; // invalid or different height right subtree + return __h + __x->__is_black_; // return black height of this node +} + +// Determintes if the red black tree rooted at __root is a proper red black tree. +// __root == nullptr is a proper tree. Returns true is __root is a proper +// red black tree, else returns false. +template +bool +__tree_invariant(_NodePtr __root) +{ + if (__root == nullptr) + return true; + // check __x->__parent_ consistency + if (__root->__parent_ == nullptr) + return false; + if (!__tree_is_left_child(__root)) + return false; + // root must be black + if (!__root->__is_black_) + return false; + // do normal node checks + return __tree_sub_invariant(__root) != 0; +} + +// Returns: pointer to the left-most node under __x. +// Precondition: __x != nullptr. +template +inline _LIBCPP_INLINE_VISIBILITY +_NodePtr +__tree_min(_NodePtr __x) _NOEXCEPT +{ + while (__x->__left_ != nullptr) + __x = __x->__left_; + return __x; +} + +// Returns: pointer to the right-most node under __x. +// Precondition: __x != nullptr. +template +inline _LIBCPP_INLINE_VISIBILITY +_NodePtr +__tree_max(_NodePtr __x) _NOEXCEPT +{ + while (__x->__right_ != nullptr) + __x = __x->__right_; + return __x; +} + +// Returns: pointer to the next in-order node after __x. +// Precondition: __x != nullptr. +template +_NodePtr +__tree_next(_NodePtr __x) _NOEXCEPT +{ + if (__x->__right_ != nullptr) + return __tree_min(__x->__right_); + while (!__tree_is_left_child(__x)) + __x = __x->__parent_; + return __x->__parent_; +} + +// Returns: pointer to the previous in-order node before __x. +// Precondition: __x != nullptr. +template +_NodePtr +__tree_prev(_NodePtr __x) _NOEXCEPT +{ + if (__x->__left_ != nullptr) + return __tree_max(__x->__left_); + while (__tree_is_left_child(__x)) + __x = __x->__parent_; + return __x->__parent_; +} + +// Returns: pointer to a node which has no children +// Precondition: __x != nullptr. +template +_NodePtr +__tree_leaf(_NodePtr __x) _NOEXCEPT +{ + while (true) + { + if (__x->__left_ != nullptr) + { + __x = __x->__left_; + continue; + } + if (__x->__right_ != nullptr) + { + __x = __x->__right_; + continue; + } + break; + } + return __x; +} + +// Effects: Makes __x->__right_ the subtree root with __x as its left child +// while preserving in-order order. +// Precondition: __x->__right_ != nullptr +template +void +__tree_left_rotate(_NodePtr __x) _NOEXCEPT +{ + _NodePtr __y = __x->__right_; + __x->__right_ = __y->__left_; + if (__x->__right_ != nullptr) + __x->__right_->__parent_ = __x; + __y->__parent_ = __x->__parent_; + if (__tree_is_left_child(__x)) + __x->__parent_->__left_ = __y; + else + __x->__parent_->__right_ = __y; + __y->__left_ = __x; + __x->__parent_ = __y; +} + +// Effects: Makes __x->__left_ the subtree root with __x as its right child +// while preserving in-order order. +// Precondition: __x->__left_ != nullptr +template +void +__tree_right_rotate(_NodePtr __x) _NOEXCEPT +{ + _NodePtr __y = __x->__left_; + __x->__left_ = __y->__right_; + if (__x->__left_ != nullptr) + __x->__left_->__parent_ = __x; + __y->__parent_ = __x->__parent_; + if (__tree_is_left_child(__x)) + __x->__parent_->__left_ = __y; + else + __x->__parent_->__right_ = __y; + __y->__right_ = __x; + __x->__parent_ = __y; +} + +// Effects: Rebalances __root after attaching __x to a leaf. +// Precondition: __root != nulptr && __x != nullptr. +// __x has no children. +// __x == __root or == a direct or indirect child of __root. +// If __x were to be unlinked from __root (setting __root to +// nullptr if __root == __x), __tree_invariant(__root) == true. +// Postcondition: __tree_invariant(end_node->__left_) == true. end_node->__left_ +// may be different than the value passed in as __root. +template +void +__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT +{ + __x->__is_black_ = __x == __root; + while (__x != __root && !__x->__parent_->__is_black_) + { + // __x->__parent_ != __root because __x->__parent_->__is_black == false + if (__tree_is_left_child(__x->__parent_)) + { + _NodePtr __y = __x->__parent_->__parent_->__right_; + if (__y != nullptr && !__y->__is_black_) + { + __x = __x->__parent_; + __x->__is_black_ = true; + __x = __x->__parent_; + __x->__is_black_ = __x == __root; + __y->__is_black_ = true; + } + else + { + if (!__tree_is_left_child(__x)) + { + __x = __x->__parent_; + __tree_left_rotate(__x); + } + __x = __x->__parent_; + __x->__is_black_ = true; + __x = __x->__parent_; + __x->__is_black_ = false; + __tree_right_rotate(__x); + break; + } + } + else + { + _NodePtr __y = __x->__parent_->__parent_->__left_; + if (__y != nullptr && !__y->__is_black_) + { + __x = __x->__parent_; + __x->__is_black_ = true; + __x = __x->__parent_; + __x->__is_black_ = __x == __root; + __y->__is_black_ = true; + } + else + { + if (__tree_is_left_child(__x)) + { + __x = __x->__parent_; + __tree_right_rotate(__x); + } + __x = __x->__parent_; + __x->__is_black_ = true; + __x = __x->__parent_; + __x->__is_black_ = false; + __tree_left_rotate(__x); + break; + } + } + } +} + +// Precondition: __root != nullptr && __z != nullptr. +// __tree_invariant(__root) == true. +// __z == __root or == a direct or indirect child of __root. +// Effects: unlinks __z from the tree rooted at __root, rebalancing as needed. +// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_ +// nor any of its children refer to __z. end_node->__left_ +// may be different than the value passed in as __root. +template +void +__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT +{ + // __z will be removed from the tree. Client still needs to destruct/deallocate it + // __y is either __z, or if __z has two children, __tree_next(__z). + // __y will have at most one child. + // __y will be the initial hole in the tree (make the hole at a leaf) + _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ? + __z : __tree_next(__z); + // __x is __y's possibly null single child + _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_; + // __w is __x's possibly null uncle (will become __x's sibling) + _NodePtr __w = nullptr; + // link __x to __y's parent, and find __w + if (__x != nullptr) + __x->__parent_ = __y->__parent_; + if (__tree_is_left_child(__y)) + { + __y->__parent_->__left_ = __x; + if (__y != __root) + __w = __y->__parent_->__right_; + else + __root = __x; // __w == nullptr + } + else + { + __y->__parent_->__right_ = __x; + // __y can't be root if it is a right child + __w = __y->__parent_->__left_; + } + bool __removed_black = __y->__is_black_; + // If we didn't remove __z, do so now by splicing in __y for __z, + // but copy __z's color. This does not impact __x or __w. + if (__y != __z) + { + // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr + __y->__parent_ = __z->__parent_; + if (__tree_is_left_child(__z)) + __y->__parent_->__left_ = __y; + else + __y->__parent_->__right_ = __y; + __y->__left_ = __z->__left_; + __y->__left_->__parent_ = __y; + __y->__right_ = __z->__right_; + if (__y->__right_ != nullptr) + __y->__right_->__parent_ = __y; + __y->__is_black_ = __z->__is_black_; + if (__root == __z) + __root = __y; + } + // There is no need to rebalance if we removed a red, or if we removed + // the last node. + if (__removed_black && __root != nullptr) + { + // Rebalance: + // __x has an implicit black color (transferred from the removed __y) + // associated with it, no matter what its color is. + // If __x is __root (in which case it can't be null), it is supposed + // to be black anyway, and if it is doubly black, then the double + // can just be ignored. + // If __x is red (in which case it can't be null), then it can absorb + // the implicit black just by setting its color to black. + // Since __y was black and only had one child (which __x points to), __x + // is either red with no children, else null, otherwise __y would have + // different black heights under left and right pointers. + // if (__x == __root || __x != nullptr && !__x->__is_black_) + if (__x != nullptr) + __x->__is_black_ = true; + else + { + // Else __x isn't root, and is "doubly black", even though it may + // be null. __w can not be null here, else the parent would + // see a black height >= 2 on the __x side and a black height + // of 1 on the __w side (__w must be a non-null black or a red + // with a non-null black child). + while (true) + { + if (!__tree_is_left_child(__w)) // if x is left child + { + if (!__w->__is_black_) + { + __w->__is_black_ = true; + __w->__parent_->__is_black_ = false; + __tree_left_rotate(__w->__parent_); + // __x is still valid + // reset __root only if necessary + if (__root == __w->__left_) + __root = __w; + // reset sibling, and it still can't be null + __w = __w->__left_->__right_; + } + // __w->__is_black_ is now true, __w may have null children + if ((__w->__left_ == nullptr || __w->__left_->__is_black_) && + (__w->__right_ == nullptr || __w->__right_->__is_black_)) + { + __w->__is_black_ = false; + __x = __w->__parent_; + // __x can no longer be null + if (__x == __root || !__x->__is_black_) + { + __x->__is_black_ = true; + break; + } + // reset sibling, and it still can't be null + __w = __tree_is_left_child(__x) ? + __x->__parent_->__right_ : + __x->__parent_->__left_; + // continue; + } + else // __w has a red child + { + if (__w->__right_ == nullptr || __w->__right_->__is_black_) + { + // __w left child is non-null and red + __w->__left_->__is_black_ = true; + __w->__is_black_ = false; + __tree_right_rotate(__w); + // __w is known not to be root, so root hasn't changed + // reset sibling, and it still can't be null + __w = __w->__parent_; + } + // __w has a right red child, left child may be null + __w->__is_black_ = __w->__parent_->__is_black_; + __w->__parent_->__is_black_ = true; + __w->__right_->__is_black_ = true; + __tree_left_rotate(__w->__parent_); + break; + } + } + else + { + if (!__w->__is_black_) + { + __w->__is_black_ = true; + __w->__parent_->__is_black_ = false; + __tree_right_rotate(__w->__parent_); + // __x is still valid + // reset __root only if necessary + if (__root == __w->__right_) + __root = __w; + // reset sibling, and it still can't be null + __w = __w->__right_->__left_; + } + // __w->__is_black_ is now true, __w may have null children + if ((__w->__left_ == nullptr || __w->__left_->__is_black_) && + (__w->__right_ == nullptr || __w->__right_->__is_black_)) + { + __w->__is_black_ = false; + __x = __w->__parent_; + // __x can no longer be null + if (!__x->__is_black_ || __x == __root) + { + __x->__is_black_ = true; + break; + } + // reset sibling, and it still can't be null + __w = __tree_is_left_child(__x) ? + __x->__parent_->__right_ : + __x->__parent_->__left_; + // continue; + } + else // __w has a red child + { + if (__w->__left_ == nullptr || __w->__left_->__is_black_) + { + // __w right child is non-null and red + __w->__right_->__is_black_ = true; + __w->__is_black_ = false; + __tree_left_rotate(__w); + // __w is known not to be root, so root hasn't changed + // reset sibling, and it still can't be null + __w = __w->__parent_; + } + // __w has a left red child, right child may be null + __w->__is_black_ = __w->__parent_->__is_black_; + __w->__parent_->__is_black_ = true; + __w->__left_->__is_black_ = true; + __tree_right_rotate(__w->__parent_); + break; + } + } + } + } + } +} + +template class __map_node_destructor; + +template +class __tree_node_destructor +{ + typedef _Allocator allocator_type; + typedef allocator_traits __alloc_traits; + typedef typename __alloc_traits::value_type::value_type value_type; +public: + typedef typename __alloc_traits::pointer pointer; +private: + + allocator_type& __na_; + + __tree_node_destructor& operator=(const __tree_node_destructor&); + +public: + bool __value_constructed; + + _LIBCPP_INLINE_VISIBILITY + explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT + : __na_(__na), + __value_constructed(__val) + {} + + _LIBCPP_INLINE_VISIBILITY + void operator()(pointer __p) _NOEXCEPT + { + if (__value_constructed) + __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_)); + if (__p) + __alloc_traits::deallocate(__na_, __p, 1); + } + + template friend class __map_node_destructor; +}; + +// node + +template +class __tree_end_node +{ +public: + typedef _Pointer pointer; + pointer __left_; + + _LIBCPP_INLINE_VISIBILITY + __tree_end_node() _NOEXCEPT : __left_() {} +}; + +template +class __tree_node_base + : public __tree_end_node + < + typename pointer_traits<_VoidPtr>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind<__tree_node_base<_VoidPtr> > +#else + rebind<__tree_node_base<_VoidPtr> >::other +#endif + > +{ + __tree_node_base(const __tree_node_base&); + __tree_node_base& operator=(const __tree_node_base&); +public: + typedef typename pointer_traits<_VoidPtr>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind<__tree_node_base> +#else + rebind<__tree_node_base>::other +#endif + pointer; + typedef typename pointer_traits<_VoidPtr>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + const_pointer; + typedef __tree_end_node base; + + pointer __right_; + pointer __parent_; + bool __is_black_; + + _LIBCPP_INLINE_VISIBILITY + __tree_node_base() _NOEXCEPT + : __right_(), __parent_(), __is_black_(false) {} +}; + +template +class __tree_node + : public __tree_node_base<_VoidPtr> +{ +public: + typedef __tree_node_base<_VoidPtr> base; + typedef _Tp value_type; + + value_type __value_; + +#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) + template + _LIBCPP_INLINE_VISIBILITY + explicit __tree_node(_Args&& ...__args) + : __value_(_VSTD::forward<_Args>(__args)...) {} +#else // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) + _LIBCPP_INLINE_VISIBILITY + explicit __tree_node(const value_type& __v) + : __value_(__v) {} +#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) +}; + +template class _LIBCPP_TYPE_VIS_ONLY __map_iterator; +template class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator; + +template +class _LIBCPP_TYPE_VIS_ONLY __tree_iterator +{ + typedef _NodePtr __node_pointer; + typedef typename pointer_traits<__node_pointer>::element_type __node; + + __node_pointer __ptr_; + + typedef pointer_traits<__node_pointer> __pointer_traits; +public: + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _DiffType difference_type; + typedef value_type& reference; + typedef typename pointer_traits<__node_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + pointer; + + _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT +#if _LIBCPP_STD_VER > 11 + : __ptr_(nullptr) +#endif + {} + + _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;} + _LIBCPP_INLINE_VISIBILITY pointer operator->() const + {return pointer_traits::pointer_to(__ptr_->__value_);} + + _LIBCPP_INLINE_VISIBILITY + __tree_iterator& operator++() { + __ptr_ = static_cast<__node_pointer>( + __tree_next(static_cast(__ptr_))); + return *this; + } + _LIBCPP_INLINE_VISIBILITY + __tree_iterator operator++(int) + {__tree_iterator __t(*this); ++(*this); return __t;} + + _LIBCPP_INLINE_VISIBILITY + __tree_iterator& operator--() { + __ptr_ = static_cast<__node_pointer>( + __tree_prev(static_cast(__ptr_))); + return *this; + } + _LIBCPP_INLINE_VISIBILITY + __tree_iterator operator--(int) + {__tree_iterator __t(*this); --(*this); return __t;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __tree_iterator& __x, const __tree_iterator& __y) + {return __x.__ptr_ == __y.__ptr_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y) + {return !(__x == __y);} + +private: + _LIBCPP_INLINE_VISIBILITY + explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} + template friend class __tree; + template friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator; + template friend class _LIBCPP_TYPE_VIS_ONLY __map_iterator; + template friend class _LIBCPP_TYPE_VIS_ONLY map; + template friend class _LIBCPP_TYPE_VIS_ONLY multimap; + template friend class _LIBCPP_TYPE_VIS_ONLY set; + template friend class _LIBCPP_TYPE_VIS_ONLY multiset; +}; + +template +class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator +{ + typedef _ConstNodePtr __node_pointer; + typedef typename pointer_traits<__node_pointer>::element_type __node; + + __node_pointer __ptr_; + + typedef pointer_traits<__node_pointer> __pointer_traits; +public: + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _DiffType difference_type; + typedef const value_type& reference; + typedef typename pointer_traits<__node_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + pointer; + + _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT +#if _LIBCPP_STD_VER > 11 + : __ptr_(nullptr) +#endif + {} + +private: + typedef typename remove_const<__node>::type __non_const_node; + typedef typename pointer_traits<__node_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind<__non_const_node> +#else + rebind<__non_const_node>::other +#endif + __non_const_node_pointer; + typedef __tree_iterator + __non_const_iterator; +public: + _LIBCPP_INLINE_VISIBILITY + __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT + : __ptr_(__p.__ptr_) {} + + _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;} + _LIBCPP_INLINE_VISIBILITY pointer operator->() const + {return pointer_traits::pointer_to(__ptr_->__value_);} + + _LIBCPP_INLINE_VISIBILITY + __tree_const_iterator& operator++() { + typedef typename pointer_traits<__node_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + __node_base_pointer; + + __ptr_ = static_cast<__node_pointer>( + __tree_next(static_cast<__node_base_pointer>(__ptr_))); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __tree_const_iterator operator++(int) + {__tree_const_iterator __t(*this); ++(*this); return __t;} + + _LIBCPP_INLINE_VISIBILITY + __tree_const_iterator& operator--() { + typedef typename pointer_traits<__node_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + __node_base_pointer; + + __ptr_ = static_cast<__node_pointer>( + __tree_prev(static_cast<__node_base_pointer>(__ptr_))); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __tree_const_iterator operator--(int) + {__tree_const_iterator __t(*this); --(*this); return __t;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y) + {return __x.__ptr_ == __y.__ptr_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y) + {return !(__x == __y);} + +private: + _LIBCPP_INLINE_VISIBILITY + explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT + : __ptr_(__p) {} + template friend class __tree; + template friend class _LIBCPP_TYPE_VIS_ONLY map; + template friend class _LIBCPP_TYPE_VIS_ONLY multimap; + template friend class _LIBCPP_TYPE_VIS_ONLY set; + template friend class _LIBCPP_TYPE_VIS_ONLY multiset; + template friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator; +}; + +template +class __tree +{ +public: + typedef _Tp value_type; + typedef _Compare value_compare; + typedef _Allocator allocator_type; + typedef allocator_traits __alloc_traits; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; + typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::difference_type difference_type; + + typedef typename __alloc_traits::void_pointer __void_pointer; + + typedef __tree_node __node; + typedef __tree_node_base<__void_pointer> __node_base; + typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; + typedef allocator_traits<__node_allocator> __node_traits; + typedef typename __node_traits::pointer __node_pointer; + typedef typename __node_traits::pointer __node_const_pointer; + typedef typename __node_base::pointer __node_base_pointer; + typedef typename __node_base::pointer __node_base_const_pointer; +private: + typedef typename __node_base::base __end_node_t; + typedef typename pointer_traits<__node_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind<__end_node_t> +#else + rebind<__end_node_t>::other +#endif + __end_node_ptr; + typedef typename pointer_traits<__node_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind<__end_node_t> +#else + rebind<__end_node_t>::other +#endif + __end_node_const_ptr; + + __node_pointer __begin_node_; + __compressed_pair<__end_node_t, __node_allocator> __pair1_; + __compressed_pair __pair3_; + +public: + _LIBCPP_INLINE_VISIBILITY + __node_pointer __end_node() _NOEXCEPT + { + return static_cast<__node_pointer> + ( + pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first()) + ); + } + _LIBCPP_INLINE_VISIBILITY + __node_const_pointer __end_node() const _NOEXCEPT + { + return static_cast<__node_const_pointer> + ( + pointer_traits<__end_node_const_ptr>::pointer_to(const_cast<__end_node_t&>(__pair1_.first())) + ); + } + _LIBCPP_INLINE_VISIBILITY + __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();} +private: + _LIBCPP_INLINE_VISIBILITY + const __node_allocator& __node_alloc() const _NOEXCEPT + {return __pair1_.second();} + _LIBCPP_INLINE_VISIBILITY + __node_pointer& __begin_node() _NOEXCEPT {return __begin_node_;} + _LIBCPP_INLINE_VISIBILITY + const __node_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;} +public: + _LIBCPP_INLINE_VISIBILITY + allocator_type __alloc() const _NOEXCEPT + {return allocator_type(__node_alloc());} +private: + _LIBCPP_INLINE_VISIBILITY + size_type& size() _NOEXCEPT {return __pair3_.first();} +public: + _LIBCPP_INLINE_VISIBILITY + const size_type& size() const _NOEXCEPT {return __pair3_.first();} + _LIBCPP_INLINE_VISIBILITY + value_compare& value_comp() _NOEXCEPT {return __pair3_.second();} + _LIBCPP_INLINE_VISIBILITY + const value_compare& value_comp() const _NOEXCEPT + {return __pair3_.second();} +public: + _LIBCPP_INLINE_VISIBILITY + __node_pointer __root() _NOEXCEPT + {return static_cast<__node_pointer> (__end_node()->__left_);} + _LIBCPP_INLINE_VISIBILITY + __node_const_pointer __root() const _NOEXCEPT + {return static_cast<__node_const_pointer>(__end_node()->__left_);} + + typedef __tree_iterator iterator; + typedef __tree_const_iterator const_iterator; + + explicit __tree(const value_compare& __comp) + _NOEXCEPT_( + is_nothrow_default_constructible<__node_allocator>::value && + is_nothrow_copy_constructible::value); + explicit __tree(const allocator_type& __a); + __tree(const value_compare& __comp, const allocator_type& __a); + __tree(const __tree& __t); + __tree& operator=(const __tree& __t); + template + void __assign_unique(_InputIterator __first, _InputIterator __last); + template + void __assign_multi(_InputIterator __first, _InputIterator __last); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + __tree(__tree&& __t) + _NOEXCEPT_( + is_nothrow_move_constructible<__node_allocator>::value && + is_nothrow_move_constructible::value); + __tree(__tree&& __t, const allocator_type& __a); + __tree& operator=(__tree&& __t) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable<__node_allocator>::value); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + ~__tree(); + + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT {return iterator(__begin_node());} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());} + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT {return iterator(__end_node());} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());} + + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT + {return __node_traits::max_size(__node_alloc());} + + void clear() _NOEXCEPT; + + void swap(__tree& __t) + _NOEXCEPT_( + __is_nothrow_swappable::value +#if _LIBCPP_STD_VER <= 11 + && (!__node_traits::propagate_on_container_swap::value || + __is_nothrow_swappable<__node_allocator>::value) +#endif + ); + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + template + pair + __emplace_unique(_Args&&... __args); + template + iterator + __emplace_multi(_Args&&... __args); + + template + iterator + __emplace_hint_unique(const_iterator __p, _Args&&... __args); + template + iterator + __emplace_hint_multi(const_iterator __p, _Args&&... __args); +#endif // _LIBCPP_HAS_NO_VARIADICS + + template + pair __insert_unique(_Vp&& __v); + template + iterator __insert_unique(const_iterator __p, _Vp&& __v); + template + iterator __insert_multi(_Vp&& __v); + template + iterator __insert_multi(const_iterator __p, _Vp&& __v); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + pair __insert_unique(const value_type& __v); + iterator __insert_unique(const_iterator __p, const value_type& __v); + iterator __insert_multi(const value_type& __v); + iterator __insert_multi(const_iterator __p, const value_type& __v); + + pair __node_insert_unique(__node_pointer __nd); + iterator __node_insert_unique(const_iterator __p, + __node_pointer __nd); + + iterator __node_insert_multi(__node_pointer __nd); + iterator __node_insert_multi(const_iterator __p, __node_pointer __nd); + + iterator erase(const_iterator __p); + iterator erase(const_iterator __f, const_iterator __l); + template + size_type __erase_unique(const _Key& __k); + template + size_type __erase_multi(const _Key& __k); + + void __insert_node_at(__node_base_pointer __parent, + __node_base_pointer& __child, + __node_base_pointer __new_node); + + template + iterator find(const _Key& __v); + template + const_iterator find(const _Key& __v) const; + + template + size_type __count_unique(const _Key& __k) const; + template + size_type __count_multi(const _Key& __k) const; + + template + _LIBCPP_INLINE_VISIBILITY + iterator lower_bound(const _Key& __v) + {return __lower_bound(__v, __root(), __end_node());} + template + iterator __lower_bound(const _Key& __v, + __node_pointer __root, + __node_pointer __result); + template + _LIBCPP_INLINE_VISIBILITY + const_iterator lower_bound(const _Key& __v) const + {return __lower_bound(__v, __root(), __end_node());} + template + const_iterator __lower_bound(const _Key& __v, + __node_const_pointer __root, + __node_const_pointer __result) const; + template + _LIBCPP_INLINE_VISIBILITY + iterator upper_bound(const _Key& __v) + {return __upper_bound(__v, __root(), __end_node());} + template + iterator __upper_bound(const _Key& __v, + __node_pointer __root, + __node_pointer __result); + template + _LIBCPP_INLINE_VISIBILITY + const_iterator upper_bound(const _Key& __v) const + {return __upper_bound(__v, __root(), __end_node());} + template + const_iterator __upper_bound(const _Key& __v, + __node_const_pointer __root, + __node_const_pointer __result) const; + template + pair + __equal_range_unique(const _Key& __k); + template + pair + __equal_range_unique(const _Key& __k) const; + + template + pair + __equal_range_multi(const _Key& __k); + template + pair + __equal_range_multi(const _Key& __k) const; + + typedef __tree_node_destructor<__node_allocator> _Dp; + typedef unique_ptr<__node, _Dp> __node_holder; + + __node_holder remove(const_iterator __p) _NOEXCEPT; +private: + typename __node_base::pointer& + __find_leaf_low(typename __node_base::pointer& __parent, const value_type& __v); + typename __node_base::pointer& + __find_leaf_high(typename __node_base::pointer& __parent, const value_type& __v); + typename __node_base::pointer& + __find_leaf(const_iterator __hint, + typename __node_base::pointer& __parent, const value_type& __v); + template + typename __node_base::pointer& + __find_equal(typename __node_base::pointer& __parent, const _Key& __v); + template + typename __node_base::pointer& + __find_equal(const_iterator __hint, typename __node_base::pointer& __parent, + const _Key& __v); + +#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) + template + __node_holder __construct_node(_Args&& ...__args); +#else // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) + __node_holder __construct_node(const value_type& __v); +#endif + + void destroy(__node_pointer __nd) _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __tree& __t) + {__copy_assign_alloc(__t, integral_constant());} + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __tree& __t, true_type) + {__node_alloc() = __t.__node_alloc();} + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __tree& __t, false_type) {} + + void __move_assign(__tree& __t, false_type); + void __move_assign(__tree& __t, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value && + is_nothrow_move_assignable<__node_allocator>::value); + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__tree& __t) + _NOEXCEPT_( + !__node_traits::propagate_on_container_move_assignment::value || + is_nothrow_move_assignable<__node_allocator>::value) + {__move_assign_alloc(__t, integral_constant());} + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__tree& __t, true_type) + _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) + {__node_alloc() = _VSTD::move(__t.__node_alloc());} + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__tree& __t, false_type) _NOEXCEPT {} + + __node_pointer __detach(); + static __node_pointer __detach(__node_pointer); + + template friend class _LIBCPP_TYPE_VIS_ONLY map; + template friend class _LIBCPP_TYPE_VIS_ONLY multimap; +}; + +template +__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp) + _NOEXCEPT_( + is_nothrow_default_constructible<__node_allocator>::value && + is_nothrow_copy_constructible::value) + : __pair3_(0, __comp) +{ + __begin_node() = __end_node(); +} + +template +__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a) + : __begin_node_(__node_pointer()), + __pair1_(__node_allocator(__a)), + __pair3_(0) +{ + __begin_node() = __end_node(); +} + +template +__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp, + const allocator_type& __a) + : __begin_node_(__node_pointer()), + __pair1_(__node_allocator(__a)), + __pair3_(0, __comp) +{ + __begin_node() = __end_node(); +} + +// Precondition: size() != 0 +template +typename __tree<_Tp, _Compare, _Allocator>::__node_pointer +__tree<_Tp, _Compare, _Allocator>::__detach() +{ + __node_pointer __cache = __begin_node(); + __begin_node() = __end_node(); + __end_node()->__left_->__parent_ = nullptr; + __end_node()->__left_ = nullptr; + size() = 0; + // __cache->__left_ == nullptr + if (__cache->__right_ != nullptr) + __cache = static_cast<__node_pointer>(__cache->__right_); + // __cache->__left_ == nullptr + // __cache->__right_ == nullptr + return __cache; +} + +// Precondition: __cache != nullptr +// __cache->left_ == nullptr +// __cache->right_ == nullptr +// This is no longer a red-black tree +template +typename __tree<_Tp, _Compare, _Allocator>::__node_pointer +__tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache) +{ + if (__cache->__parent_ == nullptr) + return nullptr; + if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache))) + { + __cache->__parent_->__left_ = nullptr; + __cache = static_cast<__node_pointer>(__cache->__parent_); + if (__cache->__right_ == nullptr) + return __cache; + return static_cast<__node_pointer>(__tree_leaf(__cache->__right_)); + } + // __cache is right child + __cache->__parent_->__right_ = nullptr; + __cache = static_cast<__node_pointer>(__cache->__parent_); + if (__cache->__left_ == nullptr) + return __cache; + return static_cast<__node_pointer>(__tree_leaf(__cache->__left_)); +} + +template +__tree<_Tp, _Compare, _Allocator>& +__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t) +{ + if (this != &__t) + { + value_comp() = __t.value_comp(); + __copy_assign_alloc(__t); + __assign_multi(__t.begin(), __t.end()); + } + return *this; +} + +template +template +void +__tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last) +{ + if (size() != 0) + { + __node_pointer __cache = __detach(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (; __cache != nullptr && __first != __last; ++__first) + { + __cache->__value_ = *__first; + __node_pointer __next = __detach(__cache); + __node_insert_unique(__cache); + __cache = __next; + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + while (__cache->__parent_ != nullptr) + __cache = static_cast<__node_pointer>(__cache->__parent_); + destroy(__cache); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + if (__cache != nullptr) + { + while (__cache->__parent_ != nullptr) + __cache = static_cast<__node_pointer>(__cache->__parent_); + destroy(__cache); + } + } + for (; __first != __last; ++__first) + __insert_unique(*__first); +} + +template +template +void +__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last) +{ + if (size() != 0) + { + __node_pointer __cache = __detach(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (; __cache != nullptr && __first != __last; ++__first) + { + __cache->__value_ = *__first; + __node_pointer __next = __detach(__cache); + __node_insert_multi(__cache); + __cache = __next; + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + while (__cache->__parent_ != nullptr) + __cache = static_cast<__node_pointer>(__cache->__parent_); + destroy(__cache); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + if (__cache != nullptr) + { + while (__cache->__parent_ != nullptr) + __cache = static_cast<__node_pointer>(__cache->__parent_); + destroy(__cache); + } + } + for (; __first != __last; ++__first) + __insert_multi(*__first); +} + +template +__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t) + : __begin_node_(__node_pointer()), + __pair1_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())), + __pair3_(0, __t.value_comp()) +{ + __begin_node() = __end_node(); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) + _NOEXCEPT_( + is_nothrow_move_constructible<__node_allocator>::value && + is_nothrow_move_constructible::value) + : __begin_node_(_VSTD::move(__t.__begin_node_)), + __pair1_(_VSTD::move(__t.__pair1_)), + __pair3_(_VSTD::move(__t.__pair3_)) +{ + if (size() == 0) + __begin_node() = __end_node(); + else + { + __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node()); + __t.__begin_node() = __t.__end_node(); + __t.__end_node()->__left_ = nullptr; + __t.size() = 0; + } +} + +template +__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a) + : __pair1_(__node_allocator(__a)), + __pair3_(0, _VSTD::move(__t.value_comp())) +{ + if (__a == __t.__alloc()) + { + if (__t.size() == 0) + __begin_node() = __end_node(); + else + { + __begin_node() = __t.__begin_node(); + __end_node()->__left_ = __t.__end_node()->__left_; + __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node()); + size() = __t.size(); + __t.__begin_node() = __t.__end_node(); + __t.__end_node()->__left_ = nullptr; + __t.size() = 0; + } + } + else + { + __begin_node() = __end_node(); + } +} + +template +void +__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value && + is_nothrow_move_assignable<__node_allocator>::value) +{ + destroy(static_cast<__node_pointer>(__end_node()->__left_)); + __begin_node_ = __t.__begin_node_; + __pair1_.first() = __t.__pair1_.first(); + __move_assign_alloc(__t); + __pair3_ = _VSTD::move(__t.__pair3_); + if (size() == 0) + __begin_node() = __end_node(); + else + { + __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node()); + __t.__begin_node() = __t.__end_node(); + __t.__end_node()->__left_ = nullptr; + __t.size() = 0; + } +} + +template +void +__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) +{ + if (__node_alloc() == __t.__node_alloc()) + __move_assign(__t, true_type()); + else + { + value_comp() = _VSTD::move(__t.value_comp()); + const_iterator __e = end(); + if (size() != 0) + { + __node_pointer __cache = __detach(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + while (__cache != nullptr && __t.size() != 0) + { + __cache->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_); + __node_pointer __next = __detach(__cache); + __node_insert_multi(__cache); + __cache = __next; + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + while (__cache->__parent_ != nullptr) + __cache = static_cast<__node_pointer>(__cache->__parent_); + destroy(__cache); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + if (__cache != nullptr) + { + while (__cache->__parent_ != nullptr) + __cache = static_cast<__node_pointer>(__cache->__parent_); + destroy(__cache); + } + } + while (__t.size() != 0) + __insert_multi(__e, _VSTD::move(__t.remove(__t.begin())->__value_)); + } +} + +template +__tree<_Tp, _Compare, _Allocator>& +__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable<__node_allocator>::value) + +{ + __move_assign(__t, integral_constant()); + return *this; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +__tree<_Tp, _Compare, _Allocator>::~__tree() +{ + destroy(__root()); +} + +template +void +__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT +{ + if (__nd != nullptr) + { + destroy(static_cast<__node_pointer>(__nd->__left_)); + destroy(static_cast<__node_pointer>(__nd->__right_)); + __node_allocator& __na = __node_alloc(); + __node_traits::destroy(__na, _VSTD::addressof(__nd->__value_)); + __node_traits::deallocate(__na, __nd, 1); + } +} + +template +void +__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t) + _NOEXCEPT_( + __is_nothrow_swappable::value +#if _LIBCPP_STD_VER <= 11 + && (!__node_traits::propagate_on_container_swap::value || + __is_nothrow_swappable<__node_allocator>::value) +#endif + ) +{ + using _VSTD::swap; + swap(__begin_node_, __t.__begin_node_); + swap(__pair1_.first(), __t.__pair1_.first()); + __swap_allocator(__node_alloc(), __t.__node_alloc()); + __pair3_.swap(__t.__pair3_); + if (size() == 0) + __begin_node() = __end_node(); + else + __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node()); + if (__t.size() == 0) + __t.__begin_node() = __t.__end_node(); + else + __t.__end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__t.__end_node()); +} + +template +void +__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT +{ + destroy(__root()); + size() = 0; + __begin_node() = __end_node(); + __end_node()->__left_ = nullptr; +} + +// Find lower_bound place to insert +// Set __parent to parent of null leaf +// Return reference to null leaf +template +typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& +__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node_base::pointer& __parent, + const value_type& __v) +{ + __node_pointer __nd = __root(); + if (__nd != nullptr) + { + while (true) + { + if (value_comp()(__nd->__value_, __v)) + { + if (__nd->__right_ != nullptr) + __nd = static_cast<__node_pointer>(__nd->__right_); + else + { + __parent = static_cast<__node_base_pointer>(__nd); + return __parent->__right_; + } + } + else + { + if (__nd->__left_ != nullptr) + __nd = static_cast<__node_pointer>(__nd->__left_); + else + { + __parent = static_cast<__node_base_pointer>(__nd); + return __parent->__left_; + } + } + } + } + __parent = static_cast<__node_base_pointer>(__end_node()); + return __parent->__left_; +} + +// Find upper_bound place to insert +// Set __parent to parent of null leaf +// Return reference to null leaf +template +typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& +__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node_base::pointer& __parent, + const value_type& __v) +{ + __node_pointer __nd = __root(); + if (__nd != nullptr) + { + while (true) + { + if (value_comp()(__v, __nd->__value_)) + { + if (__nd->__left_ != nullptr) + __nd = static_cast<__node_pointer>(__nd->__left_); + else + { + __parent = static_cast<__node_base_pointer>(__nd); + return __parent->__left_; + } + } + else + { + if (__nd->__right_ != nullptr) + __nd = static_cast<__node_pointer>(__nd->__right_); + else + { + __parent = static_cast<__node_base_pointer>(__nd); + return __parent->__right_; + } + } + } + } + __parent = static_cast<__node_base_pointer>(__end_node()); + return __parent->__left_; +} + +// Find leaf place to insert closest to __hint +// First check prior to __hint. +// Next check after __hint. +// Next do O(log N) search. +// Set __parent to parent of null leaf +// Return reference to null leaf +template +typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& +__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint, + typename __node_base::pointer& __parent, + const value_type& __v) +{ + if (__hint == end() || !value_comp()(*__hint, __v)) // check before + { + // __v <= *__hint + const_iterator __prior = __hint; + if (__prior == begin() || !value_comp()(__v, *--__prior)) + { + // *prev(__hint) <= __v <= *__hint + if (__hint.__ptr_->__left_ == nullptr) + { + __parent = static_cast<__node_base_pointer>(__hint.__ptr_); + return __parent->__left_; + } + else + { + __parent = static_cast<__node_base_pointer>(__prior.__ptr_); + return __parent->__right_; + } + } + // __v < *prev(__hint) + return __find_leaf_high(__parent, __v); + } + // else __v > *__hint + return __find_leaf_low(__parent, __v); +} + +// Find place to insert if __v doesn't exist +// Set __parent to parent of null leaf +// Return reference to null leaf +// If __v exists, set parent to node of __v and return reference to node of __v +template +template +typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& +__tree<_Tp, _Compare, _Allocator>::__find_equal(typename __node_base::pointer& __parent, + const _Key& __v) +{ + __node_pointer __nd = __root(); + if (__nd != nullptr) + { + while (true) + { + if (value_comp()(__v, __nd->__value_)) + { + if (__nd->__left_ != nullptr) + __nd = static_cast<__node_pointer>(__nd->__left_); + else + { + __parent = static_cast<__node_base_pointer>(__nd); + return __parent->__left_; + } + } + else if (value_comp()(__nd->__value_, __v)) + { + if (__nd->__right_ != nullptr) + __nd = static_cast<__node_pointer>(__nd->__right_); + else + { + __parent = static_cast<__node_base_pointer>(__nd); + return __parent->__right_; + } + } + else + { + __parent = static_cast<__node_base_pointer>(__nd); + return __parent; + } + } + } + __parent = static_cast<__node_base_pointer>(__end_node()); + return __parent->__left_; +} + +// Find place to insert if __v doesn't exist +// First check prior to __hint. +// Next check after __hint. +// Next do O(log N) search. +// Set __parent to parent of null leaf +// Return reference to null leaf +// If __v exists, set parent to node of __v and return reference to node of __v +template +template +typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& +__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, + typename __node_base::pointer& __parent, + const _Key& __v) +{ + if (__hint == end() || value_comp()(__v, *__hint)) // check before + { + // __v < *__hint + const_iterator __prior = __hint; + if (__prior == begin() || value_comp()(*--__prior, __v)) + { + // *prev(__hint) < __v < *__hint + if (__hint.__ptr_->__left_ == nullptr) + { + __parent = static_cast<__node_base_pointer>(__hint.__ptr_); + return __parent->__left_; + } + else + { + __parent = static_cast<__node_base_pointer>(__prior.__ptr_); + return __parent->__right_; + } + } + // __v <= *prev(__hint) + return __find_equal(__parent, __v); + } + else if (value_comp()(*__hint, __v)) // check after + { + // *__hint < __v + const_iterator __next = _VSTD::next(__hint); + if (__next == end() || value_comp()(__v, *__next)) + { + // *__hint < __v < *_VSTD::next(__hint) + if (__hint.__ptr_->__right_ == nullptr) + { + __parent = static_cast<__node_base_pointer>(__hint.__ptr_); + return __parent->__right_; + } + else + { + __parent = static_cast<__node_base_pointer>(__next.__ptr_); + return __parent->__left_; + } + } + // *next(__hint) <= __v + return __find_equal(__parent, __v); + } + // else __v == *__hint + __parent = static_cast<__node_base_pointer>(__hint.__ptr_); + return __parent; +} + +template +void +__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__node_base_pointer __parent, + __node_base_pointer& __child, + __node_base_pointer __new_node) +{ + __new_node->__left_ = nullptr; + __new_node->__right_ = nullptr; + __new_node->__parent_ = __parent; + __child = __new_node; + if (__begin_node()->__left_ != nullptr) + __begin_node() = static_cast<__node_pointer>(__begin_node()->__left_); + __tree_balance_after_insert(__end_node()->__left_, __child); + ++size(); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + +template +template +typename __tree<_Tp, _Compare, _Allocator>::__node_holder +__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args) +{ + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...); + __h.get_deleter().__value_constructed = true; + return __h; +} + +template +template +pair::iterator, bool> +__tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + __node_base_pointer __parent; + __node_base_pointer& __child = __find_equal(__parent, __h->__value_); + __node_pointer __r = static_cast<__node_pointer>(__child); + bool __inserted = false; + if (__child == nullptr) + { + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + __r = __h.release(); + __inserted = true; + } + return pair(iterator(__r), __inserted); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique(const_iterator __p, _Args&&... __args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + __node_base_pointer __parent; + __node_base_pointer& __child = __find_equal(__p, __parent, __h->__value_); + __node_pointer __r = static_cast<__node_pointer>(__child); + if (__child == nullptr) + { + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + __r = __h.release(); + } + return iterator(__r); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + __node_base_pointer __parent; + __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + return iterator(static_cast<__node_pointer>(__h.release())); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, + _Args&&... __args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + __node_base_pointer __parent; + __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + return iterator(static_cast<__node_pointer>(__h.release())); +} + +#endif // _LIBCPP_HAS_NO_VARIADICS + +template +template +pair::iterator, bool> +__tree<_Tp, _Compare, _Allocator>::__insert_unique(_Vp&& __v) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v)); + pair __r = __node_insert_unique(__h.get()); + if (__r.second) + __h.release(); + return __r; +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, _Vp&& __v) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v)); + iterator __r = __node_insert_unique(__p, __h.get()); + if (__r.__ptr_ == __h.get()) + __h.release(); + return __r; +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__insert_multi(_Vp&& __v) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v)); + __node_base_pointer __parent; + __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + return iterator(__h.release()); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, _Vp&& __v) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v)); + __node_base_pointer __parent; + __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + return iterator(__h.release()); +} + +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +typename __tree<_Tp, _Compare, _Allocator>::__node_holder +__tree<_Tp, _Compare, _Allocator>::__construct_node(const value_type& __v) +{ + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v); + __h.get_deleter().__value_constructed = true; + return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +pair::iterator, bool> +__tree<_Tp, _Compare, _Allocator>::__insert_unique(const value_type& __v) +{ + __node_base_pointer __parent; + __node_base_pointer& __child = __find_equal(__parent, __v); + __node_pointer __r = static_cast<__node_pointer>(__child); + bool __inserted = false; + if (__child == nullptr) + { + __node_holder __h = __construct_node(__v); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + __r = __h.release(); + __inserted = true; + } + return pair(iterator(__r), __inserted); +} + +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, const value_type& __v) +{ + __node_base_pointer __parent; + __node_base_pointer& __child = __find_equal(__p, __parent, __v); + __node_pointer __r = static_cast<__node_pointer>(__child); + if (__child == nullptr) + { + __node_holder __h = __construct_node(__v); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + __r = __h.release(); + } + return iterator(__r); +} + +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__insert_multi(const value_type& __v) +{ + __node_base_pointer __parent; + __node_base_pointer& __child = __find_leaf_high(__parent, __v); + __node_holder __h = __construct_node(__v); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + return iterator(__h.release()); +} + +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const value_type& __v) +{ + __node_base_pointer __parent; + __node_base_pointer& __child = __find_leaf(__p, __parent, __v); + __node_holder __h = __construct_node(__v); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + return iterator(__h.release()); +} + +template +pair::iterator, bool> +__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd) +{ + __node_base_pointer __parent; + __node_base_pointer& __child = __find_equal(__parent, __nd->__value_); + __node_pointer __r = static_cast<__node_pointer>(__child); + bool __inserted = false; + if (__child == nullptr) + { + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); + __r = __nd; + __inserted = true; + } + return pair(iterator(__r), __inserted); +} + +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p, + __node_pointer __nd) +{ + __node_base_pointer __parent; + __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_); + __node_pointer __r = static_cast<__node_pointer>(__child); + if (__child == nullptr) + { + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); + __r = __nd; + } + return iterator(__r); +} + +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd) +{ + __node_base_pointer __parent; + __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); + return iterator(__nd); +} + +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, + __node_pointer __nd) +{ + __node_base_pointer __parent; + __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); + return iterator(__nd); +} + +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p) +{ + __node_pointer __np = __p.__ptr_; + iterator __r(__np); + ++__r; + if (__begin_node() == __np) + __begin_node() = __r.__ptr_; + --size(); + __node_allocator& __na = __node_alloc(); + __tree_remove(__end_node()->__left_, + static_cast<__node_base_pointer>(__np)); + __node_traits::destroy(__na, const_cast(_VSTD::addressof(*__p))); + __node_traits::deallocate(__na, __np, 1); + return __r; +} + +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l) +{ + while (__f != __l) + __f = erase(__f); + return iterator(__l.__ptr_); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::size_type +__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k) +{ + iterator __i = find(__k); + if (__i == end()) + return 0; + erase(__i); + return 1; +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::size_type +__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k) +{ + pair __p = __equal_range_multi(__k); + size_type __r = 0; + for (; __p.first != __p.second; ++__r) + __p.first = erase(__p.first); + return __r; +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) +{ + iterator __p = __lower_bound(__v, __root(), __end_node()); + if (__p != end() && !value_comp()(__v, *__p)) + return __p; + return end(); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::const_iterator +__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const +{ + const_iterator __p = __lower_bound(__v, __root(), __end_node()); + if (__p != end() && !value_comp()(__v, *__p)) + return __p; + return end(); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::size_type +__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const +{ + __node_const_pointer __result = __end_node(); + __node_const_pointer __rt = __root(); + while (__rt != nullptr) + { + if (value_comp()(__k, __rt->__value_)) + { + __result = __rt; + __rt = static_cast<__node_const_pointer>(__rt->__left_); + } + else if (value_comp()(__rt->__value_, __k)) + __rt = static_cast<__node_const_pointer>(__rt->__right_); + else + return 1; + } + return 0; +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::size_type +__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const +{ + __node_const_pointer __result = __end_node(); + __node_const_pointer __rt = __root(); + while (__rt != nullptr) + { + if (value_comp()(__k, __rt->__value_)) + { + __result = __rt; + __rt = static_cast<__node_const_pointer>(__rt->__left_); + } + else if (value_comp()(__rt->__value_, __k)) + __rt = static_cast<__node_const_pointer>(__rt->__right_); + else + return _VSTD::distance( + __lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt), + __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result) + ); + } + return 0; +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, + __node_pointer __root, + __node_pointer __result) +{ + while (__root != nullptr) + { + if (!value_comp()(__root->__value_, __v)) + { + __result = __root; + __root = static_cast<__node_pointer>(__root->__left_); + } + else + __root = static_cast<__node_pointer>(__root->__right_); + } + return iterator(__result); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::const_iterator +__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, + __node_const_pointer __root, + __node_const_pointer __result) const +{ + while (__root != nullptr) + { + if (!value_comp()(__root->__value_, __v)) + { + __result = __root; + __root = static_cast<__node_const_pointer>(__root->__left_); + } + else + __root = static_cast<__node_const_pointer>(__root->__right_); + } + return const_iterator(__result); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, + __node_pointer __root, + __node_pointer __result) +{ + while (__root != nullptr) + { + if (value_comp()(__v, __root->__value_)) + { + __result = __root; + __root = static_cast<__node_pointer>(__root->__left_); + } + else + __root = static_cast<__node_pointer>(__root->__right_); + } + return iterator(__result); +} + +template +template +typename __tree<_Tp, _Compare, _Allocator>::const_iterator +__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, + __node_const_pointer __root, + __node_const_pointer __result) const +{ + while (__root != nullptr) + { + if (value_comp()(__v, __root->__value_)) + { + __result = __root; + __root = static_cast<__node_const_pointer>(__root->__left_); + } + else + __root = static_cast<__node_const_pointer>(__root->__right_); + } + return const_iterator(__result); +} + +template +template +pair::iterator, + typename __tree<_Tp, _Compare, _Allocator>::iterator> +__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) +{ + typedef pair _Pp; + __node_pointer __result = __end_node(); + __node_pointer __rt = __root(); + while (__rt != nullptr) + { + if (value_comp()(__k, __rt->__value_)) + { + __result = __rt; + __rt = static_cast<__node_pointer>(__rt->__left_); + } + else if (value_comp()(__rt->__value_, __k)) + __rt = static_cast<__node_pointer>(__rt->__right_); + else + return _Pp(iterator(__rt), + iterator( + __rt->__right_ != nullptr ? + static_cast<__node_pointer>(__tree_min(__rt->__right_)) + : __result)); + } + return _Pp(iterator(__result), iterator(__result)); +} + +template +template +pair::const_iterator, + typename __tree<_Tp, _Compare, _Allocator>::const_iterator> +__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const +{ + typedef pair _Pp; + __node_const_pointer __result = __end_node(); + __node_const_pointer __rt = __root(); + while (__rt != nullptr) + { + if (value_comp()(__k, __rt->__value_)) + { + __result = __rt; + __rt = static_cast<__node_const_pointer>(__rt->__left_); + } + else if (value_comp()(__rt->__value_, __k)) + __rt = static_cast<__node_const_pointer>(__rt->__right_); + else + return _Pp(const_iterator(__rt), + const_iterator( + __rt->__right_ != nullptr ? + static_cast<__node_const_pointer>(__tree_min(__rt->__right_)) + : __result)); + } + return _Pp(const_iterator(__result), const_iterator(__result)); +} + +template +template +pair::iterator, + typename __tree<_Tp, _Compare, _Allocator>::iterator> +__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) +{ + typedef pair _Pp; + __node_pointer __result = __end_node(); + __node_pointer __rt = __root(); + while (__rt != nullptr) + { + if (value_comp()(__k, __rt->__value_)) + { + __result = __rt; + __rt = static_cast<__node_pointer>(__rt->__left_); + } + else if (value_comp()(__rt->__value_, __k)) + __rt = static_cast<__node_pointer>(__rt->__right_); + else + return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), __rt), + __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); + } + return _Pp(iterator(__result), iterator(__result)); +} + +template +template +pair::const_iterator, + typename __tree<_Tp, _Compare, _Allocator>::const_iterator> +__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const +{ + typedef pair _Pp; + __node_const_pointer __result = __end_node(); + __node_const_pointer __rt = __root(); + while (__rt != nullptr) + { + if (value_comp()(__k, __rt->__value_)) + { + __result = __rt; + __rt = static_cast<__node_const_pointer>(__rt->__left_); + } + else if (value_comp()(__rt->__value_, __k)) + __rt = static_cast<__node_const_pointer>(__rt->__right_); + else + return _Pp(__lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt), + __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result)); + } + return _Pp(const_iterator(__result), const_iterator(__result)); +} + +template +typename __tree<_Tp, _Compare, _Allocator>::__node_holder +__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT +{ + __node_pointer __np = __p.__ptr_; + if (__begin_node() == __np) + { + if (__np->__right_ != nullptr) + __begin_node() = static_cast<__node_pointer>(__np->__right_); + else + __begin_node() = static_cast<__node_pointer>(__np->__parent_); + } + --size(); + __tree_remove(__end_node()->__left_, + static_cast<__node_base_pointer>(__np)); + return __node_holder(__np, _Dp(__node_alloc(), true)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__tree<_Tp, _Compare, _Allocator>& __x, + __tree<_Tp, _Compare, _Allocator>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TREE diff --git a/headers/libs/libc++/__tuple b/headers/libs/libc++/__tuple new file mode 100644 index 0000000000..57581e8428 --- /dev/null +++ b/headers/libs/libc++/__tuple @@ -0,0 +1,348 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TUPLE +#define _LIBCPP___TUPLE + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + + +_LIBCPP_BEGIN_NAMESPACE_STD + +template class _LIBCPP_TYPE_VIS_ONLY tuple_size; + +template +class _LIBCPP_TYPE_VIS_ONLY tuple_size + : public tuple_size<_Tp> {}; + +template +class _LIBCPP_TYPE_VIS_ONLY tuple_size + : public tuple_size<_Tp> {}; + +template +class _LIBCPP_TYPE_VIS_ONLY tuple_size + : public tuple_size<_Tp> {}; + +template class _LIBCPP_TYPE_VIS_ONLY tuple_element; + +template +class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const _Tp> +{ +public: + typedef typename add_const::type>::type type; +}; + +template +class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, volatile _Tp> +{ +public: + typedef typename add_volatile::type>::type type; +}; + +template +class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const volatile _Tp> +{ +public: + typedef typename add_cv::type>::type type; +}; + +template struct __tuple_like : false_type {}; + +template struct __tuple_like : public __tuple_like<_Tp> {}; +template struct __tuple_like : public __tuple_like<_Tp> {}; +template struct __tuple_like : public __tuple_like<_Tp> {}; + +// tuple specializations + +#if !defined(_LIBCPP_HAS_NO_VARIADICS) +template class _LIBCPP_TYPE_VIS_ONLY tuple; + +template struct __tuple_like > : true_type {}; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +typename tuple_element<_Ip, tuple<_Tp...> >::type& +get(tuple<_Tp...>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +const typename tuple_element<_Ip, tuple<_Tp...> >::type& +get(const tuple<_Tp...>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +typename tuple_element<_Ip, tuple<_Tp...> >::type&& +get(tuple<_Tp...>&&) _NOEXCEPT; +#endif + +// pair specializations + +template struct _LIBCPP_TYPE_VIS_ONLY pair; + +template struct __tuple_like > : true_type {}; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +typename tuple_element<_Ip, pair<_T1, _T2> >::type& +get(pair<_T1, _T2>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +const typename tuple_element<_Ip, pair<_T1, _T2> >::type& +get(const pair<_T1, _T2>&) _NOEXCEPT; + +#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +typename tuple_element<_Ip, pair<_T1, _T2> >::type&& +get(pair<_T1, _T2>&&) _NOEXCEPT; +#endif + +// array specializations + +template struct _LIBCPP_TYPE_VIS_ONLY array; + +template struct __tuple_like > : true_type {}; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp& +get(array<_Tp, _Size>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +const _Tp& +get(const array<_Tp, _Size>&) _NOEXCEPT; + +#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp&& +get(array<_Tp, _Size>&&) _NOEXCEPT; +#endif + +#if !defined(_LIBCPP_HAS_NO_VARIADICS) + +// __make_tuple_indices + +template struct __tuple_indices {}; + +template +struct __make_indices_imp; + +template +struct __make_indices_imp<_Sp, __tuple_indices<_Indices...>, _Ep> +{ + typedef typename __make_indices_imp<_Sp+1, __tuple_indices<_Indices..., _Sp>, _Ep>::type type; +}; + +template +struct __make_indices_imp<_Ep, __tuple_indices<_Indices...>, _Ep> +{ + typedef __tuple_indices<_Indices...> type; +}; + +template +struct __make_tuple_indices +{ + static_assert(_Sp <= _Ep, "__make_tuple_indices input error"); + typedef typename __make_indices_imp<_Sp, __tuple_indices<>, _Ep>::type type; +}; + +// __tuple_types + +template struct __tuple_types {}; + +template +class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<> > +{ +public: + static_assert(_Ip == 0, "tuple_element index out of range"); + static_assert(_Ip != 0, "tuple_element index out of range"); +}; + +template +class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, __tuple_types<_Hp, _Tp...> > +{ +public: + typedef _Hp type; +}; + +template +class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<_Hp, _Tp...> > +{ +public: + typedef typename tuple_element<_Ip-1, __tuple_types<_Tp...> >::type type; +}; + +template +class _LIBCPP_TYPE_VIS_ONLY tuple_size<__tuple_types<_Tp...> > + : public integral_constant +{ +}; + +template struct __tuple_like<__tuple_types<_Tp...> > : true_type {}; + +// __make_tuple_types + +// __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a +// __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep). +// _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>. If _Tuple is a +// lvalue_reference type, then __tuple_types<_Types&...> is the result. + +template +struct __make_tuple_types_imp; + +template +struct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Sp, _Ep> +{ + typedef typename remove_reference<_Tp>::type _Tpr; + typedef typename __make_tuple_types_imp<__tuple_types<_Types..., + typename conditional::value, + typename tuple_element<_Sp, _Tpr>::type&, + typename tuple_element<_Sp, _Tpr>::type>::type>, + _Tp, _Sp+1, _Ep>::type type; +}; + +template +struct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Ep, _Ep> +{ + typedef __tuple_types<_Types...> type; +}; + +template ::type>::value, size_t _Sp = 0> +struct __make_tuple_types +{ + static_assert(_Sp <= _Ep, "__make_tuple_types input error"); + typedef typename __make_tuple_types_imp<__tuple_types<>, _Tp, _Sp, _Ep>::type type; +}; + +// __tuple_convertible + +template +struct __tuple_convertible_imp : public false_type {}; + +template +struct __tuple_convertible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > + : public integral_constant::value && + __tuple_convertible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; + +template <> +struct __tuple_convertible_imp<__tuple_types<>, __tuple_types<> > + : public true_type {}; + +template +struct __tuple_convertible_apply : public false_type {}; + +template +struct __tuple_convertible_apply + : public __tuple_convertible_imp< + typename __make_tuple_types<_Tp>::type + , typename __make_tuple_types<_Up>::type + > +{}; + +template ::type>::value, + bool = __tuple_like<_Up>::value> +struct __tuple_convertible + : public false_type {}; + +template +struct __tuple_convertible<_Tp, _Up, true, true> + : public __tuple_convertible_apply::type>::value == + tuple_size<_Up>::value, _Tp, _Up> +{}; + +// __tuple_constructible + +template +struct __tuple_constructible_imp : public false_type {}; + +template +struct __tuple_constructible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > + : public integral_constant::value && + __tuple_constructible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; + +template <> +struct __tuple_constructible_imp<__tuple_types<>, __tuple_types<> > + : public true_type {}; + +template +struct __tuple_constructible_apply : public false_type {}; + +template +struct __tuple_constructible_apply + : public __tuple_constructible_imp< + typename __make_tuple_types<_Tp>::type + , typename __make_tuple_types<_Up>::type + > +{}; + +template ::type>::value, + bool = __tuple_like<_Up>::value> +struct __tuple_constructible + : public false_type {}; + +template +struct __tuple_constructible<_Tp, _Up, true, true> + : public __tuple_constructible_apply::type>::value == + tuple_size<_Up>::value, _Tp, _Up> +{}; + +// __tuple_assignable + +template +struct __tuple_assignable_imp : public false_type {}; + +template +struct __tuple_assignable_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > + : public integral_constant::value && + __tuple_assignable_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; + +template <> +struct __tuple_assignable_imp<__tuple_types<>, __tuple_types<> > + : public true_type {}; + +template +struct __tuple_assignable_apply : public false_type {}; + +template +struct __tuple_assignable_apply + : __tuple_assignable_imp< + typename __make_tuple_types<_Tp>::type + , typename __make_tuple_types<_Up>::type + > +{}; + +template ::type>::value, + bool = __tuple_like<_Up>::value> +struct __tuple_assignable + : public false_type {}; + +template +struct __tuple_assignable<_Tp, _Up, true, true> + : public __tuple_assignable_apply::type>::value == + tuple_size<_Up>::value, _Tp, _Up> +{}; + +#endif // _LIBCPP_HAS_NO_VARIADICS + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TUPLE diff --git a/headers/libs/libc++/__undef___deallocate b/headers/libs/libc++/__undef___deallocate new file mode 100644 index 0000000000..2b4ad99dad --- /dev/null +++ b/headers/libs/libc++/__undef___deallocate @@ -0,0 +1,18 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifdef __deallocate +#if defined(_MSC_VER) && !defined(__clang__) +_LIBCPP_WARNING("macro __deallocate is incompatible with C++. #undefining __deallocate") +#else +#warning: macro __deallocate is incompatible with C++. #undefining __deallocate +#endif +#undef __deallocate +#endif diff --git a/headers/libs/libc++/__undef_min_max b/headers/libs/libc++/__undef_min_max new file mode 100644 index 0000000000..5df9412c64 --- /dev/null +++ b/headers/libs/libc++/__undef_min_max @@ -0,0 +1,29 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifdef min +#if defined(_MSC_VER) && ! defined(__clang__) +_LIBCPP_WARNING("macro min is incompatible with C++. Try #define NOMINMAX " + "before any Windows header. #undefing min") +#else +#warning: macro min is incompatible with C++. #undefing min +#endif +#undef min +#endif + +#ifdef max +#if defined(_MSC_VER) && ! defined(__clang__) +_LIBCPP_WARNING("macro max is incompatible with C++. Try #define NOMINMAX " + "before any Windows header. #undefing max") +#else +#warning: macro max is incompatible with C++. #undefing max +#endif +#undef max +#endif diff --git a/headers/libs/libc++/algorithm b/headers/libs/libc++/algorithm new file mode 100644 index 0000000000..9c05119893 --- /dev/null +++ b/headers/libs/libc++/algorithm @@ -0,0 +1,5777 @@ +// -*- C++ -*- +//===-------------------------- algorithm ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_ALGORITHM +#define _LIBCPP_ALGORITHM + +/* + algorithm synopsis + +#include + +namespace std +{ + +template + bool + all_of(InputIterator first, InputIterator last, Predicate pred); + +template + bool + any_of(InputIterator first, InputIterator last, Predicate pred); + +template + bool + none_of(InputIterator first, InputIterator last, Predicate pred); + +template + Function + for_each(InputIterator first, InputIterator last, Function f); + +template + InputIterator + find(InputIterator first, InputIterator last, const T& value); + +template + InputIterator + find_if(InputIterator first, InputIterator last, Predicate pred); + +template + InputIterator + find_if_not(InputIterator first, InputIterator last, Predicate pred); + +template + ForwardIterator1 + find_end(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + +template + ForwardIterator1 + find_end(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); + +template + ForwardIterator1 + find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + +template + ForwardIterator1 + find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); + +template + ForwardIterator + adjacent_find(ForwardIterator first, ForwardIterator last); + +template + ForwardIterator + adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); + +template + typename iterator_traits::difference_type + count(InputIterator first, InputIterator last, const T& value); + +template + typename iterator_traits::difference_type + count_if(InputIterator first, InputIterator last, Predicate pred); + +template + pair + mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); + +template + pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); // **C++14** + +template + pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, BinaryPredicate pred); + +template + pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred); // **C++14** + +template + bool + equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); + +template + bool + equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); // **C++14** + +template + bool + equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, BinaryPredicate pred); + +template + bool + equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred); // **C++14** + +template + bool + is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + +template + bool + is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); // **C++14** + +template + bool + is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); + +template + bool + is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); // **C++14** + +template + ForwardIterator1 + search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + +template + ForwardIterator1 + search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); + +template + ForwardIterator + search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value); + +template + ForwardIterator + search_n(ForwardIterator first, ForwardIterator last, + Size count, const T& value, BinaryPredicate pred); + +template + OutputIterator + copy(InputIterator first, InputIterator last, OutputIterator result); + +template + OutputIterator + copy_if(InputIterator first, InputIterator last, + OutputIterator result, Predicate pred); + +template + OutputIterator + copy_n(InputIterator first, Size n, OutputIterator result); + +template + BidirectionalIterator2 + copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, + BidirectionalIterator2 result); + +template + ForwardIterator2 + swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); + +template + void + iter_swap(ForwardIterator1 a, ForwardIterator2 b); + +template + OutputIterator + transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op); + +template + OutputIterator + transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, + OutputIterator result, BinaryOperation binary_op); + +template + void + replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); + +template + void + replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value); + +template + OutputIterator + replace_copy(InputIterator first, InputIterator last, OutputIterator result, + const T& old_value, const T& new_value); + +template + OutputIterator + replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value); + +template + void + fill(ForwardIterator first, ForwardIterator last, const T& value); + +template + OutputIterator + fill_n(OutputIterator first, Size n, const T& value); + +template + void + generate(ForwardIterator first, ForwardIterator last, Generator gen); + +template + OutputIterator + generate_n(OutputIterator first, Size n, Generator gen); + +template + ForwardIterator + remove(ForwardIterator first, ForwardIterator last, const T& value); + +template + ForwardIterator + remove_if(ForwardIterator first, ForwardIterator last, Predicate pred); + +template + OutputIterator + remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value); + +template + OutputIterator + remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); + +template + ForwardIterator + unique(ForwardIterator first, ForwardIterator last); + +template + ForwardIterator + unique(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); + +template + OutputIterator + unique_copy(InputIterator first, InputIterator last, OutputIterator result); + +template + OutputIterator + unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred); + +template + void + reverse(BidirectionalIterator first, BidirectionalIterator last); + +template + OutputIterator + reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result); + +template + ForwardIterator + rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last); + +template + OutputIterator + rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result); + +template + void + random_shuffle(RandomAccessIterator first, RandomAccessIterator last); // deprecated in C++14 + +template + void + random_shuffle(RandomAccessIterator first, RandomAccessIterator last, + RandomNumberGenerator& rand); // deprecated in C++14 + +template + void shuffle(RandomAccessIterator first, RandomAccessIterator last, + UniformRandomNumberGenerator&& g); + +template + bool + is_partitioned(InputIterator first, InputIterator last, Predicate pred); + +template + ForwardIterator + partition(ForwardIterator first, ForwardIterator last, Predicate pred); + +template + pair + partition_copy(InputIterator first, InputIterator last, + OutputIterator1 out_true, OutputIterator2 out_false, + Predicate pred); + +template + ForwardIterator + stable_partition(ForwardIterator first, ForwardIterator last, Predicate pred); + +template + ForwardIterator + partition_point(ForwardIterator first, ForwardIterator last, Predicate pred); + +template + bool + is_sorted(ForwardIterator first, ForwardIterator last); + +template + bool + is_sorted(ForwardIterator first, ForwardIterator last, Compare comp); + +template + ForwardIterator + is_sorted_until(ForwardIterator first, ForwardIterator last); + +template + ForwardIterator + is_sorted_until(ForwardIterator first, ForwardIterator last, Compare comp); + +template + void + sort(RandomAccessIterator first, RandomAccessIterator last); + +template + void + sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); + +template + void + stable_sort(RandomAccessIterator first, RandomAccessIterator last); + +template + void + stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); + +template + void + partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last); + +template + void + partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp); + +template + RandomAccessIterator + partial_sort_copy(InputIterator first, InputIterator last, + RandomAccessIterator result_first, RandomAccessIterator result_last); + +template + RandomAccessIterator + partial_sort_copy(InputIterator first, InputIterator last, + RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp); + +template + void + nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last); + +template + void + nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp); + +template + ForwardIterator + lower_bound(ForwardIterator first, ForwardIterator last, const T& value); + +template + ForwardIterator + lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); + +template + ForwardIterator + upper_bound(ForwardIterator first, ForwardIterator last, const T& value); + +template + ForwardIterator + upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); + +template + pair + equal_range(ForwardIterator first, ForwardIterator last, const T& value); + +template + pair + equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); + +template + bool + binary_search(ForwardIterator first, ForwardIterator last, const T& value); + +template + bool + binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); + +template + OutputIterator + merge(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, OutputIterator result); + +template + OutputIterator + merge(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); + +template + void + inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last); + +template + void + inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp); + +template + bool + includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); + +template + bool + includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); + +template + OutputIterator + set_union(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, OutputIterator result); + +template + OutputIterator + set_union(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); + +template + OutputIterator + set_intersection(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, OutputIterator result); + +template + OutputIterator + set_intersection(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); + +template + OutputIterator + set_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, OutputIterator result); + +template + OutputIterator + set_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); + +template + OutputIterator + set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, OutputIterator result); + +template + OutputIterator + set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); + +template + void + push_heap(RandomAccessIterator first, RandomAccessIterator last); + +template + void + push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); + +template + void + pop_heap(RandomAccessIterator first, RandomAccessIterator last); + +template + void + pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); + +template + void + make_heap(RandomAccessIterator first, RandomAccessIterator last); + +template + void + make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); + +template + void + sort_heap(RandomAccessIterator first, RandomAccessIterator last); + +template + void + sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); + +template + bool + is_heap(RandomAccessIterator first, RandomAccessiterator last); + +template + bool + is_heap(RandomAccessIterator first, RandomAccessiterator last, Compare comp); + +template + RandomAccessIterator + is_heap_until(RandomAccessIterator first, RandomAccessiterator last); + +template + RandomAccessIterator + is_heap_until(RandomAccessIterator first, RandomAccessiterator last, Compare comp); + +template + ForwardIterator + min_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14 + +template + ForwardIterator + min_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14 + +template + const T& + min(const T& a, const T& b); // constexpr in C++14 + +template + const T& + min(const T& a, const T& b, Compare comp); // constexpr in C++14 + +template + T + min(initializer_list t); // constexpr in C++14 + +template + T + min(initializer_list t, Compare comp); // constexpr in C++14 + +template + ForwardIterator + max_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14 + +template + ForwardIterator + max_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14 + +template + const T& + max(const T& a, const T& b); // constexpr in C++14 + +template + const T& + max(const T& a, const T& b, Compare comp); // constexpr in C++14 + +template + T + max(initializer_list t); // constexpr in C++14 + +template + T + max(initializer_list t, Compare comp); // constexpr in C++14 + +template + pair + minmax_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14 + +template + pair + minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14 + +template + pair + minmax(const T& a, const T& b); // constexpr in C++14 + +template + pair + minmax(const T& a, const T& b, Compare comp); // constexpr in C++14 + +template + pair + minmax(initializer_list t); // constexpr in C++14 + +template + pair + minmax(initializer_list t, Compare comp); // constexpr in C++14 + +template + bool + lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); + +template + bool + lexicographical_compare(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, Compare comp); + +template + bool + next_permutation(BidirectionalIterator first, BidirectionalIterator last); + +template + bool + next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp); + +template + bool + prev_permutation(BidirectionalIterator first, BidirectionalIterator last); + +template + bool + prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp); + +} // std + +*/ + +#include <__config> +#include +#include +#include +#include +#include +#include +#include + +#if defined(__IBMCPP__) +#include "support/ibm/support.h" +#endif +#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) +#include "support/win32/support.h" +#endif + +#include <__undef_min_max> + +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// I'd like to replace these with _VSTD::equal_to, but can't because: +// * That only works with C++14 and later, and +// * We haven't included here. +template +struct __equal_to +{ + _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} + _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;} + _LIBCPP_INLINE_VISIBILITY bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;} + _LIBCPP_INLINE_VISIBILITY bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;} +}; + +template +struct __equal_to<_T1, _T1> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} +}; + +template +struct __equal_to +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} +}; + +template +struct __equal_to<_T1, const _T1> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} +}; + +template +struct __less +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;} +}; + +template +struct __less<_T1, _T1> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} +}; + +template +struct __less +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} +}; + +template +struct __less<_T1, const _T1> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} +}; + +template +class __negate +{ +private: + _Predicate __p_; +public: + _LIBCPP_INLINE_VISIBILITY __negate() {} + + _LIBCPP_INLINE_VISIBILITY + explicit __negate(_Predicate __p) : __p_(__p) {} + + template + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _T1& __x) {return !__p_(__x);} + + template + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _T1& __x, const _T2& __y) {return !__p_(__x, __y);} +}; + +#ifdef _LIBCPP_DEBUG + +template +struct __debug_less +{ + _Compare __comp_; + __debug_less(_Compare& __c) : __comp_(__c) {} + template + bool operator()(const _Tp& __x, const _Up& __y) + { + bool __r = __comp_(__x, __y); + if (__r) + _LIBCPP_ASSERT(!__comp_(__y, __x), "Comparator does not induce a strict weak ordering"); + return __r; + } +}; + +#endif // _LIBCPP_DEBUG + +// Precondition: __x != 0 +inline _LIBCPP_INLINE_VISIBILITY +unsigned +__ctz(unsigned __x) +{ + return static_cast(__builtin_ctz(__x)); +} + +inline _LIBCPP_INLINE_VISIBILITY +unsigned long +__ctz(unsigned long __x) +{ + return static_cast(__builtin_ctzl(__x)); +} + +inline _LIBCPP_INLINE_VISIBILITY +unsigned long long +__ctz(unsigned long long __x) +{ + return static_cast(__builtin_ctzll(__x)); +} + +// Precondition: __x != 0 +inline _LIBCPP_INLINE_VISIBILITY +unsigned +__clz(unsigned __x) +{ + return static_cast(__builtin_clz(__x)); +} + +inline _LIBCPP_INLINE_VISIBILITY +unsigned long +__clz(unsigned long __x) +{ + return static_cast(__builtin_clzl (__x)); +} + +inline _LIBCPP_INLINE_VISIBILITY +unsigned long long +__clz(unsigned long long __x) +{ + return static_cast(__builtin_clzll(__x)); +} + +inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned __x) {return __builtin_popcount (__x);} +inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned long __x) {return __builtin_popcountl (__x);} +inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned long long __x) {return __builtin_popcountll(__x);} + +// all_of + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) +{ + for (; __first != __last; ++__first) + if (!__pred(*__first)) + return false; + return true; +} + +// any_of + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) +{ + for (; __first != __last; ++__first) + if (__pred(*__first)) + return true; + return false; +} + +// none_of + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) +{ + for (; __first != __last; ++__first) + if (__pred(*__first)) + return false; + return true; +} + +// for_each + +template +inline _LIBCPP_INLINE_VISIBILITY +_Function +for_each(_InputIterator __first, _InputIterator __last, _Function __f) +{ + for (; __first != __last; ++__first) + __f(*__first); + return _LIBCPP_EXPLICIT_MOVE(__f); // explicitly moved for (emulated) C++03 +} + +// find + +template +inline _LIBCPP_INLINE_VISIBILITY +_InputIterator +find(_InputIterator __first, _InputIterator __last, const _Tp& __value_) +{ + for (; __first != __last; ++__first) + if (*__first == __value_) + break; + return __first; +} + +// find_if + +template +inline _LIBCPP_INLINE_VISIBILITY +_InputIterator +find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) +{ + for (; __first != __last; ++__first) + if (__pred(*__first)) + break; + return __first; +} + +// find_if_not + +template +inline _LIBCPP_INLINE_VISIBILITY +_InputIterator +find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) +{ + for (; __first != __last; ++__first) + if (!__pred(*__first)) + break; + return __first; +} + +// find_end + +template +_ForwardIterator1 +__find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred, + forward_iterator_tag, forward_iterator_tag) +{ + // modeled after search algorithm + _ForwardIterator1 __r = __last1; // __last1 is the "default" answer + if (__first2 == __last2) + return __r; + while (true) + { + while (true) + { + if (__first1 == __last1) // if source exhausted return last correct answer + return __r; // (or __last1 if never found) + if (__pred(*__first1, *__first2)) + break; + ++__first1; + } + // *__first1 matches *__first2, now match elements after here + _ForwardIterator1 __m1 = __first1; + _ForwardIterator2 __m2 = __first2; + while (true) + { + if (++__m2 == __last2) + { // Pattern exhaused, record answer and search for another one + __r = __first1; + ++__first1; + break; + } + if (++__m1 == __last1) // Source exhausted, return last answer + return __r; + if (!__pred(*__m1, *__m2)) // mismatch, restart with a new __first + { + ++__first1; + break; + } // else there is a match, check next elements + } + } +} + +template +_BidirectionalIterator1 +__find_end(_BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, _BidirectionalIterator2 __last2, _BinaryPredicate __pred, + bidirectional_iterator_tag, bidirectional_iterator_tag) +{ + // modeled after search algorithm (in reverse) + if (__first2 == __last2) + return __last1; // Everything matches an empty sequence + _BidirectionalIterator1 __l1 = __last1; + _BidirectionalIterator2 __l2 = __last2; + --__l2; + while (true) + { + // Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks + while (true) + { + if (__first1 == __l1) // return __last1 if no element matches *__first2 + return __last1; + if (__pred(*--__l1, *__l2)) + break; + } + // *__l1 matches *__l2, now match elements before here + _BidirectionalIterator1 __m1 = __l1; + _BidirectionalIterator2 __m2 = __l2; + while (true) + { + if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern) + return __m1; + if (__m1 == __first1) // Otherwise if source exhaused, pattern not found + return __last1; + if (!__pred(*--__m1, *--__m2)) // if there is a mismatch, restart with a new __l1 + { + break; + } // else there is a match, check next elements + } + } +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 +__find_end(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, + random_access_iterator_tag, random_access_iterator_tag) +{ + // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern + typename iterator_traits<_RandomAccessIterator2>::difference_type __len2 = __last2 - __first2; + if (__len2 == 0) + return __last1; + typename iterator_traits<_RandomAccessIterator1>::difference_type __len1 = __last1 - __first1; + if (__len1 < __len2) + return __last1; + const _RandomAccessIterator1 __s = __first1 + (__len2 - 1); // End of pattern match can't go before here + _RandomAccessIterator1 __l1 = __last1; + _RandomAccessIterator2 __l2 = __last2; + --__l2; + while (true) + { + while (true) + { + if (__s == __l1) + return __last1; + if (__pred(*--__l1, *__l2)) + break; + } + _RandomAccessIterator1 __m1 = __l1; + _RandomAccessIterator2 __m2 = __l2; + while (true) + { + if (__m2 == __first2) + return __m1; + // no need to check range on __m1 because __s guarantees we have enough source + if (!__pred(*--__m1, *--__m2)) + { + break; + } + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator1 +find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) +{ + return _VSTD::__find_end::type> + (__first1, __last1, __first2, __last2, __pred, + typename iterator_traits<_ForwardIterator1>::iterator_category(), + typename iterator_traits<_ForwardIterator2>::iterator_category()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator1 +find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) +{ + typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; + typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; + return _VSTD::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); +} + +// find_first_of + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1 +__find_first_of_ce(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) +{ + for (; __first1 != __last1; ++__first1) + for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) + if (__pred(*__first1, *__j)) + return __first1; + return __last1; +} + + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator1 +find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) +{ + return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator1 +find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) +{ + typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; + typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; + return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); +} + +// adjacent_find + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) +{ + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + { + if (__pred(*__first, *__i)) + return __first; + __first = __i; + } + } + return __last; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +adjacent_find(_ForwardIterator __first, _ForwardIterator __last) +{ + typedef typename iterator_traits<_ForwardIterator>::value_type __v; + return _VSTD::adjacent_find(__first, __last, __equal_to<__v>()); +} + +// count + +template +inline _LIBCPP_INLINE_VISIBILITY +typename iterator_traits<_InputIterator>::difference_type +count(_InputIterator __first, _InputIterator __last, const _Tp& __value_) +{ + typename iterator_traits<_InputIterator>::difference_type __r(0); + for (; __first != __last; ++__first) + if (*__first == __value_) + ++__r; + return __r; +} + +// count_if + +template +inline _LIBCPP_INLINE_VISIBILITY +typename iterator_traits<_InputIterator>::difference_type +count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) +{ + typename iterator_traits<_InputIterator>::difference_type __r(0); + for (; __first != __last; ++__first) + if (__pred(*__first)) + ++__r; + return __r; +} + +// mismatch + +template +inline _LIBCPP_INLINE_VISIBILITY +pair<_InputIterator1, _InputIterator2> +mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _BinaryPredicate __pred) +{ + for (; __first1 != __last1; ++__first1, (void) ++__first2) + if (!__pred(*__first1, *__first2)) + break; + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +pair<_InputIterator1, _InputIterator2> +mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) +{ + typedef typename iterator_traits<_InputIterator1>::value_type __v1; + typedef typename iterator_traits<_InputIterator2>::value_type __v2; + return _VSTD::mismatch(__first1, __last1, __first2, __equal_to<__v1, __v2>()); +} + +#if _LIBCPP_STD_VER > 11 +template +inline _LIBCPP_INLINE_VISIBILITY +pair<_InputIterator1, _InputIterator2> +mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _BinaryPredicate __pred) +{ + for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2) + if (!__pred(*__first1, *__first2)) + break; + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +pair<_InputIterator1, _InputIterator2> +mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) +{ + typedef typename iterator_traits<_InputIterator1>::value_type __v1; + typedef typename iterator_traits<_InputIterator2>::value_type __v2; + return _VSTD::mismatch(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); +} +#endif + +// equal + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) +{ + for (; __first1 != __last1; ++__first1, (void) ++__first2) + if (!__pred(*__first1, *__first2)) + return false; + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) +{ + typedef typename iterator_traits<_InputIterator1>::value_type __v1; + typedef typename iterator_traits<_InputIterator2>::value_type __v2; + return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>()); +} + +#if _LIBCPP_STD_VER > 11 +template +inline _LIBCPP_INLINE_VISIBILITY +bool +__equal(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred, + input_iterator_tag, input_iterator_tag ) +{ + for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2) + if (!__pred(*__first1, *__first2)) + return false; + return __first1 == __last1 && __first2 == __last2; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, + random_access_iterator_tag, random_access_iterator_tag ) +{ + if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) + return false; + return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2, + typename add_lvalue_reference<_BinaryPredicate>::type> + (__first1, __last1, __first2, __pred ); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +equal(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred ) +{ + return _VSTD::__equal::type> + (__first1, __last1, __first2, __last2, __pred, + typename iterator_traits<_InputIterator1>::iterator_category(), + typename iterator_traits<_InputIterator2>::iterator_category()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +equal(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) +{ + typedef typename iterator_traits<_InputIterator1>::value_type __v1; + typedef typename iterator_traits<_InputIterator2>::value_type __v2; + return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(), + typename iterator_traits<_InputIterator1>::iterator_category(), + typename iterator_traits<_InputIterator2>::iterator_category()); +} +#endif + +// is_permutation + +template +bool +is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _BinaryPredicate __pred) +{ + // shorten sequences as much as possible by lopping of any equal parts + for (; __first1 != __last1; ++__first1, (void) ++__first2) + if (!__pred(*__first1, *__first2)) + goto __not_done; + return true; +__not_done: + // __first1 != __last1 && *__first1 != *__first2 + typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1; + _D1 __l1 = _VSTD::distance(__first1, __last1); + if (__l1 == _D1(1)) + return false; + _ForwardIterator2 __last2 = _VSTD::next(__first2, __l1); + // For each element in [f1, l1) see if there are the same number of + // equal elements in [f2, l2) + for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) + { + // Have we already counted the number of *__i in [f1, l1)? + for (_ForwardIterator1 __j = __first1; __j != __i; ++__j) + if (__pred(*__j, *__i)) + goto __next_iter; + { + // Count number of *__i in [f2, l2) + _D1 __c2 = 0; + for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) + if (__pred(*__i, *__j)) + ++__c2; + if (__c2 == 0) + return false; + // Count number of *__i in [__i, l1) (we can start with 1) + _D1 __c1 = 1; + for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j) + if (__pred(*__i, *__j)) + ++__c1; + if (__c1 != __c2) + return false; + } +__next_iter:; + } + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2) +{ + typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; + typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; + return _VSTD::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>()); +} + +#if _LIBCPP_STD_VER > 11 +template +bool +__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred, + forward_iterator_tag, forward_iterator_tag ) +{ + // shorten sequences as much as possible by lopping of any equal parts + for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2) + if (!__pred(*__first1, *__first2)) + goto __not_done; + return __first1 == __last1 && __first2 == __last2; +__not_done: + // __first1 != __last1 && __first2 != __last2 && *__first1 != *__first2 + typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1; + _D1 __l1 = _VSTD::distance(__first1, __last1); + + typedef typename iterator_traits<_ForwardIterator2>::difference_type _D2; + _D2 __l2 = _VSTD::distance(__first2, __last2); + if (__l1 != __l2) + return false; + + // For each element in [f1, l1) see if there are the same number of + // equal elements in [f2, l2) + for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) + { + // Have we already counted the number of *__i in [f1, l1)? + for (_ForwardIterator1 __j = __first1; __j != __i; ++__j) + if (__pred(*__j, *__i)) + goto __next_iter; + { + // Count number of *__i in [f2, l2) + _D1 __c2 = 0; + for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) + if (__pred(*__i, *__j)) + ++__c2; + if (__c2 == 0) + return false; + // Count number of *__i in [__i, l1) (we can start with 1) + _D1 __c1 = 1; + for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j) + if (__pred(*__i, *__j)) + ++__c1; + if (__c1 != __c2) + return false; + } +__next_iter:; + } + return true; +} + +template +bool +__is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1, + _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2, + _BinaryPredicate __pred, + random_access_iterator_tag, random_access_iterator_tag ) +{ + if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) + return false; + return _VSTD::is_permutation<_RandomAccessIterator1, _RandomAccessIterator2, + typename add_lvalue_reference<_BinaryPredicate>::type> + (__first1, __last1, __first2, __pred ); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred ) +{ + return _VSTD::__is_permutation::type> + (__first1, __last1, __first2, __last2, __pred, + typename iterator_traits<_ForwardIterator1>::iterator_category(), + typename iterator_traits<_ForwardIterator2>::iterator_category()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) +{ + typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; + typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; + return _VSTD::__is_permutation(__first1, __last1, __first2, __last2, + __equal_to<__v1, __v2>(), + typename iterator_traits<_ForwardIterator1>::iterator_category(), + typename iterator_traits<_ForwardIterator2>::iterator_category()); +} +#endif + +// search + +template +_ForwardIterator1 +__search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred, + forward_iterator_tag, forward_iterator_tag) +{ + if (__first2 == __last2) + return __first1; // Everything matches an empty sequence + while (true) + { + // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks + while (true) + { + if (__first1 == __last1) // return __last1 if no element matches *__first2 + return __last1; + if (__pred(*__first1, *__first2)) + break; + ++__first1; + } + // *__first1 matches *__first2, now match elements after here + _ForwardIterator1 __m1 = __first1; + _ForwardIterator2 __m2 = __first2; + while (true) + { + if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern) + return __first1; + if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found + return __last1; + if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1 + { + ++__first1; + break; + } // else there is a match, check next elements + } + } +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 +__search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, + random_access_iterator_tag, random_access_iterator_tag) +{ + typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _D1; + typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _D2; + // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern + _D2 __len2 = __last2 - __first2; + if (__len2 == 0) + return __first1; + _D1 __len1 = __last1 - __first1; + if (__len1 < __len2) + return __last1; + const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here + while (true) + { +#if !_LIBCPP_UNROLL_LOOPS + while (true) + { + if (__first1 == __s) + return __last1; + if (__pred(*__first1, *__first2)) + break; + ++__first1; + } +#else // !_LIBCPP_UNROLL_LOOPS + for (_D1 __loop_unroll = (__s - __first1) / 4; __loop_unroll > 0; --__loop_unroll) + { + if (__pred(*__first1, *__first2)) + goto __phase2; + if (__pred(*++__first1, *__first2)) + goto __phase2; + if (__pred(*++__first1, *__first2)) + goto __phase2; + if (__pred(*++__first1, *__first2)) + goto __phase2; + ++__first1; + } + switch (__s - __first1) + { + case 3: + if (__pred(*__first1, *__first2)) + break; + ++__first1; + case 2: + if (__pred(*__first1, *__first2)) + break; + ++__first1; + case 1: + if (__pred(*__first1, *__first2)) + break; + case 0: + return __last1; + } + __phase2: +#endif // !_LIBCPP_UNROLL_LOOPS + _RandomAccessIterator1 __m1 = __first1; + _RandomAccessIterator2 __m2 = __first2; +#if !_LIBCPP_UNROLL_LOOPS + while (true) + { + if (++__m2 == __last2) + return __first1; + ++__m1; // no need to check range on __m1 because __s guarantees we have enough source + if (!__pred(*__m1, *__m2)) + { + ++__first1; + break; + } + } +#else // !_LIBCPP_UNROLL_LOOPS + ++__m2; + ++__m1; + for (_D2 __loop_unroll = (__last2 - __m2) / 4; __loop_unroll > 0; --__loop_unroll) + { + if (!__pred(*__m1, *__m2)) + goto __continue; + if (!__pred(*++__m1, *++__m2)) + goto __continue; + if (!__pred(*++__m1, *++__m2)) + goto __continue; + if (!__pred(*++__m1, *++__m2)) + goto __continue; + ++__m1; + ++__m2; + } + switch (__last2 - __m2) + { + case 3: + if (!__pred(*__m1, *__m2)) + break; + ++__m1; + ++__m2; + case 2: + if (!__pred(*__m1, *__m2)) + break; + ++__m1; + ++__m2; + case 1: + if (!__pred(*__m1, *__m2)) + break; + case 0: + return __first1; + } + __continue: + ++__first1; +#endif // !_LIBCPP_UNROLL_LOOPS + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator1 +search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) +{ + return _VSTD::__search::type> + (__first1, __last1, __first2, __last2, __pred, + typename std::iterator_traits<_ForwardIterator1>::iterator_category(), + typename std::iterator_traits<_ForwardIterator2>::iterator_category()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator1 +search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) +{ + typedef typename std::iterator_traits<_ForwardIterator1>::value_type __v1; + typedef typename std::iterator_traits<_ForwardIterator2>::value_type __v2; + return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); +} + +// search_n + +template +_ForwardIterator +__search_n(_ForwardIterator __first, _ForwardIterator __last, + _Size __count, const _Tp& __value_, _BinaryPredicate __pred, forward_iterator_tag) +{ + if (__count <= 0) + return __first; + while (true) + { + // Find first element in sequence that matchs __value_, with a mininum of loop checks + while (true) + { + if (__first == __last) // return __last if no element matches __value_ + return __last; + if (__pred(*__first, __value_)) + break; + ++__first; + } + // *__first matches __value_, now match elements after here + _ForwardIterator __m = __first; + _Size __c(0); + while (true) + { + if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) + return __first; + if (++__m == __last) // Otherwise if source exhaused, pattern not found + return __last; + if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first + { + __first = __m; + ++__first; + break; + } // else there is a match, check next elements + } + } +} + +template +_RandomAccessIterator +__search_n(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Size __count, const _Tp& __value_, _BinaryPredicate __pred, random_access_iterator_tag) +{ + if (__count <= 0) + return __first; + _Size __len = static_cast<_Size>(__last - __first); + if (__len < __count) + return __last; + const _RandomAccessIterator __s = __last - (__count - 1); // Start of pattern match can't go beyond here + while (true) + { + // Find first element in sequence that matchs __value_, with a mininum of loop checks + while (true) + { + if (__first >= __s) // return __last if no element matches __value_ + return __last; + if (__pred(*__first, __value_)) + break; + ++__first; + } + // *__first matches __value_, now match elements after here + _RandomAccessIterator __m = __first; + _Size __c(0); + while (true) + { + if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) + return __first; + ++__m; // no need to check range on __m because __s guarantees we have enough source + if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first + { + __first = __m; + ++__first; + break; + } // else there is a match, check next elements + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +search_n(_ForwardIterator __first, _ForwardIterator __last, + _Size __count, const _Tp& __value_, _BinaryPredicate __pred) +{ + return _VSTD::__search_n::type> + (__first, __last, __convert_to_integral(__count), __value_, __pred, + typename iterator_traits<_ForwardIterator>::iterator_category()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_) +{ + typedef typename iterator_traits<_ForwardIterator>::value_type __v; + return _VSTD::search_n(__first, __last, __convert_to_integral(__count), + __value_, __equal_to<__v, _Tp>()); +} + +// copy + +template +struct __libcpp_is_trivial_iterator +{ + static const bool value = is_pointer<_Iter>::value; +}; + +template +struct __libcpp_is_trivial_iterator > +{ + static const bool value = is_pointer<_Iter>::value; +}; + +template +struct __libcpp_is_trivial_iterator<__wrap_iter<_Iter> > +{ + static const bool value = is_pointer<_Iter>::value; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_Iter +__unwrap_iter(_Iter __i) +{ + return __i; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_trivially_copy_assignable<_Tp>::value, + _Tp* +>::type +__unwrap_iter(move_iterator<_Tp*> __i) +{ + return __i.base(); +} + +#if _LIBCPP_DEBUG_LEVEL < 2 + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_trivially_copy_assignable<_Tp>::value, + _Tp* +>::type +__unwrap_iter(__wrap_iter<_Tp*> __i) +{ + return __i.base(); +} + +#endif // _LIBCPP_DEBUG_LEVEL < 2 + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + for (; __first != __last; ++__first, (void) ++__result) + *__result = *__first; + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_same::type, _Up>::value && + is_trivially_copy_assignable<_Up>::value, + _Up* +>::type +__copy(_Tp* __first, _Tp* __last, _Up* __result) +{ + const size_t __n = static_cast(__last - __first); + if (__n > 0) + _VSTD::memmove(__result, __first, __n * sizeof(_Up)); + return __result + __n; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + return _VSTD::__copy(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); +} + +// copy_backward + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) +{ + while (__first != __last) + *--__result = *--__last; + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_same::type, _Up>::value && + is_trivially_copy_assignable<_Up>::value, + _Up* +>::type +__copy_backward(_Tp* __first, _Tp* __last, _Up* __result) +{ + const size_t __n = static_cast(__last - __first); + if (__n > 0) + { + __result -= __n; + _VSTD::memmove(__result, __first, __n * sizeof(_Up)); + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_BidirectionalIterator2 +copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, + _BidirectionalIterator2 __result) +{ + return _VSTD::__copy_backward(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); +} + +// copy_if + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Predicate __pred) +{ + for (; __first != __last; ++__first) + { + if (__pred(*__first)) + { + *__result = *__first; + ++__result; + } + } + return __result; +} + +// copy_n + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_input_iterator<_InputIterator>::value && + !__is_random_access_iterator<_InputIterator>::value, + _OutputIterator +>::type +copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) +{ + typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + if (__n > 0) + { + *__result = *__first; + ++__result; + for (--__n; __n > 0; --__n) + { + ++__first; + *__result = *__first; + ++__result; + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_random_access_iterator<_InputIterator>::value, + _OutputIterator +>::type +copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) +{ + typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + return _VSTD::copy(__first, __first + __n, __result); +} + +// move + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + for (; __first != __last; ++__first, (void) ++__result) + *__result = _VSTD::move(*__first); + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_same::type, _Up>::value && + is_trivially_copy_assignable<_Up>::value, + _Up* +>::type +__move(_Tp* __first, _Tp* __last, _Up* __result) +{ + const size_t __n = static_cast(__last - __first); + if (__n > 0) + _VSTD::memmove(__result, __first, __n * sizeof(_Up)); + return __result + __n; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + return _VSTD::__move(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); +} + +// move_backward + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + while (__first != __last) + *--__result = _VSTD::move(*--__last); + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_same::type, _Up>::value && + is_trivially_copy_assignable<_Up>::value, + _Up* +>::type +__move_backward(_Tp* __first, _Tp* __last, _Up* __result) +{ + const size_t __n = static_cast(__last - __first); + if (__n > 0) + { + __result -= __n; + _VSTD::memmove(__result, __first, __n * sizeof(_Up)); + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_BidirectionalIterator2 +move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, + _BidirectionalIterator2 __result) +{ + return _VSTD::__move_backward(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); +} + +// iter_swap + +// moved to for better swap / noexcept support + +// transform + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) +{ + for (; __first != __last; ++__first, (void) ++__result) + *__result = __op(*__first); + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, + _OutputIterator __result, _BinaryOperation __binary_op) +{ + for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result) + *__result = __binary_op(*__first1, *__first2); + return __result; +} + +// replace + +template +inline _LIBCPP_INLINE_VISIBILITY +void +replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) +{ + for (; __first != __last; ++__first) + if (*__first == __old_value) + *__first = __new_value; +} + +// replace_if + +template +inline _LIBCPP_INLINE_VISIBILITY +void +replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) +{ + for (; __first != __last; ++__first) + if (__pred(*__first)) + *__first = __new_value; +} + +// replace_copy + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, + const _Tp& __old_value, const _Tp& __new_value) +{ + for (; __first != __last; ++__first, (void) ++__result) + if (*__first == __old_value) + *__result = __new_value; + else + *__result = *__first; + return __result; +} + +// replace_copy_if + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, + _Predicate __pred, const _Tp& __new_value) +{ + for (; __first != __last; ++__first, (void) ++__result) + if (__pred(*__first)) + *__result = __new_value; + else + *__result = *__first; + return __result; +} + +// fill_n + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) +{ + for (; __n > 0; ++__first, (void) --__n) + *__first = __value_; + return __first; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && sizeof(_Tp) == 1 && + !is_same<_Tp, bool>::value && + is_integral<_Up>::value && sizeof(_Up) == 1, + _Tp* +>::type +__fill_n(_Tp* __first, _Size __n,_Up __value_) +{ + if (__n > 0) + _VSTD::memset(__first, (unsigned char)__value_, (size_t)(__n)); + return __first + __n; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) +{ + return _VSTD::__fill_n(__first, __convert_to_integral(__n), __value_); +} + +// fill + +template +inline _LIBCPP_INLINE_VISIBILITY +void +__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, forward_iterator_tag) +{ + for (; __first != __last; ++__first) + *__first = __value_; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value_, random_access_iterator_tag) +{ + _VSTD::fill_n(__first, __last - __first, __value_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) +{ + _VSTD::__fill(__first, __last, __value_, typename iterator_traits<_ForwardIterator>::iterator_category()); +} + +// generate + +template +inline _LIBCPP_INLINE_VISIBILITY +void +generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) +{ + for (; __first != __last; ++__first) + *__first = __gen(); +} + +// generate_n + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) +{ + typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + for (; __n > 0; ++__first, (void) --__n) + *__first = __gen(); + return __first; +} + +// remove + +template +_ForwardIterator +remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) +{ + __first = _VSTD::find(__first, __last, __value_); + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + { + if (!(*__i == __value_)) + { + *__first = _VSTD::move(*__i); + ++__first; + } + } + } + return __first; +} + +// remove_if + +template +_ForwardIterator +remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) +{ + __first = _VSTD::find_if<_ForwardIterator, typename add_lvalue_reference<_Predicate>::type> + (__first, __last, __pred); + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + { + if (!__pred(*__i)) + { + *__first = _VSTD::move(*__i); + ++__first; + } + } + } + return __first; +} + +// remove_copy + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value_) +{ + for (; __first != __last; ++__first) + { + if (!(*__first == __value_)) + { + *__result = *__first; + ++__result; + } + } + return __result; +} + +// remove_copy_if + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) +{ + for (; __first != __last; ++__first) + { + if (!__pred(*__first)) + { + *__result = *__first; + ++__result; + } + } + return __result; +} + +// unique + +template +_ForwardIterator +unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) +{ + __first = _VSTD::adjacent_find<_ForwardIterator, typename add_lvalue_reference<_BinaryPredicate>::type> + (__first, __last, __pred); + if (__first != __last) + { + // ... a a ? ... + // f i + _ForwardIterator __i = __first; + for (++__i; ++__i != __last;) + if (!__pred(*__first, *__i)) + *++__first = _VSTD::move(*__i); + ++__first; + } + return __first; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +unique(_ForwardIterator __first, _ForwardIterator __last) +{ + typedef typename iterator_traits<_ForwardIterator>::value_type __v; + return _VSTD::unique(__first, __last, __equal_to<__v>()); +} + +// unique_copy + +template +_OutputIterator +__unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred, + input_iterator_tag, output_iterator_tag) +{ + if (__first != __last) + { + typename iterator_traits<_InputIterator>::value_type __t(*__first); + *__result = __t; + ++__result; + while (++__first != __last) + { + if (!__pred(__t, *__first)) + { + __t = *__first; + *__result = __t; + ++__result; + } + } + } + return __result; +} + +template +_OutputIterator +__unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred, + forward_iterator_tag, output_iterator_tag) +{ + if (__first != __last) + { + _ForwardIterator __i = __first; + *__result = *__i; + ++__result; + while (++__first != __last) + { + if (!__pred(*__i, *__first)) + { + *__result = *__first; + ++__result; + __i = __first; + } + } + } + return __result; +} + +template +_ForwardIterator +__unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred, + input_iterator_tag, forward_iterator_tag) +{ + if (__first != __last) + { + *__result = *__first; + while (++__first != __last) + if (!__pred(*__result, *__first)) + *++__result = *__first; + ++__result; + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) +{ + return _VSTD::__unique_copy::type> + (__first, __last, __result, __pred, + typename iterator_traits<_InputIterator>::iterator_category(), + typename iterator_traits<_OutputIterator>::iterator_category()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + typedef typename iterator_traits<_InputIterator>::value_type __v; + return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>()); +} + +// reverse + +template +inline _LIBCPP_INLINE_VISIBILITY +void +__reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) +{ + while (__first != __last) + { + if (__first == --__last) + break; + _VSTD::iter_swap(__first, __last); + ++__first; + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +__reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) +{ + if (__first != __last) + for (; __first < --__last; ++__first) + _VSTD::iter_swap(__first, __last); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) +{ + _VSTD::__reverse(__first, __last, typename iterator_traits<_BidirectionalIterator>::iterator_category()); +} + +// reverse_copy + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) +{ + for (; __first != __last; ++__result) + *__result = *--__last; + return __result; +} + +// rotate + +template +_ForwardIterator +__rotate_left(_ForwardIterator __first, _ForwardIterator __last) +{ + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + value_type __tmp = _VSTD::move(*__first); + _ForwardIterator __lm1 = _VSTD::move(_VSTD::next(__first), __last, __first); + *__lm1 = _VSTD::move(__tmp); + return __lm1; +} + +template +_BidirectionalIterator +__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) +{ + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + _BidirectionalIterator __lm1 = _VSTD::prev(__last); + value_type __tmp = _VSTD::move(*__lm1); + _BidirectionalIterator __fp1 = _VSTD::move_backward(__first, __lm1, __last); + *__first = _VSTD::move(__tmp); + return __fp1; +} + +template +_ForwardIterator +__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) +{ + _ForwardIterator __i = __middle; + while (true) + { + swap(*__first, *__i); + ++__first; + if (++__i == __last) + break; + if (__first == __middle) + __middle = __i; + } + _ForwardIterator __r = __first; + if (__first != __middle) + { + __i = __middle; + while (true) + { + swap(*__first, *__i); + ++__first; + if (++__i == __last) + { + if (__first == __middle) + break; + __i = __middle; + } + else if (__first == __middle) + __middle = __i; + } + } + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Integral +__gcd(_Integral __x, _Integral __y) +{ + do + { + _Integral __t = __x % __y; + __x = __y; + __y = __t; + } while (__y); + return __x; +} + +template +_RandomAccessIterator +__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + + const difference_type __m1 = __middle - __first; + const difference_type __m2 = __last - __middle; + if (__m1 == __m2) + { + _VSTD::swap_ranges(__first, __middle, __middle); + return __middle; + } + const difference_type __g = _VSTD::__gcd(__m1, __m2); + for (_RandomAccessIterator __p = __first + __g; __p != __first;) + { + value_type __t(_VSTD::move(*--__p)); + _RandomAccessIterator __p1 = __p; + _RandomAccessIterator __p2 = __p1 + __m1; + do + { + *__p1 = _VSTD::move(*__p2); + __p1 = __p2; + const difference_type __d = __last - __p2; + if (__m1 < __d) + __p2 += __m1; + else + __p2 = __first + (__m1 - __d); + } while (__p2 != __p); + *__p1 = _VSTD::move(__t); + } + return __first + __m2; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +__rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, + _VSTD::forward_iterator_tag) +{ + typedef typename _VSTD::iterator_traits<_ForwardIterator>::value_type value_type; + if (_VSTD::is_trivially_move_assignable::value) + { + if (_VSTD::next(__first) == __middle) + return _VSTD::__rotate_left(__first, __last); + } + return _VSTD::__rotate_forward(__first, __middle, __last); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_BidirectionalIterator +__rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, + _VSTD::bidirectional_iterator_tag) +{ + typedef typename _VSTD::iterator_traits<_BidirectionalIterator>::value_type value_type; + if (_VSTD::is_trivially_move_assignable::value) + { + if (_VSTD::next(__first) == __middle) + return _VSTD::__rotate_left(__first, __last); + if (_VSTD::next(__middle) == __last) + return _VSTD::__rotate_right(__first, __last); + } + return _VSTD::__rotate_forward(__first, __middle, __last); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_RandomAccessIterator +__rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, + _VSTD::random_access_iterator_tag) +{ + typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::value_type value_type; + if (_VSTD::is_trivially_move_assignable::value) + { + if (_VSTD::next(__first) == __middle) + return _VSTD::__rotate_left(__first, __last); + if (_VSTD::next(__middle) == __last) + return _VSTD::__rotate_right(__first, __last); + return _VSTD::__rotate_gcd(__first, __middle, __last); + } + return _VSTD::__rotate_forward(__first, __middle, __last); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) +{ + if (__first == __middle) + return __last; + if (__middle == __last) + return __first; + return _VSTD::__rotate(__first, __middle, __last, + typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category()); +} + +// rotate_copy + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) +{ + return _VSTD::copy(__first, __middle, _VSTD::copy(__middle, __last, __result)); +} + +// min_element + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_ForwardIterator +min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + if (__comp(*__i, *__first)) + __first = __i; + } + return __first; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_ForwardIterator +min_element(_ForwardIterator __first, _ForwardIterator __last) +{ + return _VSTD::min_element(__first, __last, + __less::value_type>()); +} + +// min + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +const _Tp& +min(const _Tp& __a, const _Tp& __b, _Compare __comp) +{ + return __comp(__b, __a) ? __b : __a; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +const _Tp& +min(const _Tp& __a, const _Tp& __b) +{ + return _VSTD::min(__a, __b, __less<_Tp>()); +} + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp +min(initializer_list<_Tp> __t, _Compare __comp) +{ + return *_VSTD::min_element(__t.begin(), __t.end(), __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp +min(initializer_list<_Tp> __t) +{ + return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>()); +} + +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +// max_element + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_ForwardIterator +max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + if (__comp(*__first, *__i)) + __first = __i; + } + return __first; +} + + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_ForwardIterator +max_element(_ForwardIterator __first, _ForwardIterator __last) +{ + return _VSTD::max_element(__first, __last, + __less::value_type>()); +} + +// max + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +const _Tp& +max(const _Tp& __a, const _Tp& __b, _Compare __comp) +{ + return __comp(__a, __b) ? __b : __a; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +const _Tp& +max(const _Tp& __a, const _Tp& __b) +{ + return _VSTD::max(__a, __b, __less<_Tp>()); +} + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp +max(initializer_list<_Tp> __t, _Compare __comp) +{ + return *_VSTD::max_element(__t.begin(), __t.end(), __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp +max(initializer_list<_Tp> __t) +{ + return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>()); +} + +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +// minmax_element + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 +std::pair<_ForwardIterator, _ForwardIterator> +minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + std::pair<_ForwardIterator, _ForwardIterator> __result(__first, __first); + if (__first != __last) + { + if (++__first != __last) + { + if (__comp(*__first, *__result.first)) + __result.first = __first; + else + __result.second = __first; + while (++__first != __last) + { + _ForwardIterator __i = __first; + if (++__first == __last) + { + if (__comp(*__i, *__result.first)) + __result.first = __i; + else if (!__comp(*__i, *__result.second)) + __result.second = __i; + break; + } + else + { + if (__comp(*__first, *__i)) + { + if (__comp(*__first, *__result.first)) + __result.first = __first; + if (!__comp(*__i, *__result.second)) + __result.second = __i; + } + else + { + if (__comp(*__i, *__result.first)) + __result.first = __i; + if (!__comp(*__first, *__result.second)) + __result.second = __first; + } + } + } + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +std::pair<_ForwardIterator, _ForwardIterator> +minmax_element(_ForwardIterator __first, _ForwardIterator __last) +{ + return _VSTD::minmax_element(__first, __last, + __less::value_type>()); +} + +// minmax + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair +minmax(const _Tp& __a, const _Tp& __b, _Compare __comp) +{ + return __comp(__b, __a) ? pair(__b, __a) : + pair(__a, __b); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair +minmax(const _Tp& __a, const _Tp& __b) +{ + return _VSTD::minmax(__a, __b, __less<_Tp>()); +} + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_Tp, _Tp> +minmax(initializer_list<_Tp> __t, _Compare __comp) +{ + typedef typename initializer_list<_Tp>::const_iterator _Iter; + _Iter __first = __t.begin(); + _Iter __last = __t.end(); + std::pair<_Tp, _Tp> __result(*__first, *__first); + + ++__first; + if (__t.size() % 2 == 0) + { + if (__comp(*__first, __result.first)) + __result.first = *__first; + else + __result.second = *__first; + ++__first; + } + + while (__first != __last) + { + _Tp __prev = *__first++; + if (__comp(*__first, __prev)) { + if ( __comp(*__first, __result.first)) __result.first = *__first; + if (!__comp(__prev, __result.second)) __result.second = __prev; + } + else { + if ( __comp(__prev, __result.first)) __result.first = __prev; + if (!__comp(*__first, __result.second)) __result.second = *__first; + } + + __first++; + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_Tp, _Tp> +minmax(initializer_list<_Tp> __t) +{ + return _VSTD::minmax(__t, __less<_Tp>()); +} + +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +// random_shuffle + +// __independent_bits_engine + +template +struct __log2_imp +{ + static const size_t value = _Xp & ((unsigned long long)(1) << _Rp) ? _Rp + : __log2_imp<_Xp, _Rp - 1>::value; +}; + +template +struct __log2_imp<_Xp, 0> +{ + static const size_t value = 0; +}; + +template +struct __log2_imp<0, _Rp> +{ + static const size_t value = _Rp + 1; +}; + +template +struct __log2 +{ + static const size_t value = __log2_imp<_Xp, + sizeof(_UI) * __CHAR_BIT__ - 1>::value; +}; + +template +class __independent_bits_engine +{ +public: + // types + typedef _UIntType result_type; + +private: + typedef typename _Engine::result_type _Engine_result_type; + typedef typename conditional + < + sizeof(_Engine_result_type) <= sizeof(result_type), + result_type, + _Engine_result_type + >::type _Working_result_type; + + _Engine& __e_; + size_t __w_; + size_t __w0_; + size_t __n_; + size_t __n0_; + _Working_result_type __y0_; + _Working_result_type __y1_; + _Engine_result_type __mask0_; + _Engine_result_type __mask1_; + +#ifdef _LIBCPP_HAS_NO_CONSTEXPR + static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min + + _Working_result_type(1); +#else + static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min() + + _Working_result_type(1); +#endif + static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value; + static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits; + static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits; + +public: + // constructors and seeding functions + __independent_bits_engine(_Engine& __e, size_t __w); + + // generating functions + result_type operator()() {return __eval(integral_constant());} + +private: + result_type __eval(false_type); + result_type __eval(true_type); +}; + +template +__independent_bits_engine<_Engine, _UIntType> + ::__independent_bits_engine(_Engine& __e, size_t __w) + : __e_(__e), + __w_(__w) +{ + __n_ = __w_ / __m + (__w_ % __m != 0); + __w0_ = __w_ / __n_; + if (_Rp == 0) + __y0_ = _Rp; + else if (__w0_ < _WDt) + __y0_ = (_Rp >> __w0_) << __w0_; + else + __y0_ = 0; + if (_Rp - __y0_ > __y0_ / __n_) + { + ++__n_; + __w0_ = __w_ / __n_; + if (__w0_ < _WDt) + __y0_ = (_Rp >> __w0_) << __w0_; + else + __y0_ = 0; + } + __n0_ = __n_ - __w_ % __n_; + if (__w0_ < _WDt - 1) + __y1_ = (_Rp >> (__w0_ + 1)) << (__w0_ + 1); + else + __y1_ = 0; + __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_) : + _Engine_result_type(0); + __mask1_ = __w0_ < _EDt - 1 ? + _Engine_result_type(~0) >> (_EDt - (__w0_ + 1)) : + _Engine_result_type(~0); +} + +template +inline +_UIntType +__independent_bits_engine<_Engine, _UIntType>::__eval(false_type) +{ + return static_cast(__e_() & __mask0_); +} + +template +_UIntType +__independent_bits_engine<_Engine, _UIntType>::__eval(true_type) +{ + result_type _Sp = 0; + for (size_t __k = 0; __k < __n0_; ++__k) + { + _Engine_result_type __u; + do + { + __u = __e_() - _Engine::min(); + } while (__u >= __y0_); + if (__w0_ < _WDt) + _Sp <<= __w0_; + else + _Sp = 0; + _Sp += __u & __mask0_; + } + for (size_t __k = __n0_; __k < __n_; ++__k) + { + _Engine_result_type __u; + do + { + __u = __e_() - _Engine::min(); + } while (__u >= __y1_); + if (__w0_ < _WDt - 1) + _Sp <<= __w0_ + 1; + else + _Sp = 0; + _Sp += __u & __mask1_; + } + return _Sp; +} + +// uniform_int_distribution + +template +class uniform_int_distribution +{ +public: + // types + typedef _IntType result_type; + + class param_type + { + result_type __a_; + result_type __b_; + public: + typedef uniform_int_distribution distribution_type; + + explicit param_type(result_type __a = 0, + result_type __b = numeric_limits::max()) + : __a_(__a), __b_(__b) {} + + result_type a() const {return __a_;} + result_type b() const {return __b_;} + + friend bool operator==(const param_type& __x, const param_type& __y) + {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;} + friend bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + +public: + // constructors and reset functions + explicit uniform_int_distribution(result_type __a = 0, + result_type __b = numeric_limits::max()) + : __p_(param_type(__a, __b)) {} + explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {} + void reset() {} + + // generating functions + template result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + result_type a() const {return __p_.a();} + result_type b() const {return __p_.b();} + + param_type param() const {return __p_;} + void param(const param_type& __p) {__p_ = __p;} + + result_type min() const {return a();} + result_type max() const {return b();} + + friend bool operator==(const uniform_int_distribution& __x, + const uniform_int_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend bool operator!=(const uniform_int_distribution& __x, + const uniform_int_distribution& __y) + {return !(__x == __y);} +}; + +template +template +typename uniform_int_distribution<_IntType>::result_type +uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p) +{ + typedef typename conditional::type _UIntType; + const _UIntType _Rp = __p.b() - __p.a() + _UIntType(1); + if (_Rp == 1) + return __p.a(); + const size_t _Dt = numeric_limits<_UIntType>::digits; + typedef __independent_bits_engine<_URNG, _UIntType> _Eng; + if (_Rp == 0) + return static_cast(_Eng(__g, _Dt)()); + size_t __w = _Dt - __clz(_Rp) - 1; + if ((_Rp & (std::numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0) + ++__w; + _Eng __e(__g, __w); + _UIntType __u; + do + { + __u = __e(); + } while (__u >= _Rp); + return static_cast(__u + __p.a()); +} + +class _LIBCPP_TYPE_VIS __rs_default; + +_LIBCPP_FUNC_VIS __rs_default __rs_get(); + +class _LIBCPP_TYPE_VIS __rs_default +{ + static unsigned __c_; + + __rs_default(); +public: + typedef uint_fast32_t result_type; + + static const result_type _Min = 0; + static const result_type _Max = 0xFFFFFFFF; + + __rs_default(const __rs_default&); + ~__rs_default(); + + result_type operator()(); + + static _LIBCPP_CONSTEXPR result_type min() {return _Min;} + static _LIBCPP_CONSTEXPR result_type max() {return _Max;} + + friend _LIBCPP_FUNC_VIS __rs_default __rs_get(); +}; + +_LIBCPP_FUNC_VIS __rs_default __rs_get(); + +template +void +random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef uniform_int_distribution _Dp; + typedef typename _Dp::param_type _Pp; + difference_type __d = __last - __first; + if (__d > 1) + { + _Dp __uid; + __rs_default __g = __rs_get(); + for (--__last, --__d; __first < __last; ++__first, --__d) + { + difference_type __i = __uid(__g, _Pp(0, __d)); + if (__i != difference_type(0)) + swap(*__first, *(__first + __i)); + } + } +} + +template +void +random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _RandomNumberGenerator&& __rand) +#else + _RandomNumberGenerator& __rand) +#endif +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __d = __last - __first; + if (__d > 1) + { + for (--__last; __first < __last; ++__first, --__d) + { + difference_type __i = __rand(__d); + swap(*__first, *(__first + __i)); + } + } +} + +template + void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _UniformRandomNumberGenerator&& __g) +#else + _UniformRandomNumberGenerator& __g) +#endif +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef uniform_int_distribution _Dp; + typedef typename _Dp::param_type _Pp; + difference_type __d = __last - __first; + if (__d > 1) + { + _Dp __uid; + for (--__last, --__d; __first < __last; ++__first, --__d) + { + difference_type __i = __uid(__g, _Pp(0, __d)); + if (__i != difference_type(0)) + swap(*__first, *(__first + __i)); + } + } +} + +template +bool +is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) +{ + for (; __first != __last; ++__first) + if (!__pred(*__first)) + break; + if ( __first == __last ) + return true; + ++__first; + for (; __first != __last; ++__first) + if (__pred(*__first)) + return false; + return true; +} + +// partition + +template +_ForwardIterator +__partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag) +{ + while (true) + { + if (__first == __last) + return __first; + if (!__pred(*__first)) + break; + ++__first; + } + for (_ForwardIterator __p = __first; ++__p != __last;) + { + if (__pred(*__p)) + { + swap(*__first, *__p); + ++__first; + } + } + return __first; +} + +template +_BidirectionalIterator +__partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, + bidirectional_iterator_tag) +{ + while (true) + { + while (true) + { + if (__first == __last) + return __first; + if (!__pred(*__first)) + break; + ++__first; + } + do + { + if (__first == --__last) + return __first; + } while (!__pred(*__last)); + swap(*__first, *__last); + ++__first; + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) +{ + return _VSTD::__partition::type> + (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category()); +} + +// partition_copy + +template +pair<_OutputIterator1, _OutputIterator2> +partition_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator1 __out_true, _OutputIterator2 __out_false, + _Predicate __pred) +{ + for (; __first != __last; ++__first) + { + if (__pred(*__first)) + { + *__out_true = *__first; + ++__out_true; + } + else + { + *__out_false = *__first; + ++__out_false; + } + } + return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); +} + +// partition_point + +template +_ForwardIterator +partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) +{ + typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; + difference_type __len = _VSTD::distance(__first, __last); + while (__len != 0) + { + difference_type __l2 = __len / 2; + _ForwardIterator __m = __first; + _VSTD::advance(__m, __l2); + if (__pred(*__m)) + { + __first = ++__m; + __len -= __l2 + 1; + } + else + __len = __l2; + } + return __first; +} + +// stable_partition + +template +_ForwardIterator +__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, + _Distance __len, _Pair __p, forward_iterator_tag __fit) +{ + // *__first is known to be false + // __len >= 1 + if (__len == 1) + return __first; + if (__len == 2) + { + _ForwardIterator __m = __first; + if (__pred(*++__m)) + { + swap(*__first, *__m); + return __m; + } + return __first; + } + if (__len <= __p.second) + { // The buffer is big enough to use + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__p.first, __d); + // Move the falses into the temporary buffer, and the trues to the front of the line + // Update __first to always point to the end of the trues + value_type* __t = __p.first; + ::new(__t) value_type(_VSTD::move(*__first)); + __d.__incr((value_type*)0); + ++__t; + _ForwardIterator __i = __first; + while (++__i != __last) + { + if (__pred(*__i)) + { + *__first = _VSTD::move(*__i); + ++__first; + } + else + { + ::new(__t) value_type(_VSTD::move(*__i)); + __d.__incr((value_type*)0); + ++__t; + } + } + // All trues now at start of range, all falses in buffer + // Move falses back into range, but don't mess up __first which points to first false + __i = __first; + for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, ++__i) + *__i = _VSTD::move(*__t2); + // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer + return __first; + } + // Else not enough buffer, do in place + // __len >= 3 + _ForwardIterator __m = __first; + _Distance __len2 = __len / 2; // __len2 >= 2 + _VSTD::advance(__m, __len2); + // recurse on [__first, __m), *__first know to be false + // F????????????????? + // f m l + typedef typename add_lvalue_reference<_Predicate>::type _PredRef; + _ForwardIterator __first_false = __stable_partition<_PredRef>(__first, __m, __pred, __len2, __p, __fit); + // TTTFFFFF?????????? + // f ff m l + // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true + _ForwardIterator __m1 = __m; + _ForwardIterator __second_false = __last; + _Distance __len_half = __len - __len2; + while (__pred(*__m1)) + { + if (++__m1 == __last) + goto __second_half_done; + --__len_half; + } + // TTTFFFFFTTTF?????? + // f ff m m1 l + __second_false = __stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __fit); +__second_half_done: + // TTTFFFFFTTTTTFFFFF + // f ff m sf l + return _VSTD::rotate(__first_false, __m, __second_false); + // TTTTTTTTFFFFFFFFFF + // | +} + +struct __return_temporary_buffer +{ + template + _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) const {_VSTD::return_temporary_buffer(__p);} +}; + +template +_ForwardIterator +__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, + forward_iterator_tag) +{ + const unsigned __alloc_limit = 3; // might want to make this a function of trivial assignment + // Either prove all true and return __first or point to first false + while (true) + { + if (__first == __last) + return __first; + if (!__pred(*__first)) + break; + ++__first; + } + // We now have a reduced range [__first, __last) + // *__first is known to be false + typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + difference_type __len = _VSTD::distance(__first, __last); + pair __p(0, 0); + unique_ptr __h; + if (__len >= __alloc_limit) + { + __p = _VSTD::get_temporary_buffer(__len); + __h.reset(__p.first); + } + return __stable_partition::type> + (__first, __last, __pred, __len, __p, forward_iterator_tag()); +} + +template +_BidirectionalIterator +__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, + _Distance __len, _Pair __p, bidirectional_iterator_tag __bit) +{ + // *__first is known to be false + // *__last is known to be true + // __len >= 2 + if (__len == 2) + { + swap(*__first, *__last); + return __last; + } + if (__len == 3) + { + _BidirectionalIterator __m = __first; + if (__pred(*++__m)) + { + swap(*__first, *__m); + swap(*__m, *__last); + return __last; + } + swap(*__m, *__last); + swap(*__first, *__m); + return __m; + } + if (__len <= __p.second) + { // The buffer is big enough to use + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__p.first, __d); + // Move the falses into the temporary buffer, and the trues to the front of the line + // Update __first to always point to the end of the trues + value_type* __t = __p.first; + ::new(__t) value_type(_VSTD::move(*__first)); + __d.__incr((value_type*)0); + ++__t; + _BidirectionalIterator __i = __first; + while (++__i != __last) + { + if (__pred(*__i)) + { + *__first = _VSTD::move(*__i); + ++__first; + } + else + { + ::new(__t) value_type(_VSTD::move(*__i)); + __d.__incr((value_type*)0); + ++__t; + } + } + // move *__last, known to be true + *__first = _VSTD::move(*__i); + __i = ++__first; + // All trues now at start of range, all falses in buffer + // Move falses back into range, but don't mess up __first which points to first false + for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, ++__i) + *__i = _VSTD::move(*__t2); + // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer + return __first; + } + // Else not enough buffer, do in place + // __len >= 4 + _BidirectionalIterator __m = __first; + _Distance __len2 = __len / 2; // __len2 >= 2 + _VSTD::advance(__m, __len2); + // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false + // F????????????????T + // f m l + _BidirectionalIterator __m1 = __m; + _BidirectionalIterator __first_false = __first; + _Distance __len_half = __len2; + while (!__pred(*--__m1)) + { + if (__m1 == __first) + goto __first_half_done; + --__len_half; + } + // F???TFFF?????????T + // f m1 m l + typedef typename add_lvalue_reference<_Predicate>::type _PredRef; + __first_false = __stable_partition<_PredRef>(__first, __m1, __pred, __len_half, __p, __bit); +__first_half_done: + // TTTFFFFF?????????T + // f ff m l + // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true + __m1 = __m; + _BidirectionalIterator __second_false = __last; + ++__second_false; + __len_half = __len - __len2; + while (__pred(*__m1)) + { + if (++__m1 == __last) + goto __second_half_done; + --__len_half; + } + // TTTFFFFFTTTF?????T + // f ff m m1 l + __second_false = __stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __bit); +__second_half_done: + // TTTFFFFFTTTTTFFFFF + // f ff m sf l + return _VSTD::rotate(__first_false, __m, __second_false); + // TTTTTTTTFFFFFFFFFF + // | +} + +template +_BidirectionalIterator +__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, + bidirectional_iterator_tag) +{ + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + const difference_type __alloc_limit = 4; // might want to make this a function of trivial assignment + // Either prove all true and return __first or point to first false + while (true) + { + if (__first == __last) + return __first; + if (!__pred(*__first)) + break; + ++__first; + } + // __first points to first false, everything prior to __first is already set. + // Either prove [__first, __last) is all false and return __first, or point __last to last true + do + { + if (__first == --__last) + return __first; + } while (!__pred(*__last)); + // We now have a reduced range [__first, __last] + // *__first is known to be false + // *__last is known to be true + // __len >= 2 + difference_type __len = _VSTD::distance(__first, __last) + 1; + pair __p(0, 0); + unique_ptr __h; + if (__len >= __alloc_limit) + { + __p = _VSTD::get_temporary_buffer(__len); + __h.reset(__p.first); + } + return __stable_partition::type> + (__first, __last, __pred, __len, __p, bidirectional_iterator_tag()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) +{ + return __stable_partition::type> + (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category()); +} + +// is_sorted_until + +template +_ForwardIterator +is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + { + if (__comp(*__i, *__first)) + return __i; + __first = __i; + } + } + return __last; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) +{ + return _VSTD::is_sorted_until(__first, __last, __less::value_type>()); +} + +// is_sorted + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + return _VSTD::is_sorted_until(__first, __last, __comp) == __last; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +is_sorted(_ForwardIterator __first, _ForwardIterator __last) +{ + return _VSTD::is_sorted(__first, __last, __less::value_type>()); +} + +// sort + +// stable, 2-3 compares, 0-2 swaps + +template +unsigned +__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c) +{ + unsigned __r = 0; + if (!__c(*__y, *__x)) // if x <= y + { + if (!__c(*__z, *__y)) // if y <= z + return __r; // x <= y && y <= z + // x <= y && y > z + swap(*__y, *__z); // x <= z && y < z + __r = 1; + if (__c(*__y, *__x)) // if x > y + { + swap(*__x, *__y); // x < y && y <= z + __r = 2; + } + return __r; // x <= y && y < z + } + if (__c(*__z, *__y)) // x > y, if y > z + { + swap(*__x, *__z); // x < y && y < z + __r = 1; + return __r; + } + swap(*__x, *__y); // x > y && y <= z + __r = 1; // x < y && x <= z + if (__c(*__z, *__y)) // if y > z + { + swap(*__y, *__z); // x <= y && y < z + __r = 2; + } + return __r; +} // x <= y && y <= z + +// stable, 3-6 compares, 0-5 swaps + +template +unsigned +__sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, + _ForwardIterator __x4, _Compare __c) +{ + unsigned __r = __sort3<_Compare>(__x1, __x2, __x3, __c); + if (__c(*__x4, *__x3)) + { + swap(*__x3, *__x4); + ++__r; + if (__c(*__x3, *__x2)) + { + swap(*__x2, *__x3); + ++__r; + if (__c(*__x2, *__x1)) + { + swap(*__x1, *__x2); + ++__r; + } + } + } + return __r; +} + +// stable, 4-10 compares, 0-9 swaps + +template +unsigned +__sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, + _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c) +{ + unsigned __r = __sort4<_Compare>(__x1, __x2, __x3, __x4, __c); + if (__c(*__x5, *__x4)) + { + swap(*__x4, *__x5); + ++__r; + if (__c(*__x4, *__x3)) + { + swap(*__x3, *__x4); + ++__r; + if (__c(*__x3, *__x2)) + { + swap(*__x2, *__x3); + ++__r; + if (__c(*__x2, *__x1)) + { + swap(*__x1, *__x2); + ++__r; + } + } + } + } + return __r; +} + +// Assumes size > 0 +template +void +__selection_sort(_BirdirectionalIterator __first, _BirdirectionalIterator __last, _Compare __comp) +{ + _BirdirectionalIterator __lm1 = __last; + for (--__lm1; __first != __lm1; ++__first) + { + _BirdirectionalIterator __i = _VSTD::min_element<_BirdirectionalIterator, + typename add_lvalue_reference<_Compare>::type> + (__first, __last, __comp); + if (__i != __first) + swap(*__first, *__i); + } +} + +template +void +__insertion_sort(_BirdirectionalIterator __first, _BirdirectionalIterator __last, _Compare __comp) +{ + typedef typename iterator_traits<_BirdirectionalIterator>::value_type value_type; + if (__first != __last) + { + _BirdirectionalIterator __i = __first; + for (++__i; __i != __last; ++__i) + { + _BirdirectionalIterator __j = __i; + value_type __t(_VSTD::move(*__j)); + for (_BirdirectionalIterator __k = __i; __k != __first && __comp(__t, *--__k); --__j) + *__j = _VSTD::move(*__k); + *__j = _VSTD::move(__t); + } + } +} + +template +void +__insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + _RandomAccessIterator __j = __first+2; + __sort3<_Compare>(__first, __first+1, __j, __comp); + for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i) + { + if (__comp(*__i, *__j)) + { + value_type __t(_VSTD::move(*__i)); + _RandomAccessIterator __k = __j; + __j = __i; + do + { + *__j = _VSTD::move(*__k); + __j = __k; + } while (__j != __first && __comp(__t, *--__k)); + *__j = _VSTD::move(__t); + } + __j = __i; + } +} + +template +bool +__insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + switch (__last - __first) + { + case 0: + case 1: + return true; + case 2: + if (__comp(*--__last, *__first)) + swap(*__first, *__last); + return true; + case 3: + _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp); + return true; + case 4: + _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp); + return true; + case 5: + _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp); + return true; + } + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + _RandomAccessIterator __j = __first+2; + __sort3<_Compare>(__first, __first+1, __j, __comp); + const unsigned __limit = 8; + unsigned __count = 0; + for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i) + { + if (__comp(*__i, *__j)) + { + value_type __t(_VSTD::move(*__i)); + _RandomAccessIterator __k = __j; + __j = __i; + do + { + *__j = _VSTD::move(*__k); + __j = __k; + } while (__j != __first && __comp(__t, *--__k)); + *__j = _VSTD::move(__t); + if (++__count == __limit) + return ++__i == __last; + } + __j = __i; + } + return true; +} + +template +void +__insertion_sort_move(_BirdirectionalIterator __first1, _BirdirectionalIterator __last1, + typename iterator_traits<_BirdirectionalIterator>::value_type* __first2, _Compare __comp) +{ + typedef typename iterator_traits<_BirdirectionalIterator>::value_type value_type; + if (__first1 != __last1) + { + __destruct_n __d(0); + unique_ptr __h(__first2, __d); + value_type* __last2 = __first2; + ::new(__last2) value_type(_VSTD::move(*__first1)); + __d.__incr((value_type*)0); + for (++__last2; ++__first1 != __last1; ++__last2) + { + value_type* __j2 = __last2; + value_type* __i2 = __j2; + if (__comp(*__first1, *--__i2)) + { + ::new(__j2) value_type(_VSTD::move(*__i2)); + __d.__incr((value_type*)0); + for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2) + *__j2 = _VSTD::move(*__i2); + *__j2 = _VSTD::move(*__first1); + } + else + { + ::new(__j2) value_type(_VSTD::move(*__first1)); + __d.__incr((value_type*)0); + } + } + __h.release(); + } +} + +template +void +__sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + // _Compare is known to be a reference type + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + const difference_type __limit = is_trivially_copy_constructible::value && + is_trivially_copy_assignable::value ? 30 : 6; + while (true) + { + __restart: + difference_type __len = __last - __first; + switch (__len) + { + case 0: + case 1: + return; + case 2: + if (__comp(*--__last, *__first)) + swap(*__first, *__last); + return; + case 3: + _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp); + return; + case 4: + _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp); + return; + case 5: + _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp); + return; + } + if (__len <= __limit) + { + _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp); + return; + } + // __len > 5 + _RandomAccessIterator __m = __first; + _RandomAccessIterator __lm1 = __last; + --__lm1; + unsigned __n_swaps; + { + difference_type __delta; + if (__len >= 1000) + { + __delta = __len/2; + __m += __delta; + __delta /= 2; + __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m+__delta, __lm1, __comp); + } + else + { + __delta = __len/2; + __m += __delta; + __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp); + } + } + // *__m is median + // partition [__first, __m) < *__m and *__m <= [__m, __last) + // (this inhibits tossing elements equivalent to __m around unnecessarily) + _RandomAccessIterator __i = __first; + _RandomAccessIterator __j = __lm1; + // j points beyond range to be tested, *__m is known to be <= *__lm1 + // The search going up is known to be guarded but the search coming down isn't. + // Prime the downward search with a guard. + if (!__comp(*__i, *__m)) // if *__first == *__m + { + // *__first == *__m, *__first doesn't go in first part + // manually guard downward moving __j against __i + while (true) + { + if (__i == --__j) + { + // *__first == *__m, *__m <= all other elements + // Parition instead into [__first, __i) == *__first and *__first < [__i, __last) + ++__i; // __first + 1 + __j = __last; + if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1) + { + while (true) + { + if (__i == __j) + return; // [__first, __last) all equivalent elements + if (__comp(*__first, *__i)) + { + swap(*__i, *__j); + ++__n_swaps; + ++__i; + break; + } + ++__i; + } + } + // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 + if (__i == __j) + return; + while (true) + { + while (!__comp(*__first, *__i)) + ++__i; + while (__comp(*__first, *--__j)) + ; + if (__i >= __j) + break; + swap(*__i, *__j); + ++__n_swaps; + ++__i; + } + // [__first, __i) == *__first and *__first < [__i, __last) + // The first part is sorted, sort the secod part + // _VSTD::__sort<_Compare>(__i, __last, __comp); + __first = __i; + goto __restart; + } + if (__comp(*__j, *__m)) + { + swap(*__i, *__j); + ++__n_swaps; + break; // found guard for downward moving __j, now use unguarded partition + } + } + } + // It is known that *__i < *__m + ++__i; + // j points beyond range to be tested, *__m is known to be <= *__lm1 + // if not yet partitioned... + if (__i < __j) + { + // known that *(__i - 1) < *__m + // known that __i <= __m + while (true) + { + // __m still guards upward moving __i + while (__comp(*__i, *__m)) + ++__i; + // It is now known that a guard exists for downward moving __j + while (!__comp(*--__j, *__m)) + ; + if (__i > __j) + break; + swap(*__i, *__j); + ++__n_swaps; + // It is known that __m != __j + // If __m just moved, follow it + if (__m == __i) + __m = __j; + ++__i; + } + } + // [__first, __i) < *__m and *__m <= [__i, __last) + if (__i != __m && __comp(*__m, *__i)) + { + swap(*__i, *__m); + ++__n_swaps; + } + // [__first, __i) < *__i and *__i <= [__i+1, __last) + // If we were given a perfect partition, see if insertion sort is quick... + if (__n_swaps == 0) + { + bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp); + if (_VSTD::__insertion_sort_incomplete<_Compare>(__i+1, __last, __comp)) + { + if (__fs) + return; + __last = __i; + continue; + } + else + { + if (__fs) + { + __first = ++__i; + continue; + } + } + } + // sort smaller range with recursive call and larger with tail recursion elimination + if (__i - __first < __last - __i) + { + _VSTD::__sort<_Compare>(__first, __i, __comp); + // _VSTD::__sort<_Compare>(__i+1, __last, __comp); + __first = ++__i; + } + else + { + _VSTD::__sort<_Compare>(__i+1, __last, __comp); + // _VSTD::__sort<_Compare>(__first, __i, __comp); + __last = __i; + } + } +} + +// This forwarder keeps the top call and the recursive calls using the same instantiation, forcing a reference _Compare +template +inline _LIBCPP_INLINE_VISIBILITY +void +sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + __sort<_Comp_ref>(__first, __last, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + __sort<_Comp_ref>(__first, __last, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +sort(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + _VSTD::sort(__first, __last, __less::value_type>()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +sort(_Tp** __first, _Tp** __last) +{ + _VSTD::sort((size_t*)__first, (size_t*)__last, __less()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +sort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last) +{ + _VSTD::sort(__first.base(), __last.base()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +sort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last, _Compare __comp) +{ + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + _VSTD::sort<_Tp*, _Comp_ref>(__first.base(), __last.base(), __comp); +} + +#ifdef _LIBCPP_MSVC +#pragma warning( push ) +#pragma warning( disable: 4231) +#endif // _LIBCPP_MSVC +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, char*>(char*, char*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, signed char*>(signed char*, signed char*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned char*>(unsigned char*, unsigned char*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, short*>(short*, short*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned short*>(unsigned short*, unsigned short*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, int*>(int*, int*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned*>(unsigned*, unsigned*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, long*>(long*, long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned long*>(unsigned long*, unsigned long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, long long*>(long long*, long long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned long long*>(unsigned long long*, unsigned long long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, float*>(float*, float*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, double*>(double*, double*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, long double*>(long double*, long double*, __less&)) + +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, char*>(char*, char*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, signed char*>(signed char*, signed char*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned char*>(unsigned char*, unsigned char*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, short*>(short*, short*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned short*>(unsigned short*, unsigned short*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, int*>(int*, int*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned*>(unsigned*, unsigned*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long*>(long*, long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned long*>(unsigned long*, unsigned long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long long*>(long long*, long long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned long long*>(unsigned long long*, unsigned long long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, float*>(float*, float*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, double*>(double*, double*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long double*>(long double*, long double*, __less&)) + +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS unsigned __sort5<__less&, long double*>(long double*, long double*, long double*, long double*, long double*, __less&)) +#ifdef _LIBCPP_MSVC +#pragma warning( pop ) +#endif // _LIBCPP_MSVC + +// lower_bound + +template +_ForwardIterator +__lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) +{ + typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; + difference_type __len = _VSTD::distance(__first, __last); + while (__len != 0) + { + difference_type __l2 = __len / 2; + _ForwardIterator __m = __first; + _VSTD::advance(__m, __l2); + if (__comp(*__m, __value_)) + { + __first = ++__m; + __len -= __l2 + 1; + } + else + __len = __l2; + } + return __first; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return __lower_bound<_Comp_ref>(__first, __last, __value_, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return __lower_bound<_Comp_ref>(__first, __last, __value_, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) +{ + return _VSTD::lower_bound(__first, __last, __value_, + __less::value_type, _Tp>()); +} + +// upper_bound + +template +_ForwardIterator +__upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) +{ + typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; + difference_type __len = _VSTD::distance(__first, __last); + while (__len != 0) + { + difference_type __l2 = __len / 2; + _ForwardIterator __m = __first; + _VSTD::advance(__m, __l2); + if (__comp(__value_, *__m)) + __len = __l2; + else + { + __first = ++__m; + __len -= __l2 + 1; + } + } + return __first; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return __upper_bound<_Comp_ref>(__first, __last, __value_, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return __upper_bound<_Comp_ref>(__first, __last, __value_, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) +{ + return _VSTD::upper_bound(__first, __last, __value_, + __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>()); +} + +// equal_range + +template +pair<_ForwardIterator, _ForwardIterator> +__equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) +{ + typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; + difference_type __len = _VSTD::distance(__first, __last); + while (__len != 0) + { + difference_type __l2 = __len / 2; + _ForwardIterator __m = __first; + _VSTD::advance(__m, __l2); + if (__comp(*__m, __value_)) + { + __first = ++__m; + __len -= __l2 + 1; + } + else if (__comp(__value_, *__m)) + { + __last = __m; + __len = __l2; + } + else + { + _ForwardIterator __mp1 = __m; + return pair<_ForwardIterator, _ForwardIterator> + ( + __lower_bound<_Compare>(__first, __m, __value_, __comp), + __upper_bound<_Compare>(++__mp1, __last, __value_, __comp) + ); + } + } + return pair<_ForwardIterator, _ForwardIterator>(__first, __first); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +pair<_ForwardIterator, _ForwardIterator> +equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return __equal_range<_Comp_ref>(__first, __last, __value_, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return __equal_range<_Comp_ref>(__first, __last, __value_, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +pair<_ForwardIterator, _ForwardIterator> +equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) +{ + return _VSTD::equal_range(__first, __last, __value_, + __less::value_type, _Tp>()); +} + +// binary_search + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +__binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) +{ + __first = __lower_bound<_Compare>(__first, __last, __value_, __comp); + return __first != __last && !__comp(__value_, *__first); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return __binary_search<_Comp_ref>(__first, __last, __value_, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return __binary_search<_Comp_ref>(__first, __last, __value_, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) +{ + return _VSTD::binary_search(__first, __last, __value_, + __less::value_type, _Tp>()); +} + +// merge + +template +_OutputIterator +__merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + for (; __first1 != __last1; ++__result) + { + if (__first2 == __last2) + return _VSTD::copy(__first1, __last1, __result); + if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + } + } + return _VSTD::copy(__first2, __last2, __result); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) +{ + typedef typename iterator_traits<_InputIterator1>::value_type __v1; + typedef typename iterator_traits<_InputIterator2>::value_type __v2; + return merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>()); +} + +// inplace_merge + +template +void __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) +{ + for (; __first1 != __last1; ++__result) + { + if (__first2 == __last2) + { + _VSTD::move(__first1, __last1, __result); + return; + } + + if (__comp(*__first2, *__first1)) + { + *__result = _VSTD::move(*__first2); + ++__first2; + } + else + { + *__result = _VSTD::move(*__first1); + ++__first1; + } + } + // __first2 through __last2 are already in the right spot. +} + +template +void +__buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, + _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1, + typename iterator_traits<_BidirectionalIterator>::difference_type __len2, + typename iterator_traits<_BidirectionalIterator>::value_type* __buff) +{ + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h2(__buff, __d); + if (__len1 <= __len2) + { + value_type* __p = __buff; + for (_BidirectionalIterator __i = __first; __i != __middle; __d.__incr((value_type*)0), (void) ++__i, ++__p) + ::new(__p) value_type(_VSTD::move(*__i)); + __half_inplace_merge(__buff, __p, __middle, __last, __first, __comp); + } + else + { + value_type* __p = __buff; + for (_BidirectionalIterator __i = __middle; __i != __last; __d.__incr((value_type*)0), (void) ++__i, ++__p) + ::new(__p) value_type(_VSTD::move(*__i)); + typedef reverse_iterator<_BidirectionalIterator> _RBi; + typedef reverse_iterator _Rv; + __half_inplace_merge(_Rv(__p), _Rv(__buff), + _RBi(__middle), _RBi(__first), + _RBi(__last), __negate<_Compare>(__comp)); + } +} + +template +void +__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, + _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1, + typename iterator_traits<_BidirectionalIterator>::difference_type __len2, + typename iterator_traits<_BidirectionalIterator>::value_type* __buff, ptrdiff_t __buff_size) +{ + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + while (true) + { + // if __middle == __last, we're done + if (__len2 == 0) + return; + if (__len1 <= __buff_size || __len2 <= __buff_size) + return __buffered_inplace_merge<_Compare> + (__first, __middle, __last, __comp, __len1, __len2, __buff); + // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0 + for (; true; ++__first, (void) --__len1) + { + if (__len1 == 0) + return; + if (__comp(*__middle, *__first)) + break; + } + // __first < __middle < __last + // *__first > *__middle + // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that + // all elements in: + // [__first, __m1) <= [__middle, __m2) + // [__middle, __m2) < [__m1, __middle) + // [__m1, __middle) <= [__m2, __last) + // and __m1 or __m2 is in the middle of its range + _BidirectionalIterator __m1; // "median" of [__first, __middle) + _BidirectionalIterator __m2; // "median" of [__middle, __last) + difference_type __len11; // distance(__first, __m1) + difference_type __len21; // distance(__middle, __m2) + // binary search smaller range + if (__len1 < __len2) + { // __len >= 1, __len2 >= 2 + __len21 = __len2 / 2; + __m2 = __middle; + _VSTD::advance(__m2, __len21); + __m1 = __upper_bound<_Compare>(__first, __middle, *__m2, __comp); + __len11 = _VSTD::distance(__first, __m1); + } + else + { + if (__len1 == 1) + { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1 + // It is known *__first > *__middle + swap(*__first, *__middle); + return; + } + // __len1 >= 2, __len2 >= 1 + __len11 = __len1 / 2; + __m1 = __first; + _VSTD::advance(__m1, __len11); + __m2 = __lower_bound<_Compare>(__middle, __last, *__m1, __comp); + __len21 = _VSTD::distance(__middle, __m2); + } + difference_type __len12 = __len1 - __len11; // distance(__m1, __middle) + difference_type __len22 = __len2 - __len21; // distance(__m2, __last) + // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) + // swap middle two partitions + __middle = _VSTD::rotate(__m1, __middle, __m2); + // __len12 and __len21 now have swapped meanings + // merge smaller range with recurisve call and larger with tail recursion elimination + if (__len11 + __len21 < __len12 + __len22) + { + __inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); +// __inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); + __first = __middle; + __middle = __m2; + __len1 = __len12; + __len2 = __len22; + } + else + { + __inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); +// __inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); + __last = __middle; + __middle = __m1; + __len1 = __len11; + __len2 = __len21; + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, + _Compare __comp) +{ + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + difference_type __len1 = _VSTD::distance(__first, __middle); + difference_type __len2 = _VSTD::distance(__middle, __last); + difference_type __buf_size = _VSTD::min(__len1, __len2); + pair __buf = _VSTD::get_temporary_buffer(__buf_size); + unique_ptr __h(__buf.first); + +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __c, __len1, __len2, + __buf.first, __buf.second); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2, + __buf.first, __buf.second); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) +{ + _VSTD::inplace_merge(__first, __middle, __last, + __less::value_type>()); +} + +// stable_sort + +template +void +__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp) +{ + typedef typename iterator_traits<_InputIterator1>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__result, __d); + for (; true; ++__result) + { + if (__first1 == __last1) + { + for (; __first2 != __last2; ++__first2, ++__result, __d.__incr((value_type*)0)) + ::new (__result) value_type(_VSTD::move(*__first2)); + __h.release(); + return; + } + if (__first2 == __last2) + { + for (; __first1 != __last1; ++__first1, ++__result, __d.__incr((value_type*)0)) + ::new (__result) value_type(_VSTD::move(*__first1)); + __h.release(); + return; + } + if (__comp(*__first2, *__first1)) + { + ::new (__result) value_type(_VSTD::move(*__first2)); + __d.__incr((value_type*)0); + ++__first2; + } + else + { + ::new (__result) value_type(_VSTD::move(*__first1)); + __d.__incr((value_type*)0); + ++__first1; + } + } +} + +template +void +__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) +{ + for (; __first1 != __last1; ++__result) + { + if (__first2 == __last2) + { + for (; __first1 != __last1; ++__first1, ++__result) + *__result = _VSTD::move(*__first1); + return; + } + if (__comp(*__first2, *__first1)) + { + *__result = _VSTD::move(*__first2); + ++__first2; + } + else + { + *__result = _VSTD::move(*__first1); + ++__first1; + } + } + for (; __first2 != __last2; ++__first2, ++__result) + *__result = _VSTD::move(*__first2); +} + +template +void +__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size); + +template +void +__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __first2) +{ + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + switch (__len) + { + case 0: + return; + case 1: + ::new(__first2) value_type(_VSTD::move(*__first1)); + return; + case 2: + __destruct_n __d(0); + unique_ptr __h2(__first2, __d); + if (__comp(*--__last1, *__first1)) + { + ::new(__first2) value_type(_VSTD::move(*__last1)); + __d.__incr((value_type*)0); + ++__first2; + ::new(__first2) value_type(_VSTD::move(*__first1)); + } + else + { + ::new(__first2) value_type(_VSTD::move(*__first1)); + __d.__incr((value_type*)0); + ++__first2; + ::new(__first2) value_type(_VSTD::move(*__last1)); + } + __h2.release(); + return; + } + if (__len <= 8) + { + __insertion_sort_move<_Compare>(__first1, __last1, __first2, __comp); + return; + } + typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; + _RandomAccessIterator __m = __first1 + __l2; + __stable_sort<_Compare>(__first1, __m, __comp, __l2, __first2, __l2); + __stable_sort<_Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2); + __merge_move_construct<_Compare>(__first1, __m, __m, __last1, __first2, __comp); +} + +template +struct __stable_sort_switch +{ + static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value; +}; + +template +void +__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size) +{ + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + switch (__len) + { + case 0: + case 1: + return; + case 2: + if (__comp(*--__last, *__first)) + swap(*__first, *__last); + return; + } + if (__len <= static_cast(__stable_sort_switch::value)) + { + __insertion_sort<_Compare>(__first, __last, __comp); + return; + } + typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; + _RandomAccessIterator __m = __first + __l2; + if (__len <= __buff_size) + { + __destruct_n __d(0); + unique_ptr __h2(__buff, __d); + __stable_sort_move<_Compare>(__first, __m, __comp, __l2, __buff); + __d.__set(__l2, (value_type*)0); + __stable_sort_move<_Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); + __d.__set(__len, (value_type*)0); + __merge_move_assign<_Compare>(__buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); +// __merge<_Compare>(move_iterator(__buff), +// move_iterator(__buff + __l2), +// move_iterator<_RandomAccessIterator>(__buff + __l2), +// move_iterator<_RandomAccessIterator>(__buff + __len), +// __first, __comp); + return; + } + __stable_sort<_Compare>(__first, __m, __comp, __l2, __buff, __buff_size); + __stable_sort<_Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size); + __inplace_merge<_Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __len = __last - __first; + pair __buf(0, 0); + unique_ptr __h; + if (__len > static_cast(__stable_sort_switch::value)) + { + __buf = _VSTD::get_temporary_buffer(__len); + __h.reset(__buf.first); + } +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + __stable_sort<_Comp_ref>(__first, __last, __c, __len, __buf.first, __buf.second); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + __stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + _VSTD::stable_sort(__first, __last, __less::value_type>()); +} + +// is_heap_until + +template +_RandomAccessIterator +is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __len = __last - __first; + difference_type __p = 0; + difference_type __c = 1; + _RandomAccessIterator __pp = __first; + while (__c < __len) + { + _RandomAccessIterator __cp = __first + __c; + if (__comp(*__pp, *__cp)) + return __cp; + ++__c; + ++__cp; + if (__c == __len) + return __last; + if (__comp(*__pp, *__cp)) + return __cp; + ++__p; + ++__pp; + __c = 2 * __p + 1; + } + return __last; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_RandomAccessIterator +is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + return _VSTD::is_heap_until(__first, __last, __less::value_type>()); +} + +// is_heap + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + return _VSTD::is_heap_until(__first, __last, __comp) == __last; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + return _VSTD::is_heap(__first, __last, __less::value_type>()); +} + +// push_heap + +template +void +__sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) +{ + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + if (__len > 1) + { + __len = (__len - 2) / 2; + _RandomAccessIterator __ptr = __first + __len; + if (__comp(*__ptr, *--__last)) + { + value_type __t(_VSTD::move(*__last)); + do + { + *__last = _VSTD::move(*__ptr); + __last = __ptr; + if (__len == 0) + break; + __len = (__len - 1) / 2; + __ptr = __first + __len; + } while (__comp(*__ptr, __t)); + *__last = _VSTD::move(__t); + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + __sift_up<_Comp_ref>(__first, __last, __c, __last - __first); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + __sift_up<_Comp_ref>(__first, __last, __comp, __last - __first); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + _VSTD::push_heap(__first, __last, __less::value_type>()); +} + +// pop_heap + +template +void +__sift_down(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + _RandomAccessIterator __start) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + // left-child of __start is at 2 * __start + 1 + // right-child of __start is at 2 * __start + 2 + difference_type __child = __start - __first; + + if (__len < 2 || (__len - 2) / 2 < __child) + return; + + __child = 2 * __child + 1; + _RandomAccessIterator __child_i = __first + __child; + + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) { + // right-child exists and is greater than left-child + ++__child_i; + ++__child; + } + + // check if we are in heap-order + if (__comp(*__child_i, *__start)) + // we are, __start is larger than it's largest child + return; + + value_type __top(_VSTD::move(*__start)); + do + { + // we are not in heap-order, swap the parent with it's largest child + *__start = _VSTD::move(*__child_i); + __start = __child_i; + + if ((__len - 2) / 2 < __child) + break; + + // recompute the child based off of the updated parent + __child = 2 * __child + 1; + __child_i = __first + __child; + + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) { + // right-child exists and is greater than left-child + ++__child_i; + ++__child; + } + + // check if we are in heap-order + } while (!__comp(*__child_i, __top)); + *__start = _VSTD::move(__top); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) +{ + if (__len > 1) + { + swap(*__first, *--__last); + __sift_down<_Compare>(__first, __last, __comp, __len - 1, __first); + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + __pop_heap<_Comp_ref>(__first, __last, __c, __last - __first); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + __pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + _VSTD::pop_heap(__first, __last, __less::value_type>()); +} + +// make_heap + +template +void +__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __n = __last - __first; + if (__n > 1) + { + // start from the first parent, there is no need to consider children + for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) + { + __sift_down<_Compare>(__first, __last, __comp, __n, __first + __start); + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + __make_heap<_Comp_ref>(__first, __last, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + __make_heap<_Comp_ref>(__first, __last, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + _VSTD::make_heap(__first, __last, __less::value_type>()); +} + +// sort_heap + +template +void +__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + for (difference_type __n = __last - __first; __n > 1; --__last, --__n) + __pop_heap<_Compare>(__first, __last, __comp, __n); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + __sort_heap<_Comp_ref>(__first, __last, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + __sort_heap<_Comp_ref>(__first, __last, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + _VSTD::sort_heap(__first, __last, __less::value_type>()); +} + +// partial_sort + +template +void +__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, + _Compare __comp) +{ + __make_heap<_Compare>(__first, __middle, __comp); + typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; + for (_RandomAccessIterator __i = __middle; __i != __last; ++__i) + { + if (__comp(*__i, *__first)) + { + swap(*__i, *__first); + __sift_down<_Compare>(__first, __middle, __comp, __len, __first); + } + } + __sort_heap<_Compare>(__first, __middle, __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, + _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + __partial_sort<_Comp_ref>(__first, __middle, __last, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + __partial_sort<_Comp_ref>(__first, __middle, __last, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) +{ + _VSTD::partial_sort(__first, __middle, __last, + __less::value_type>()); +} + +// partial_sort_copy + +template +_RandomAccessIterator +__partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) +{ + _RandomAccessIterator __r = __result_first; + if (__r != __result_last) + { + for (; __first != __last && __r != __result_last; (void) ++__first, ++__r) + *__r = *__first; + __make_heap<_Compare>(__result_first, __r, __comp); + typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; + for (; __first != __last; ++__first) + if (__comp(*__first, *__result_first)) + { + *__result_first = *__first; + __sift_down<_Compare>(__result_first, __r, __comp, __len, __result_first); + } + __sort_heap<_Compare>(__result_first, __r, __comp); + } + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_RandomAccessIterator +partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_RandomAccessIterator +partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, _RandomAccessIterator __result_last) +{ + return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, + __less::value_type>()); +} + +// nth_element + +template +void +__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) +{ + // _Compare is known to be a reference type + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + const difference_type __limit = 7; + while (true) + { + __restart: + if (__nth == __last) + return; + difference_type __len = __last - __first; + switch (__len) + { + case 0: + case 1: + return; + case 2: + if (__comp(*--__last, *__first)) + swap(*__first, *__last); + return; + case 3: + { + _RandomAccessIterator __m = __first; + _VSTD::__sort3<_Compare>(__first, ++__m, --__last, __comp); + return; + } + } + if (__len <= __limit) + { + __selection_sort<_Compare>(__first, __last, __comp); + return; + } + // __len > __limit >= 3 + _RandomAccessIterator __m = __first + __len/2; + _RandomAccessIterator __lm1 = __last; + unsigned __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, --__lm1, __comp); + // *__m is median + // partition [__first, __m) < *__m and *__m <= [__m, __last) + // (this inhibits tossing elements equivalent to __m around unnecessarily) + _RandomAccessIterator __i = __first; + _RandomAccessIterator __j = __lm1; + // j points beyond range to be tested, *__lm1 is known to be <= *__m + // The search going up is known to be guarded but the search coming down isn't. + // Prime the downward search with a guard. + if (!__comp(*__i, *__m)) // if *__first == *__m + { + // *__first == *__m, *__first doesn't go in first part + // manually guard downward moving __j against __i + while (true) + { + if (__i == --__j) + { + // *__first == *__m, *__m <= all other elements + // Parition instead into [__first, __i) == *__first and *__first < [__i, __last) + ++__i; // __first + 1 + __j = __last; + if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1) + { + while (true) + { + if (__i == __j) + return; // [__first, __last) all equivalent elements + if (__comp(*__first, *__i)) + { + swap(*__i, *__j); + ++__n_swaps; + ++__i; + break; + } + ++__i; + } + } + // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 + if (__i == __j) + return; + while (true) + { + while (!__comp(*__first, *__i)) + ++__i; + while (__comp(*__first, *--__j)) + ; + if (__i >= __j) + break; + swap(*__i, *__j); + ++__n_swaps; + ++__i; + } + // [__first, __i) == *__first and *__first < [__i, __last) + // The first part is sorted, + if (__nth < __i) + return; + // __nth_element the secod part + // __nth_element<_Compare>(__i, __nth, __last, __comp); + __first = __i; + goto __restart; + } + if (__comp(*__j, *__m)) + { + swap(*__i, *__j); + ++__n_swaps; + break; // found guard for downward moving __j, now use unguarded partition + } + } + } + ++__i; + // j points beyond range to be tested, *__lm1 is known to be <= *__m + // if not yet partitioned... + if (__i < __j) + { + // known that *(__i - 1) < *__m + while (true) + { + // __m still guards upward moving __i + while (__comp(*__i, *__m)) + ++__i; + // It is now known that a guard exists for downward moving __j + while (!__comp(*--__j, *__m)) + ; + if (__i >= __j) + break; + swap(*__i, *__j); + ++__n_swaps; + // It is known that __m != __j + // If __m just moved, follow it + if (__m == __i) + __m = __j; + ++__i; + } + } + // [__first, __i) < *__m and *__m <= [__i, __last) + if (__i != __m && __comp(*__m, *__i)) + { + swap(*__i, *__m); + ++__n_swaps; + } + // [__first, __i) < *__i and *__i <= [__i+1, __last) + if (__nth == __i) + return; + if (__n_swaps == 0) + { + // We were given a perfectly partitioned sequence. Coincidence? + if (__nth < __i) + { + // Check for [__first, __i) already sorted + __j = __m = __first; + while (++__j != __i) + { + if (__comp(*__j, *__m)) + // not yet sorted, so sort + goto not_sorted; + __m = __j; + } + // [__first, __i) sorted + return; + } + else + { + // Check for [__i, __last) already sorted + __j = __m = __i; + while (++__j != __last) + { + if (__comp(*__j, *__m)) + // not yet sorted, so sort + goto not_sorted; + __m = __j; + } + // [__i, __last) sorted + return; + } + } +not_sorted: + // __nth_element on range containing __nth + if (__nth < __i) + { + // __nth_element<_Compare>(__first, __nth, __i, __comp); + __last = __i; + } + else + { + // __nth_element<_Compare>(__i+1, __nth, __last, __comp); + __first = ++__i; + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + __nth_element<_Comp_ref>(__first, __nth, __last, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + __nth_element<_Comp_ref>(__first, __nth, __last, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) +{ + _VSTD::nth_element(__first, __nth, __last, __less::value_type>()); +} + +// includes + +template +bool +__includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, + _Compare __comp) +{ + for (; __first2 != __last2; ++__first1) + { + if (__first1 == __last1 || __comp(*__first2, *__first1)) + return false; + if (!__comp(*__first1, *__first2)) + ++__first2; + } + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, + _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) +{ + return _VSTD::includes(__first1, __last1, __first2, __last2, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +// set_union + +template +_OutputIterator +__set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + for (; __first1 != __last1; ++__result) + { + if (__first2 == __last2) + return _VSTD::copy(__first1, __last1, __result); + if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + if (!__comp(*__first1, *__first2)) + ++__first2; + ++__first1; + } + } + return _VSTD::copy(__first2, __last2, __result); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) +{ + return _VSTD::set_union(__first1, __last1, __first2, __last2, __result, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +// set_intersection + +template +_OutputIterator +__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + while (__first1 != __last1 && __first2 != __last2) + { + if (__comp(*__first1, *__first2)) + ++__first1; + else + { + if (!__comp(*__first2, *__first1)) + { + *__result = *__first1; + ++__result; + ++__first1; + } + ++__first2; + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) +{ + return _VSTD::set_intersection(__first1, __last1, __first2, __last2, __result, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +// set_difference + +template +_OutputIterator +__set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + while (__first1 != __last1) + { + if (__first2 == __last2) + return _VSTD::copy(__first1, __last1, __result); + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__result; + ++__first1; + } + else + { + if (!__comp(*__first2, *__first1)) + ++__first1; + ++__first2; + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) +{ + return _VSTD::set_difference(__first1, __last1, __first2, __last2, __result, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +// set_symmetric_difference + +template +_OutputIterator +__set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + while (__first1 != __last1) + { + if (__first2 == __last2) + return _VSTD::copy(__first1, __last1, __result); + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__result; + ++__first1; + } + else + { + if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__result; + } + else + ++__first1; + ++__first2; + } + } + return _VSTD::copy(__first2, __last2, __result); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) +{ + return _VSTD::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +// lexicographical_compare + +template +bool +__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) +{ + for (; __first2 != __last2; ++__first1, (void) ++__first2) + { + if (__first1 == __last1 || __comp(*__first1, *__first2)) + return true; + if (__comp(*__first2, *__first1)) + return false; + } + return false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) +{ + return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +// next_permutation + +template +bool +__next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) +{ + _BidirectionalIterator __i = __last; + if (__first == __last || __first == --__i) + return false; + while (true) + { + _BidirectionalIterator __ip1 = __i; + if (__comp(*--__i, *__ip1)) + { + _BidirectionalIterator __j = __last; + while (!__comp(*__i, *--__j)) + ; + swap(*__i, *__j); + _VSTD::reverse(__ip1, __last); + return true; + } + if (__i == __first) + { + _VSTD::reverse(__first, __last); + return false; + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return __next_permutation<_Comp_ref>(__first, __last, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return __next_permutation<_Comp_ref>(__first, __last, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) +{ + return _VSTD::next_permutation(__first, __last, + __less::value_type>()); +} + +// prev_permutation + +template +bool +__prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) +{ + _BidirectionalIterator __i = __last; + if (__first == __last || __first == --__i) + return false; + while (true) + { + _BidirectionalIterator __ip1 = __i; + if (__comp(*__ip1, *--__i)) + { + _BidirectionalIterator __j = __last; + while (!__comp(*--__j, *__i)) + ; + swap(*__i, *__j); + _VSTD::reverse(__ip1, __last); + return true; + } + if (__i == __first) + { + _VSTD::reverse(__first, __last); + return false; + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) +{ +#ifdef _LIBCPP_DEBUG + typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; + __debug_less<_Compare> __c(__comp); + return __prev_permutation<_Comp_ref>(__first, __last, __c); +#else // _LIBCPP_DEBUG + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + return __prev_permutation<_Comp_ref>(__first, __last, __comp); +#endif // _LIBCPP_DEBUG +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) +{ + return _VSTD::prev_permutation(__first, __last, + __less::value_type>()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value, + _Tp +>::type +__rotate_left(_Tp __t, _Tp __n = 1) +{ + const unsigned __bits = static_cast(sizeof(_Tp) * __CHAR_BIT__ - 1); + __n &= __bits; + return static_cast<_Tp>((__t << __n) | (static_cast::type>(__t) >> (__bits - __n))); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value, + _Tp +>::type +__rotate_right(_Tp __t, _Tp __n = 1) +{ + const unsigned __bits = static_cast(sizeof(_Tp) * __CHAR_BIT__ - 1); + __n &= __bits; + return static_cast<_Tp>((__t << (__bits - __n)) | (static_cast::type>(__t) >> __n)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_ALGORITHM diff --git a/headers/libs/libc++/array b/headers/libs/libc++/array new file mode 100644 index 0000000000..2e02a43ed5 --- /dev/null +++ b/headers/libs/libc++/array @@ -0,0 +1,331 @@ +// -*- C++ -*- +//===---------------------------- array -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_ARRAY +#define _LIBCPP_ARRAY + +/* + array synopsis + +namespace std +{ +template +struct array +{ + // types: + typedef T & reference; + typedef const T & const_reference; + typedef implementation defined iterator; + typedef implementation defined const_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // No explicit construct/copy/destroy for aggregate type + void fill(const T& u); + void swap(array& a) noexcept(noexcept(swap(declval(), declval()))); + + // iterators: + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + // capacity: + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + + // element access: + reference operator[](size_type n); + const_reference operator[](size_type n) const; // constexpr in C++14 + const_reference at(size_type n) const; // constexpr in C++14 + reference at(size_type n); + + reference front(); + const_reference front() const; // constexpr in C++14 + reference back(); + const_reference back() const; // constexpr in C++14 + + T* data() noexcept; + const T* data() const noexcept; +}; + +template + bool operator==(const array& x, const array& y); +template + bool operator!=(const array& x, const array& y); +template + bool operator<(const array& x, const array& y); +template + bool operator>(const array& x, const array& y); +template + bool operator<=(const array& x, const array& y); +template + bool operator>=(const array& x, const array& y); + +template + void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); + +template class tuple_size; +template class tuple_element; +template struct tuple_size>; +template struct tuple_element>; +template T& get(array&) noexcept; // constexpr in C++14 +template const T& get(const array&) noexcept; // constexpr in C++14 +template T&& get(array&&) noexcept; // constexpr in C++14 + +} // std + +*/ + +#include <__config> +#include <__tuple> +#include +#include +#include +#include +#include +#if defined(_LIBCPP_NO_EXCEPTIONS) + #include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TYPE_VIS_ONLY array +{ + // types: + typedef array __self; + typedef _Tp value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* iterator; + typedef const value_type* const_iterator; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + value_type __elems_[_Size > 0 ? _Size : 1]; + + // No explicit construct/copy/destroy for aggregate type + _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) + {_VSTD::fill_n(__elems_, _Size, __u);} + _LIBCPP_INLINE_VISIBILITY + void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) + {_VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);} + + // iterators: + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT {return iterator(__elems_);} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);} + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + _Size);} + + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());} + + _LIBCPP_INLINE_VISIBILITY + const_iterator cbegin() const _NOEXCEPT {return begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator cend() const _NOEXCEPT {return end();} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crend() const _NOEXCEPT {return rend();} + + // capacity: + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return _Size;} + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return _Size;} + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return _Size == 0;} + + // element access: + _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) {return __elems_[__n];} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference operator[](size_type __n) const {return __elems_[__n];} + reference at(size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const; + + _LIBCPP_INLINE_VISIBILITY reference front() {return __elems_[0];} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const {return __elems_[0];} + _LIBCPP_INLINE_VISIBILITY reference back() {return __elems_[_Size > 0 ? _Size-1 : 0];} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const {return __elems_[_Size > 0 ? _Size-1 : 0];} + + _LIBCPP_INLINE_VISIBILITY + value_type* data() _NOEXCEPT {return __elems_;} + _LIBCPP_INLINE_VISIBILITY + const value_type* data() const _NOEXCEPT {return __elems_;} +}; + +template +typename array<_Tp, _Size>::reference +array<_Tp, _Size>::at(size_type __n) +{ + if (__n >= _Size) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw out_of_range("array::at"); +#else + assert(!"array::at out_of_range"); +#endif + return __elems_[__n]; +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 +typename array<_Tp, _Size>::const_reference +array<_Tp, _Size>::at(size_type __n) const +{ + if (__n >= _Size) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw out_of_range("array::at"); +#else + assert(!"array::at out_of_range"); +#endif + return __elems_[__n]; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) +{ + return _VSTD::equal(__x.__elems_, __x.__elems_ + _Size, __y.__elems_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) +{ + return _VSTD::lexicographical_compare(__x.__elems_, __x.__elems_ + _Size, __y.__elems_, __y.__elems_ + _Size); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + __is_swappable<_Tp>::value, + void +>::type +swap(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) + _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) +{ + __x.swap(__y); +} + +template +class _LIBCPP_TYPE_VIS_ONLY tuple_size > + : public integral_constant {}; + +template +class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, array<_Tp, _Size> > +{ +public: + typedef _Tp type; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp& +get(array<_Tp, _Size>& __a) _NOEXCEPT +{ + static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)"); + return __a.__elems_[_Ip]; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +const _Tp& +get(const array<_Tp, _Size>& __a) _NOEXCEPT +{ + static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)"); + return __a.__elems_[_Ip]; +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp&& +get(array<_Tp, _Size>&& __a) _NOEXCEPT +{ + static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)"); + return _VSTD::move(__a.__elems_[_Ip]); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_ARRAY diff --git a/headers/libs/libc++/atomic b/headers/libs/libc++/atomic new file mode 100644 index 0000000000..b5d5a27b04 --- /dev/null +++ b/headers/libs/libc++/atomic @@ -0,0 +1,1799 @@ +// -*- C++ -*- +//===--------------------------- atomic -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_ATOMIC +#define _LIBCPP_ATOMIC + +/* + atomic synopsis + +namespace std +{ + +// order and consistency + +typedef enum memory_order +{ + memory_order_relaxed, + memory_order_consume, // load-consume + memory_order_acquire, // load-acquire + memory_order_release, // store-release + memory_order_acq_rel, // store-release load-acquire + memory_order_seq_cst // store-release load-acquire +} memory_order; + +template T kill_dependency(T y) noexcept; + +// lock-free property + +#define ATOMIC_BOOL_LOCK_FREE unspecified +#define ATOMIC_CHAR_LOCK_FREE unspecified +#define ATOMIC_CHAR16_T_LOCK_FREE unspecified +#define ATOMIC_CHAR32_T_LOCK_FREE unspecified +#define ATOMIC_WCHAR_T_LOCK_FREE unspecified +#define ATOMIC_SHORT_LOCK_FREE unspecified +#define ATOMIC_INT_LOCK_FREE unspecified +#define ATOMIC_LONG_LOCK_FREE unspecified +#define ATOMIC_LLONG_LOCK_FREE unspecified +#define ATOMIC_POINTER_LOCK_FREE unspecified + +// flag type and operations + +typedef struct atomic_flag +{ + bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept; + bool test_and_set(memory_order m = memory_order_seq_cst) noexcept; + void clear(memory_order m = memory_order_seq_cst) volatile noexcept; + void clear(memory_order m = memory_order_seq_cst) noexcept; + atomic_flag() noexcept = default; + atomic_flag(const atomic_flag&) = delete; + atomic_flag& operator=(const atomic_flag&) = delete; + atomic_flag& operator=(const atomic_flag&) volatile = delete; +} atomic_flag; + +bool + atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept; + +bool + atomic_flag_test_and_set(atomic_flag* obj) noexcept; + +bool + atomic_flag_test_and_set_explicit(volatile atomic_flag* obj, + memory_order m) noexcept; + +bool + atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept; + +void + atomic_flag_clear(volatile atomic_flag* obj) noexcept; + +void + atomic_flag_clear(atomic_flag* obj) noexcept; + +void + atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept; + +void + atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept; + +#define ATOMIC_FLAG_INIT see below +#define ATOMIC_VAR_INIT(value) see below + +template +struct atomic +{ + bool is_lock_free() const volatile noexcept; + bool is_lock_free() const noexcept; + void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; + void store(T desr, memory_order m = memory_order_seq_cst) noexcept; + T load(memory_order m = memory_order_seq_cst) const volatile noexcept; + T load(memory_order m = memory_order_seq_cst) const noexcept; + operator T() const volatile noexcept; + operator T() const noexcept; + T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; + T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept; + bool compare_exchange_weak(T& expc, T desr, + memory_order s, memory_order f) volatile noexcept; + bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept; + bool compare_exchange_strong(T& expc, T desr, + memory_order s, memory_order f) volatile noexcept; + bool compare_exchange_strong(T& expc, T desr, + memory_order s, memory_order f) noexcept; + bool compare_exchange_weak(T& expc, T desr, + memory_order m = memory_order_seq_cst) volatile noexcept; + bool compare_exchange_weak(T& expc, T desr, + memory_order m = memory_order_seq_cst) noexcept; + bool compare_exchange_strong(T& expc, T desr, + memory_order m = memory_order_seq_cst) volatile noexcept; + bool compare_exchange_strong(T& expc, T desr, + memory_order m = memory_order_seq_cst) noexcept; + + atomic() noexcept = default; + constexpr atomic(T desr) noexcept; + atomic(const atomic&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; + T operator=(T) volatile noexcept; + T operator=(T) noexcept; +}; + +template <> +struct atomic +{ + bool is_lock_free() const volatile noexcept; + bool is_lock_free() const noexcept; + void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept; + void store(integral desr, memory_order m = memory_order_seq_cst) noexcept; + integral load(memory_order m = memory_order_seq_cst) const volatile noexcept; + integral load(memory_order m = memory_order_seq_cst) const noexcept; + operator integral() const volatile noexcept; + operator integral() const noexcept; + integral exchange(integral desr, + memory_order m = memory_order_seq_cst) volatile noexcept; + integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept; + bool compare_exchange_weak(integral& expc, integral desr, + memory_order s, memory_order f) volatile noexcept; + bool compare_exchange_weak(integral& expc, integral desr, + memory_order s, memory_order f) noexcept; + bool compare_exchange_strong(integral& expc, integral desr, + memory_order s, memory_order f) volatile noexcept; + bool compare_exchange_strong(integral& expc, integral desr, + memory_order s, memory_order f) noexcept; + bool compare_exchange_weak(integral& expc, integral desr, + memory_order m = memory_order_seq_cst) volatile noexcept; + bool compare_exchange_weak(integral& expc, integral desr, + memory_order m = memory_order_seq_cst) noexcept; + bool compare_exchange_strong(integral& expc, integral desr, + memory_order m = memory_order_seq_cst) volatile noexcept; + bool compare_exchange_strong(integral& expc, integral desr, + memory_order m = memory_order_seq_cst) noexcept; + + integral + fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; + integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept; + integral + fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; + integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept; + integral + fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; + integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept; + integral + fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; + integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept; + integral + fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; + integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept; + + atomic() noexcept = default; + constexpr atomic(integral desr) noexcept; + atomic(const atomic&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; + integral operator=(integral desr) volatile noexcept; + integral operator=(integral desr) noexcept; + + integral operator++(int) volatile noexcept; + integral operator++(int) noexcept; + integral operator--(int) volatile noexcept; + integral operator--(int) noexcept; + integral operator++() volatile noexcept; + integral operator++() noexcept; + integral operator--() volatile noexcept; + integral operator--() noexcept; + integral operator+=(integral op) volatile noexcept; + integral operator+=(integral op) noexcept; + integral operator-=(integral op) volatile noexcept; + integral operator-=(integral op) noexcept; + integral operator&=(integral op) volatile noexcept; + integral operator&=(integral op) noexcept; + integral operator|=(integral op) volatile noexcept; + integral operator|=(integral op) noexcept; + integral operator^=(integral op) volatile noexcept; + integral operator^=(integral op) noexcept; +}; + +template +struct atomic +{ + bool is_lock_free() const volatile noexcept; + bool is_lock_free() const noexcept; + void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; + void store(T* desr, memory_order m = memory_order_seq_cst) noexcept; + T* load(memory_order m = memory_order_seq_cst) const volatile noexcept; + T* load(memory_order m = memory_order_seq_cst) const noexcept; + operator T*() const volatile noexcept; + operator T*() const noexcept; + T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; + T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept; + bool compare_exchange_weak(T*& expc, T* desr, + memory_order s, memory_order f) volatile noexcept; + bool compare_exchange_weak(T*& expc, T* desr, + memory_order s, memory_order f) noexcept; + bool compare_exchange_strong(T*& expc, T* desr, + memory_order s, memory_order f) volatile noexcept; + bool compare_exchange_strong(T*& expc, T* desr, + memory_order s, memory_order f) noexcept; + bool compare_exchange_weak(T*& expc, T* desr, + memory_order m = memory_order_seq_cst) volatile noexcept; + bool compare_exchange_weak(T*& expc, T* desr, + memory_order m = memory_order_seq_cst) noexcept; + bool compare_exchange_strong(T*& expc, T* desr, + memory_order m = memory_order_seq_cst) volatile noexcept; + bool compare_exchange_strong(T*& expc, T* desr, + memory_order m = memory_order_seq_cst) noexcept; + T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; + T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; + T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; + T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; + + atomic() noexcept = default; + constexpr atomic(T* desr) noexcept; + atomic(const atomic&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; + + T* operator=(T*) volatile noexcept; + T* operator=(T*) noexcept; + T* operator++(int) volatile noexcept; + T* operator++(int) noexcept; + T* operator--(int) volatile noexcept; + T* operator--(int) noexcept; + T* operator++() volatile noexcept; + T* operator++() noexcept; + T* operator--() volatile noexcept; + T* operator--() noexcept; + T* operator+=(ptrdiff_t op) volatile noexcept; + T* operator+=(ptrdiff_t op) noexcept; + T* operator-=(ptrdiff_t op) volatile noexcept; + T* operator-=(ptrdiff_t op) noexcept; +}; + + +template + bool + atomic_is_lock_free(const volatile atomic* obj) noexcept; + +template + bool + atomic_is_lock_free(const atomic* obj) noexcept; + +template + void + atomic_init(volatile atomic* obj, T desr) noexcept; + +template + void + atomic_init(atomic* obj, T desr) noexcept; + +template + void + atomic_store(volatile atomic* obj, T desr) noexcept; + +template + void + atomic_store(atomic* obj, T desr) noexcept; + +template + void + atomic_store_explicit(volatile atomic* obj, T desr, memory_order m) noexcept; + +template + void + atomic_store_explicit(atomic* obj, T desr, memory_order m) noexcept; + +template + T + atomic_load(const volatile atomic* obj) noexcept; + +template + T + atomic_load(const atomic* obj) noexcept; + +template + T + atomic_load_explicit(const volatile atomic* obj, memory_order m) noexcept; + +template + T + atomic_load_explicit(const atomic* obj, memory_order m) noexcept; + +template + T + atomic_exchange(volatile atomic* obj, T desr) noexcept; + +template + T + atomic_exchange(atomic* obj, T desr) noexcept; + +template + T + atomic_exchange_explicit(volatile atomic* obj, T desr, memory_order m) noexcept; + +template + T + atomic_exchange_explicit(atomic* obj, T desr, memory_order m) noexcept; + +template + bool + atomic_compare_exchange_weak(volatile atomic* obj, T* expc, T desr) noexcept; + +template + bool + atomic_compare_exchange_weak(atomic* obj, T* expc, T desr) noexcept; + +template + bool + atomic_compare_exchange_strong(volatile atomic* obj, T* expc, T desr) noexcept; + +template + bool + atomic_compare_exchange_strong(atomic* obj, T* expc, T desr) noexcept; + +template + bool + atomic_compare_exchange_weak_explicit(volatile atomic* obj, T* expc, + T desr, + memory_order s, memory_order f) noexcept; + +template + bool + atomic_compare_exchange_weak_explicit(atomic* obj, T* expc, T desr, + memory_order s, memory_order f) noexcept; + +template + bool + atomic_compare_exchange_strong_explicit(volatile atomic* obj, + T* expc, T desr, + memory_order s, memory_order f) noexcept; + +template + bool + atomic_compare_exchange_strong_explicit(atomic* obj, T* expc, + T desr, + memory_order s, memory_order f) noexcept; + +template + Integral + atomic_fetch_add(volatile atomic* obj, Integral op) noexcept; + +template + Integral + atomic_fetch_add(atomic* obj, Integral op) noexcept; + +template + Integral + atomic_fetch_add_explicit(volatile atomic* obj, Integral op, + memory_order m) noexcept; +template + Integral + atomic_fetch_add_explicit(atomic* obj, Integral op, + memory_order m) noexcept; +template + Integral + atomic_fetch_sub(volatile atomic* obj, Integral op) noexcept; + +template + Integral + atomic_fetch_sub(atomic* obj, Integral op) noexcept; + +template + Integral + atomic_fetch_sub_explicit(volatile atomic* obj, Integral op, + memory_order m) noexcept; +template + Integral + atomic_fetch_sub_explicit(atomic* obj, Integral op, + memory_order m) noexcept; +template + Integral + atomic_fetch_and(volatile atomic* obj, Integral op) noexcept; + +template + Integral + atomic_fetch_and(atomic* obj, Integral op) noexcept; + +template + Integral + atomic_fetch_and_explicit(volatile atomic* obj, Integral op, + memory_order m) noexcept; +template + Integral + atomic_fetch_and_explicit(atomic* obj, Integral op, + memory_order m) noexcept; +template + Integral + atomic_fetch_or(volatile atomic* obj, Integral op) noexcept; + +template + Integral + atomic_fetch_or(atomic* obj, Integral op) noexcept; + +template + Integral + atomic_fetch_or_explicit(volatile atomic* obj, Integral op, + memory_order m) noexcept; +template + Integral + atomic_fetch_or_explicit(atomic* obj, Integral op, + memory_order m) noexcept; +template + Integral + atomic_fetch_xor(volatile atomic* obj, Integral op) noexcept; + +template + Integral + atomic_fetch_xor(atomic* obj, Integral op) noexcept; + +template + Integral + atomic_fetch_xor_explicit(volatile atomic* obj, Integral op, + memory_order m) noexcept; +template + Integral + atomic_fetch_xor_explicit(atomic* obj, Integral op, + memory_order m) noexcept; + +template + T* + atomic_fetch_add(volatile atomic* obj, ptrdiff_t op) noexcept; + +template + T* + atomic_fetch_add(atomic* obj, ptrdiff_t op) noexcept; + +template + T* + atomic_fetch_add_explicit(volatile atomic* obj, ptrdiff_t op, + memory_order m) noexcept; +template + T* + atomic_fetch_add_explicit(atomic* obj, ptrdiff_t op, memory_order m) noexcept; + +template + T* + atomic_fetch_sub(volatile atomic* obj, ptrdiff_t op) noexcept; + +template + T* + atomic_fetch_sub(atomic* obj, ptrdiff_t op) noexcept; + +template + T* + atomic_fetch_sub_explicit(volatile atomic* obj, ptrdiff_t op, + memory_order m) noexcept; +template + T* + atomic_fetch_sub_explicit(atomic* obj, ptrdiff_t op, memory_order m) noexcept; + +// Atomics for standard typedef types + +typedef atomic atomic_bool; +typedef atomic atomic_char; +typedef atomic atomic_schar; +typedef atomic atomic_uchar; +typedef atomic atomic_short; +typedef atomic atomic_ushort; +typedef atomic atomic_int; +typedef atomic atomic_uint; +typedef atomic atomic_long; +typedef atomic atomic_ulong; +typedef atomic atomic_llong; +typedef atomic atomic_ullong; +typedef atomic atomic_char16_t; +typedef atomic atomic_char32_t; +typedef atomic atomic_wchar_t; + +typedef atomic atomic_int_least8_t; +typedef atomic atomic_uint_least8_t; +typedef atomic atomic_int_least16_t; +typedef atomic atomic_uint_least16_t; +typedef atomic atomic_int_least32_t; +typedef atomic atomic_uint_least32_t; +typedef atomic atomic_int_least64_t; +typedef atomic atomic_uint_least64_t; + +typedef atomic atomic_int_fast8_t; +typedef atomic atomic_uint_fast8_t; +typedef atomic atomic_int_fast16_t; +typedef atomic atomic_uint_fast16_t; +typedef atomic atomic_int_fast32_t; +typedef atomic atomic_uint_fast32_t; +typedef atomic atomic_int_fast64_t; +typedef atomic atomic_uint_fast64_t; + +typedef atomic atomic_intptr_t; +typedef atomic atomic_uintptr_t; +typedef atomic atomic_size_t; +typedef atomic atomic_ptrdiff_t; +typedef atomic atomic_intmax_t; +typedef atomic atomic_uintmax_t; + +// fences + +void atomic_thread_fence(memory_order m) noexcept; +void atomic_signal_fence(memory_order m) noexcept; + +} // std + +*/ + +#include <__config> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifdef _LIBCPP_HAS_NO_THREADS +#error is not supported on this single threaded system +#endif +#if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) +#error is not implemented +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +typedef enum memory_order +{ + memory_order_relaxed, memory_order_consume, memory_order_acquire, + memory_order_release, memory_order_acq_rel, memory_order_seq_cst +} memory_order; + +#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) +namespace __gcc_atomic { +template +struct __gcc_atomic_t { + _LIBCPP_INLINE_VISIBILITY +#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS + __gcc_atomic_t() _NOEXCEPT = default; +#else + __gcc_atomic_t() _NOEXCEPT : __a_value() {} +#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS + _LIBCPP_CONSTEXPR explicit __gcc_atomic_t(_Tp value) _NOEXCEPT + : __a_value(value) {} + _Tp __a_value; +}; +#define _Atomic(x) __gcc_atomic::__gcc_atomic_t + +template _Tp __create(); + +template +typename enable_if__a_value = __create<_Td>()), char>::type + __test_atomic_assignable(int); +template +__two __test_atomic_assignable(...); + +template +struct __can_assign { + static const bool value = + sizeof(__test_atomic_assignable<_Tp, _Td>(1)) == sizeof(char); +}; + +static inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) { + // Avoid switch statement to make this a constexpr. + return __order == memory_order_relaxed ? __ATOMIC_RELAXED: + (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: + (__order == memory_order_release ? __ATOMIC_RELEASE: + (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: + (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL: + __ATOMIC_CONSUME)))); +} + +static inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) { + // Avoid switch statement to make this a constexpr. + return __order == memory_order_relaxed ? __ATOMIC_RELAXED: + (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: + (__order == memory_order_release ? __ATOMIC_RELAXED: + (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: + (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE: + __ATOMIC_CONSUME)))); +} + +} // namespace __gcc_atomic + +template +static inline +typename enable_if< + __gcc_atomic::__can_assign::value>::type +__c11_atomic_init(volatile _Atomic(_Tp)* __a, _Tp __val) { + __a->__a_value = __val; +} + +template +static inline +typename enable_if< + !__gcc_atomic::__can_assign::value && + __gcc_atomic::__can_assign< _Atomic(_Tp)*, _Tp>::value>::type +__c11_atomic_init(volatile _Atomic(_Tp)* __a, _Tp __val) { + // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because + // the default operator= in an object is not volatile, a byte-by-byte copy + // is required. + volatile char* to = reinterpret_cast(&__a->__a_value); + volatile char* end = to + sizeof(_Tp); + char* from = reinterpret_cast(&__val); + while (to != end) { + *to++ = *from++; + } +} + +template +static inline void __c11_atomic_init(_Atomic(_Tp)* __a, _Tp __val) { + __a->__a_value = __val; +} + +static inline void __c11_atomic_thread_fence(memory_order __order) { + __atomic_thread_fence(__gcc_atomic::__to_gcc_order(__order)); +} + +static inline void __c11_atomic_signal_fence(memory_order __order) { + __atomic_signal_fence(__gcc_atomic::__to_gcc_order(__order)); +} + +template +static inline void __c11_atomic_store(volatile _Atomic(_Tp)* __a, _Tp __val, + memory_order __order) { + return __atomic_store(&__a->__a_value, &__val, + __gcc_atomic::__to_gcc_order(__order)); +} + +template +static inline void __c11_atomic_store(_Atomic(_Tp)* __a, _Tp __val, + memory_order __order) { + __atomic_store(&__a->__a_value, &__val, + __gcc_atomic::__to_gcc_order(__order)); +} + +template +static inline _Tp __c11_atomic_load(volatile _Atomic(_Tp)* __a, + memory_order __order) { + _Tp __ret; + __atomic_load(&__a->__a_value, &__ret, + __gcc_atomic::__to_gcc_order(__order)); + return __ret; +} + +template +static inline _Tp __c11_atomic_load(_Atomic(_Tp)* __a, memory_order __order) { + _Tp __ret; + __atomic_load(&__a->__a_value, &__ret, + __gcc_atomic::__to_gcc_order(__order)); + return __ret; +} + +template +static inline _Tp __c11_atomic_exchange(volatile _Atomic(_Tp)* __a, + _Tp __value, memory_order __order) { + _Tp __ret; + __atomic_exchange(&__a->__a_value, &__value, &__ret, + __gcc_atomic::__to_gcc_order(__order)); + return __ret; +} + +template +static inline _Tp __c11_atomic_exchange(_Atomic(_Tp)* __a, _Tp __value, + memory_order __order) { + _Tp __ret; + __atomic_exchange(&__a->__a_value, &__value, &__ret, + __gcc_atomic::__to_gcc_order(__order)); + return __ret; +} + +template +static inline bool __c11_atomic_compare_exchange_strong( + volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, + memory_order __success, memory_order __failure) { + return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, + false, + __gcc_atomic::__to_gcc_order(__success), + __gcc_atomic::__to_gcc_failure_order(__failure)); +} + +template +static inline bool __c11_atomic_compare_exchange_strong( + _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success, + memory_order __failure) { + return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, + false, + __gcc_atomic::__to_gcc_order(__success), + __gcc_atomic::__to_gcc_failure_order(__failure)); +} + +template +static inline bool __c11_atomic_compare_exchange_weak( + volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, + memory_order __success, memory_order __failure) { + return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, + true, + __gcc_atomic::__to_gcc_order(__success), + __gcc_atomic::__to_gcc_failure_order(__failure)); +} + +template +static inline bool __c11_atomic_compare_exchange_weak( + _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success, + memory_order __failure) { + return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, + true, + __gcc_atomic::__to_gcc_order(__success), + __gcc_atomic::__to_gcc_failure_order(__failure)); +} + +template +struct __skip_amt { enum {value = 1}; }; + +template +struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; }; + +// FIXME: Haven't figured out what the spec says about using arrays with +// atomic_fetch_add. Force a failure rather than creating bad behavior. +template +struct __skip_amt<_Tp[]> { }; +template +struct __skip_amt<_Tp[n]> { }; + +template +static inline _Tp __c11_atomic_fetch_add(volatile _Atomic(_Tp)* __a, + _Td __delta, memory_order __order) { + return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value, + __gcc_atomic::__to_gcc_order(__order)); +} + +template +static inline _Tp __c11_atomic_fetch_add(_Atomic(_Tp)* __a, _Td __delta, + memory_order __order) { + return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value, + __gcc_atomic::__to_gcc_order(__order)); +} + +template +static inline _Tp __c11_atomic_fetch_sub(volatile _Atomic(_Tp)* __a, + _Td __delta, memory_order __order) { + return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value, + __gcc_atomic::__to_gcc_order(__order)); +} + +template +static inline _Tp __c11_atomic_fetch_sub(_Atomic(_Tp)* __a, _Td __delta, + memory_order __order) { + return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value, + __gcc_atomic::__to_gcc_order(__order)); +} + +template +static inline _Tp __c11_atomic_fetch_and(volatile _Atomic(_Tp)* __a, + _Tp __pattern, memory_order __order) { + return __atomic_fetch_and(&__a->__a_value, __pattern, + __gcc_atomic::__to_gcc_order(__order)); +} + +template +static inline _Tp __c11_atomic_fetch_and(_Atomic(_Tp)* __a, + _Tp __pattern, memory_order __order) { + return __atomic_fetch_and(&__a->__a_value, __pattern, + __gcc_atomic::__to_gcc_order(__order)); +} + +template +static inline _Tp __c11_atomic_fetch_or(volatile _Atomic(_Tp)* __a, + _Tp __pattern, memory_order __order) { + return __atomic_fetch_or(&__a->__a_value, __pattern, + __gcc_atomic::__to_gcc_order(__order)); +} + +template +static inline _Tp __c11_atomic_fetch_or(_Atomic(_Tp)* __a, _Tp __pattern, + memory_order __order) { + return __atomic_fetch_or(&__a->__a_value, __pattern, + __gcc_atomic::__to_gcc_order(__order)); +} + +template +static inline _Tp __c11_atomic_fetch_xor(volatile _Atomic(_Tp)* __a, + _Tp __pattern, memory_order __order) { + return __atomic_fetch_xor(&__a->__a_value, __pattern, + __gcc_atomic::__to_gcc_order(__order)); +} + +template +static inline _Tp __c11_atomic_fetch_xor(_Atomic(_Tp)* __a, _Tp __pattern, + memory_order __order) { + return __atomic_fetch_xor(&__a->__a_value, __pattern, + __gcc_atomic::__to_gcc_order(__order)); +} +#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +kill_dependency(_Tp __y) _NOEXCEPT +{ + return __y; +} + +// general atomic + +template ::value && !is_same<_Tp, bool>::value> +struct __atomic_base // false +{ + mutable _Atomic(_Tp) __a_; + + _LIBCPP_INLINE_VISIBILITY + bool is_lock_free() const volatile _NOEXCEPT + { +#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) + return __c11_atomic_is_lock_free(sizeof(_Tp)); +#else + return __atomic_is_lock_free(sizeof(_Tp), 0); +#endif + } + _LIBCPP_INLINE_VISIBILITY + bool is_lock_free() const _NOEXCEPT + {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();} + _LIBCPP_INLINE_VISIBILITY + void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT + {__c11_atomic_store(&__a_, __d, __m);} + _LIBCPP_INLINE_VISIBILITY + void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT + {__c11_atomic_store(&__a_, __d, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT + {return __c11_atomic_load(&__a_, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT + {return __c11_atomic_load(&__a_, __m);} + _LIBCPP_INLINE_VISIBILITY + operator _Tp() const volatile _NOEXCEPT {return load();} + _LIBCPP_INLINE_VISIBILITY + operator _Tp() const _NOEXCEPT {return load();} + _LIBCPP_INLINE_VISIBILITY + _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT + {return __c11_atomic_exchange(&__a_, __d, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT + {return __c11_atomic_exchange(&__a_, __d, __m);} + _LIBCPP_INLINE_VISIBILITY + bool compare_exchange_weak(_Tp& __e, _Tp __d, + memory_order __s, memory_order __f) volatile _NOEXCEPT + {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} + _LIBCPP_INLINE_VISIBILITY + bool compare_exchange_weak(_Tp& __e, _Tp __d, + memory_order __s, memory_order __f) _NOEXCEPT + {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} + _LIBCPP_INLINE_VISIBILITY + bool compare_exchange_strong(_Tp& __e, _Tp __d, + memory_order __s, memory_order __f) volatile _NOEXCEPT + {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} + _LIBCPP_INLINE_VISIBILITY + bool compare_exchange_strong(_Tp& __e, _Tp __d, + memory_order __s, memory_order __f) _NOEXCEPT + {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} + _LIBCPP_INLINE_VISIBILITY + bool compare_exchange_weak(_Tp& __e, _Tp __d, + memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT + {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} + _LIBCPP_INLINE_VISIBILITY + bool compare_exchange_weak(_Tp& __e, _Tp __d, + memory_order __m = memory_order_seq_cst) _NOEXCEPT + {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} + _LIBCPP_INLINE_VISIBILITY + bool compare_exchange_strong(_Tp& __e, _Tp __d, + memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT + {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} + _LIBCPP_INLINE_VISIBILITY + bool compare_exchange_strong(_Tp& __e, _Tp __d, + memory_order __m = memory_order_seq_cst) _NOEXCEPT + {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} + + _LIBCPP_INLINE_VISIBILITY +#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS + __atomic_base() _NOEXCEPT = default; +#else + __atomic_base() _NOEXCEPT : __a_() {} +#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS + + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} +#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS + __atomic_base(const __atomic_base&) = delete; + __atomic_base& operator=(const __atomic_base&) = delete; + __atomic_base& operator=(const __atomic_base&) volatile = delete; +#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS +private: + __atomic_base(const __atomic_base&); + __atomic_base& operator=(const __atomic_base&); + __atomic_base& operator=(const __atomic_base&) volatile; +#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS +}; + +// atomic + +template +struct __atomic_base<_Tp, true> + : public __atomic_base<_Tp, false> +{ + typedef __atomic_base<_Tp, false> __base; + _LIBCPP_INLINE_VISIBILITY + __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} + + _LIBCPP_INLINE_VISIBILITY + _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT + {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT + {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT + {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT + {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT + {return __c11_atomic_fetch_and(&this->__a_, __op, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT + {return __c11_atomic_fetch_and(&this->__a_, __op, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT + {return __c11_atomic_fetch_or(&this->__a_, __op, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT + {return __c11_atomic_fetch_or(&this->__a_, __op, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT + {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT + {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);} + + _LIBCPP_INLINE_VISIBILITY + _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));} + _LIBCPP_INLINE_VISIBILITY + _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));} + _LIBCPP_INLINE_VISIBILITY + _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));} + _LIBCPP_INLINE_VISIBILITY + _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));} + _LIBCPP_INLINE_VISIBILITY + _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} + _LIBCPP_INLINE_VISIBILITY + _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} + _LIBCPP_INLINE_VISIBILITY + _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} + _LIBCPP_INLINE_VISIBILITY + _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} + _LIBCPP_INLINE_VISIBILITY + _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} + _LIBCPP_INLINE_VISIBILITY + _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;} + _LIBCPP_INLINE_VISIBILITY + _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} + _LIBCPP_INLINE_VISIBILITY + _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;} + _LIBCPP_INLINE_VISIBILITY + _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;} + _LIBCPP_INLINE_VISIBILITY + _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;} + _LIBCPP_INLINE_VISIBILITY + _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;} + _LIBCPP_INLINE_VISIBILITY + _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;} + _LIBCPP_INLINE_VISIBILITY + _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;} + _LIBCPP_INLINE_VISIBILITY + _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;} +}; + +// atomic + +template +struct atomic + : public __atomic_base<_Tp> +{ + typedef __atomic_base<_Tp> __base; + _LIBCPP_INLINE_VISIBILITY + atomic() _NOEXCEPT _LIBCPP_DEFAULT + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} + + _LIBCPP_INLINE_VISIBILITY + _Tp operator=(_Tp __d) volatile _NOEXCEPT + {__base::store(__d); return __d;} + _LIBCPP_INLINE_VISIBILITY + _Tp operator=(_Tp __d) _NOEXCEPT + {__base::store(__d); return __d;} +}; + +// atomic + +template +struct atomic<_Tp*> + : public __atomic_base<_Tp*> +{ + typedef __atomic_base<_Tp*> __base; + _LIBCPP_INLINE_VISIBILITY + atomic() _NOEXCEPT _LIBCPP_DEFAULT + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} + + _LIBCPP_INLINE_VISIBILITY + _Tp* operator=(_Tp* __d) volatile _NOEXCEPT + {__base::store(__d); return __d;} + _LIBCPP_INLINE_VISIBILITY + _Tp* operator=(_Tp* __d) _NOEXCEPT + {__base::store(__d); return __d;} + + _LIBCPP_INLINE_VISIBILITY + _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) + volatile _NOEXCEPT + {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT + {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) + volatile _NOEXCEPT + {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} + _LIBCPP_INLINE_VISIBILITY + _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT + {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} + + _LIBCPP_INLINE_VISIBILITY + _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} + _LIBCPP_INLINE_VISIBILITY + _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);} + _LIBCPP_INLINE_VISIBILITY + _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);} + _LIBCPP_INLINE_VISIBILITY + _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);} + _LIBCPP_INLINE_VISIBILITY + _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;} + _LIBCPP_INLINE_VISIBILITY + _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;} + _LIBCPP_INLINE_VISIBILITY + _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;} + _LIBCPP_INLINE_VISIBILITY + _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;} + _LIBCPP_INLINE_VISIBILITY + _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} + _LIBCPP_INLINE_VISIBILITY + _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;} + _LIBCPP_INLINE_VISIBILITY + _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} + _LIBCPP_INLINE_VISIBILITY + _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;} +}; + +// atomic_is_lock_free + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT +{ + return __o->is_lock_free(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT +{ + return __o->is_lock_free(); +} + +// atomic_init + +template +inline _LIBCPP_INLINE_VISIBILITY +void +atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT +{ + __c11_atomic_init(&__o->__a_, __d); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT +{ + __c11_atomic_init(&__o->__a_, __d); +} + +// atomic_store + +template +inline _LIBCPP_INLINE_VISIBILITY +void +atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT +{ + __o->store(__d); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT +{ + __o->store(__d); +} + +// atomic_store_explicit + +template +inline _LIBCPP_INLINE_VISIBILITY +void +atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT +{ + __o->store(__d, __m); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT +{ + __o->store(__d, __m); +} + +// atomic_load + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT +{ + return __o->load(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +atomic_load(const atomic<_Tp>* __o) _NOEXCEPT +{ + return __o->load(); +} + +// atomic_load_explicit + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT +{ + return __o->load(__m); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT +{ + return __o->load(__m); +} + +// atomic_exchange + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT +{ + return __o->exchange(__d); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT +{ + return __o->exchange(__d); +} + +// atomic_exchange_explicit + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT +{ + return __o->exchange(__d, __m); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT +{ + return __o->exchange(__d, __m); +} + +// atomic_compare_exchange_weak + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT +{ + return __o->compare_exchange_weak(*__e, __d); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT +{ + return __o->compare_exchange_weak(*__e, __d); +} + +// atomic_compare_exchange_strong + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT +{ + return __o->compare_exchange_strong(*__e, __d); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT +{ + return __o->compare_exchange_strong(*__e, __d); +} + +// atomic_compare_exchange_weak_explicit + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e, + _Tp __d, + memory_order __s, memory_order __f) _NOEXCEPT +{ + return __o->compare_exchange_weak(*__e, __d, __s, __f); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d, + memory_order __s, memory_order __f) _NOEXCEPT +{ + return __o->compare_exchange_weak(*__e, __d, __s, __f); +} + +// atomic_compare_exchange_strong_explicit + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, + _Tp* __e, _Tp __d, + memory_order __s, memory_order __f) _NOEXCEPT +{ + return __o->compare_exchange_strong(*__e, __d, __s, __f); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e, + _Tp __d, + memory_order __s, memory_order __f) _NOEXCEPT +{ + return __o->compare_exchange_strong(*__e, __d, __s, __f); +} + +// atomic_fetch_add + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT +{ + return __o->fetch_add(__op); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT +{ + return __o->fetch_add(__op); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp* +atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT +{ + return __o->fetch_add(__op); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp* +atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT +{ + return __o->fetch_add(__op); +} + +// atomic_fetch_add_explicit + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT +{ + return __o->fetch_add(__op, __m); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT +{ + return __o->fetch_add(__op, __m); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp* +atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, + memory_order __m) _NOEXCEPT +{ + return __o->fetch_add(__op, __m); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp* +atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT +{ + return __o->fetch_add(__op, __m); +} + +// atomic_fetch_sub + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT +{ + return __o->fetch_sub(__op); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT +{ + return __o->fetch_sub(__op); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp* +atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT +{ + return __o->fetch_sub(__op); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp* +atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT +{ + return __o->fetch_sub(__op); +} + +// atomic_fetch_sub_explicit + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT +{ + return __o->fetch_sub(__op, __m); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT +{ + return __o->fetch_sub(__op, __m); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp* +atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, + memory_order __m) _NOEXCEPT +{ + return __o->fetch_sub(__op, __m); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp* +atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT +{ + return __o->fetch_sub(__op, __m); +} + +// atomic_fetch_and + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT +{ + return __o->fetch_and(__op); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT +{ + return __o->fetch_and(__op); +} + +// atomic_fetch_and_explicit + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT +{ + return __o->fetch_and(__op, __m); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT +{ + return __o->fetch_and(__op, __m); +} + +// atomic_fetch_or + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT +{ + return __o->fetch_or(__op); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT +{ + return __o->fetch_or(__op); +} + +// atomic_fetch_or_explicit + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT +{ + return __o->fetch_or(__op, __m); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT +{ + return __o->fetch_or(__op, __m); +} + +// atomic_fetch_xor + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT +{ + return __o->fetch_xor(__op); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT +{ + return __o->fetch_xor(__op); +} + +// atomic_fetch_xor_explicit + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT +{ + return __o->fetch_xor(__op, __m); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value && !is_same<_Tp, bool>::value, + _Tp +>::type +atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT +{ + return __o->fetch_xor(__op, __m); +} + +// flag type and operations + +typedef struct atomic_flag +{ + _Atomic(bool) __a_; + + _LIBCPP_INLINE_VISIBILITY + bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT + {return __c11_atomic_exchange(&__a_, true, __m);} + _LIBCPP_INLINE_VISIBILITY + bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT + {return __c11_atomic_exchange(&__a_, true, __m);} + _LIBCPP_INLINE_VISIBILITY + void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT + {__c11_atomic_store(&__a_, false, __m);} + _LIBCPP_INLINE_VISIBILITY + void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT + {__c11_atomic_store(&__a_, false, __m);} + + _LIBCPP_INLINE_VISIBILITY +#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS + atomic_flag() _NOEXCEPT = default; +#else + atomic_flag() _NOEXCEPT : __a_() {} +#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS + + _LIBCPP_INLINE_VISIBILITY + atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} + +#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS + atomic_flag(const atomic_flag&) = delete; + atomic_flag& operator=(const atomic_flag&) = delete; + atomic_flag& operator=(const atomic_flag&) volatile = delete; +#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS +private: + atomic_flag(const atomic_flag&); + atomic_flag& operator=(const atomic_flag&); + atomic_flag& operator=(const atomic_flag&) volatile; +#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS +} atomic_flag; + +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT +{ + return __o->test_and_set(); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT +{ + return __o->test_and_set(); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT +{ + return __o->test_and_set(__m); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT +{ + return __o->test_and_set(__m); +} + +inline _LIBCPP_INLINE_VISIBILITY +void +atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT +{ + __o->clear(); +} + +inline _LIBCPP_INLINE_VISIBILITY +void +atomic_flag_clear(atomic_flag* __o) _NOEXCEPT +{ + __o->clear(); +} + +inline _LIBCPP_INLINE_VISIBILITY +void +atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT +{ + __o->clear(__m); +} + +inline _LIBCPP_INLINE_VISIBILITY +void +atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT +{ + __o->clear(__m); +} + +// fences + +inline _LIBCPP_INLINE_VISIBILITY +void +atomic_thread_fence(memory_order __m) _NOEXCEPT +{ + __c11_atomic_thread_fence(__m); +} + +inline _LIBCPP_INLINE_VISIBILITY +void +atomic_signal_fence(memory_order __m) _NOEXCEPT +{ + __c11_atomic_signal_fence(__m); +} + +// Atomics for standard typedef types + +typedef atomic atomic_bool; +typedef atomic atomic_char; +typedef atomic atomic_schar; +typedef atomic atomic_uchar; +typedef atomic atomic_short; +typedef atomic atomic_ushort; +typedef atomic atomic_int; +typedef atomic atomic_uint; +typedef atomic atomic_long; +typedef atomic atomic_ulong; +typedef atomic atomic_llong; +typedef atomic atomic_ullong; +typedef atomic atomic_char16_t; +typedef atomic atomic_char32_t; +typedef atomic atomic_wchar_t; + +typedef atomic atomic_int_least8_t; +typedef atomic atomic_uint_least8_t; +typedef atomic atomic_int_least16_t; +typedef atomic atomic_uint_least16_t; +typedef atomic atomic_int_least32_t; +typedef atomic atomic_uint_least32_t; +typedef atomic atomic_int_least64_t; +typedef atomic atomic_uint_least64_t; + +typedef atomic atomic_int_fast8_t; +typedef atomic atomic_uint_fast8_t; +typedef atomic atomic_int_fast16_t; +typedef atomic atomic_uint_fast16_t; +typedef atomic atomic_int_fast32_t; +typedef atomic atomic_uint_fast32_t; +typedef atomic atomic_int_fast64_t; +typedef atomic atomic_uint_fast64_t; + +typedef atomic atomic_intptr_t; +typedef atomic atomic_uintptr_t; +typedef atomic atomic_size_t; +typedef atomic atomic_ptrdiff_t; +typedef atomic atomic_intmax_t; +typedef atomic atomic_uintmax_t; + +#define ATOMIC_FLAG_INIT {false} +#define ATOMIC_VAR_INIT(__v) {__v} + +#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE +#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE +#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE +#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE +#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE +#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE +#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE +#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE +#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE +#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_ATOMIC diff --git a/headers/libs/libc++/atomic_support.h b/headers/libs/libc++/atomic_support.h new file mode 100644 index 0000000000..dbf3b9c81e --- /dev/null +++ b/headers/libs/libc++/atomic_support.h @@ -0,0 +1,149 @@ +#ifndef ATOMIC_SUPPORT_H +#define ATOMIC_SUPPORT_H + +#include "__config" +#include "memory" // for __libcpp_relaxed_load + +#if defined(__clang__) && __has_builtin(__atomic_load_n) \ + && __has_builtin(__atomic_store_n) \ + && __has_builtin(__atomic_add_fetch) \ + && __has_builtin(__atomic_compare_exchange_n) \ + && defined(__ATOMIC_RELAXED) \ + && defined(__ATOMIC_CONSUME) \ + && defined(__ATOMIC_ACQUIRE) \ + && defined(__ATOMIC_RELEASE) \ + && defined(__ATOMIC_ACQ_REL) \ + && defined(__ATOMIC_SEQ_CST) +# define _LIBCPP_HAS_ATOMIC_BUILTINS +#elif !defined(__clang__) && defined(_GNUC_VER) && _GNUC_VER >= 407 +# define _LIBCPP_HAS_ATOMIC_BUILTINS +#endif + +#if !defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS) +# if defined(_MSC_VER) && !defined(__clang__) + _LIBCPP_WARNING("Building libc++ without __atomic builtins is unsupported") +# else +# warning Building libc++ without __atomic builtins is unsupported +# endif +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace { + +#if defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS) + +enum __libcpp_atomic_order { + _AO_Relaxed = __ATOMIC_RELAXED, + _AO_Consume = __ATOMIC_CONSUME, + _AO_Aquire = __ATOMIC_ACQUIRE, + _AO_Release = __ATOMIC_RELEASE, + _AO_Acq_Rel = __ATOMIC_ACQ_REL, + _AO_Seq = __ATOMIC_SEQ_CST +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +void __libcpp_atomic_store(_ValueType* __dest, _FromType __val, + int __order = _AO_Seq) +{ + __atomic_store_n(__dest, __val, __order); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void __libcpp_relaxed_store(_ValueType* __dest, _FromType __val) +{ + __atomic_store_n(__dest, __val, _AO_Relaxed); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ValueType __libcpp_atomic_load(_ValueType const* __val, + int __order = _AO_Seq) +{ + return __atomic_load_n(__val, __order); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a, + int __order = _AO_Seq) +{ + return __atomic_add_fetch(__val, __a, __order); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool __libcpp_atomic_compare_exchange(_ValueType* __val, + _ValueType* __expected, _ValueType __after, + int __success_order = _AO_Seq, + int __fail_order = _AO_Seq) +{ + return __atomic_compare_exchange_n(__val, __expected, __after, true, + __success_order, __fail_order); +} + +#else // _LIBCPP_HAS_NO_THREADS + +enum __libcpp_atomic_order { + _AO_Relaxed, + _AO_Consume, + _AO_Acquire, + _AO_Release, + _AO_Acq_Rel, + _AO_Seq +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +void __libcpp_atomic_store(_ValueType* __dest, _FromType __val, + int = 0) +{ + *__dest = __val; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void __libcpp_relaxed_store(_ValueType* __dest, _FromType __val) +{ + *__dest = __val; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ValueType __libcpp_atomic_load(_ValueType const* __val, + int = 0) +{ + return *__val; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a, + int = 0) +{ + return *__val += __a; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool __libcpp_atomic_compare_exchange(_ValueType* __val, + _ValueType* __expected, _ValueType __after, + int = 0, int = 0) +{ + if (*__val == *__expected) { + *__val = __after; + return true; + } + *__expected = *__val; + return false; +} + +#endif // _LIBCPP_HAS_NO_THREADS + +} // end namespace + +_LIBCPP_END_NAMESPACE_STD + +#endif // ATOMIC_SUPPORT_H diff --git a/headers/libs/libc++/bitset b/headers/libs/libc++/bitset new file mode 100644 index 0000000000..b7d95a811f --- /dev/null +++ b/headers/libs/libc++/bitset @@ -0,0 +1,1122 @@ +// -*- C++ -*- +//===---------------------------- bitset ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_BITSET +#define _LIBCPP_BITSET + +/* + bitset synopsis + +namespace std +{ + +namespace std { + +template +class bitset +{ +public: + // bit reference: + class reference + { + friend class bitset; + reference() noexcept; + public: + ~reference() noexcept; + reference& operator=(bool x) noexcept; // for b[i] = x; + reference& operator=(const reference&) noexcept; // for b[i] = b[j]; + bool operator~() const noexcept; // flips the bit + operator bool() const noexcept; // for x = b[i]; + reference& flip() noexcept; // for b[i].flip(); + }; + + // 23.3.5.1 constructors: + constexpr bitset() noexcept; + constexpr bitset(unsigned long long val) noexcept; + template + explicit bitset(const charT* str, + typename basic_string::size_type n = basic_string::npos, + charT zero = charT('0'), charT one = charT('1')); + template + explicit bitset(const basic_string& str, + typename basic_string::size_type pos = 0, + typename basic_string::size_type n = + basic_string::npos, + charT zero = charT('0'), charT one = charT('1')); + + // 23.3.5.2 bitset operations: + bitset& operator&=(const bitset& rhs) noexcept; + bitset& operator|=(const bitset& rhs) noexcept; + bitset& operator^=(const bitset& rhs) noexcept; + bitset& operator<<=(size_t pos) noexcept; + bitset& operator>>=(size_t pos) noexcept; + bitset& set() noexcept; + bitset& set(size_t pos, bool val = true); + bitset& reset() noexcept; + bitset& reset(size_t pos); + bitset operator~() const noexcept; + bitset& flip() noexcept; + bitset& flip(size_t pos); + + // element access: + constexpr bool operator[](size_t pos) const; // for b[i]; + reference operator[](size_t pos); // for b[i]; + unsigned long to_ulong() const; + unsigned long long to_ullong() const; + template + basic_string to_string(charT zero = charT('0'), charT one = charT('1')) const; + template + basic_string > to_string(charT zero = charT('0'), charT one = charT('1')) const; + template + basic_string, allocator > to_string(charT zero = charT('0'), charT one = charT('1')) const; + basic_string, allocator > to_string(char zero = '0', char one = '1') const; + size_t count() const noexcept; + constexpr size_t size() const noexcept; + bool operator==(const bitset& rhs) const noexcept; + bool operator!=(const bitset& rhs) const noexcept; + bool test(size_t pos) const; + bool all() const noexcept; + bool any() const noexcept; + bool none() const noexcept; + bitset operator<<(size_t pos) const noexcept; + bitset operator>>(size_t pos) const noexcept; +}; + +// 23.3.5.3 bitset operators: +template +bitset operator&(const bitset&, const bitset&) noexcept; + +template +bitset operator|(const bitset&, const bitset&) noexcept; + +template +bitset operator^(const bitset&, const bitset&) noexcept; + +template +basic_istream& +operator>>(basic_istream& is, bitset& x); + +template +basic_ostream& +operator<<(basic_ostream& os, const bitset& x); + +template struct hash>; + +} // std + +*/ + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#include <__config> +#include <__bit_reference> +#include +#include +#include +#include +#include +#include <__functional_base> +#if defined(_LIBCPP_NO_EXCEPTIONS) + #include +#endif + +#include <__undef_min_max> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class __bitset; + +template +struct __has_storage_type<__bitset<_N_words, _Size> > +{ + static const bool value = true; +}; + +template +class __bitset +{ +public: + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef size_type __storage_type; +protected: + typedef __bitset __self; + typedef __storage_type* __storage_pointer; + typedef const __storage_type* __const_storage_pointer; + static const unsigned __bits_per_word = static_cast(sizeof(__storage_type) * CHAR_BIT); + + friend class __bit_reference<__bitset>; + friend class __bit_const_reference<__bitset>; + friend class __bit_iterator<__bitset, false>; + friend class __bit_iterator<__bitset, true>; + friend struct __bit_array<__bitset>; + + __storage_type __first_[_N_words]; + + typedef __bit_reference<__bitset> reference; + typedef __bit_const_reference<__bitset> const_reference; + typedef __bit_iterator<__bitset, false> iterator; + typedef __bit_iterator<__bitset, true> const_iterator; + + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t __pos) _NOEXCEPT + {return reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t __pos) const _NOEXCEPT + {return const_reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} + _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t __pos) _NOEXCEPT + {return iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);} + _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t __pos) const _NOEXCEPT + {return const_iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);} + + _LIBCPP_INLINE_VISIBILITY + void operator&=(const __bitset& __v) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + void operator|=(const __bitset& __v) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + void operator^=(const __bitset& __v) _NOEXCEPT; + + void flip() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY unsigned long to_ulong() const + {return to_ulong(integral_constant());} + _LIBCPP_INLINE_VISIBILITY unsigned long long to_ullong() const + {return to_ullong(integral_constant());} + + bool all() const _NOEXCEPT; + bool any() const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_t __hash_code() const _NOEXCEPT; +private: +#ifdef _LIBCPP_HAS_NO_CONSTEXPR + void __init(unsigned long long __v, false_type) _NOEXCEPT; + void __init(unsigned long long __v, true_type) _NOEXCEPT; +#endif // _LIBCPP_HAS_NO_CONSTEXPR + unsigned long to_ulong(false_type) const; + _LIBCPP_INLINE_VISIBILITY + unsigned long to_ulong(true_type) const; + unsigned long long to_ullong(false_type) const; + _LIBCPP_INLINE_VISIBILITY + unsigned long long to_ullong(true_type) const; + _LIBCPP_INLINE_VISIBILITY + unsigned long long to_ullong(true_type, false_type) const; + unsigned long long to_ullong(true_type, true_type) const; +}; + +template +inline +_LIBCPP_CONSTEXPR +__bitset<_N_words, _Size>::__bitset() _NOEXCEPT +#ifndef _LIBCPP_HAS_NO_CONSTEXPR + : __first_{0} +#endif +{ +#ifdef _LIBCPP_HAS_NO_CONSTEXPR + _VSTD::fill_n(__first_, _N_words, __storage_type(0)); +#endif +} + +#ifdef _LIBCPP_HAS_NO_CONSTEXPR + +template +void +__bitset<_N_words, _Size>::__init(unsigned long long __v, false_type) _NOEXCEPT +{ + __storage_type __t[sizeof(unsigned long long) / sizeof(__storage_type)]; + for (size_t __i = 0; __i < sizeof(__t)/sizeof(__t[0]); ++__i, __v >>= __bits_per_word) + __t[__i] = static_cast<__storage_type>(__v); + _VSTD::copy(__t, __t + sizeof(__t)/sizeof(__t[0]), __first_); + _VSTD::fill(__first_ + sizeof(__t)/sizeof(__t[0]), __first_ + sizeof(__first_)/sizeof(__first_[0]), + __storage_type(0)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +__bitset<_N_words, _Size>::__init(unsigned long long __v, true_type) _NOEXCEPT +{ + __first_[0] = __v; + _VSTD::fill(__first_ + 1, __first_ + sizeof(__first_)/sizeof(__first_[0]), __storage_type(0)); +} + +#endif // _LIBCPP_HAS_NO_CONSTEXPR + +template +inline +_LIBCPP_CONSTEXPR +__bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT +#ifndef _LIBCPP_HAS_NO_CONSTEXPR +#if __SIZEOF_SIZE_T__ == 8 + : __first_{__v} +#elif __SIZEOF_SIZE_T__ == 4 + : __first_{__v, __v >> __bits_per_word} +#else +#error This constructor has not been ported to this platform +#endif +#endif +{ +#ifdef _LIBCPP_HAS_NO_CONSTEXPR + __init(__v, integral_constant()); +#endif +} + +template +inline +void +__bitset<_N_words, _Size>::operator&=(const __bitset& __v) _NOEXCEPT +{ + for (size_type __i = 0; __i < _N_words; ++__i) + __first_[__i] &= __v.__first_[__i]; +} + +template +inline +void +__bitset<_N_words, _Size>::operator|=(const __bitset& __v) _NOEXCEPT +{ + for (size_type __i = 0; __i < _N_words; ++__i) + __first_[__i] |= __v.__first_[__i]; +} + +template +inline +void +__bitset<_N_words, _Size>::operator^=(const __bitset& __v) _NOEXCEPT +{ + for (size_type __i = 0; __i < _N_words; ++__i) + __first_[__i] ^= __v.__first_[__i]; +} + +template +void +__bitset<_N_words, _Size>::flip() _NOEXCEPT +{ + // do middle whole words + size_type __n = _Size; + __storage_pointer __p = __first_; + for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word) + *__p = ~*__p; + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__p & __m; + *__p &= ~__m; + *__p |= ~__b & __m; + } +} + +template +unsigned long +__bitset<_N_words, _Size>::to_ulong(false_type) const +{ + const_iterator __e = __make_iter(_Size); + const_iterator __i = _VSTD::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true); + if (__i != __e) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw overflow_error("bitset to_ulong overflow error"); +#else + assert(!"bitset to_ulong overflow error"); +#endif + return __first_[0]; +} + +template +inline +unsigned long +__bitset<_N_words, _Size>::to_ulong(true_type) const +{ + return __first_[0]; +} + +template +unsigned long long +__bitset<_N_words, _Size>::to_ullong(false_type) const +{ + const_iterator __e = __make_iter(_Size); + const_iterator __i = _VSTD::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true); + if (__i != __e) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw overflow_error("bitset to_ullong overflow error"); +#else + assert(!"bitset to_ullong overflow error"); +#endif + return to_ullong(true_type()); +} + +template +inline +unsigned long long +__bitset<_N_words, _Size>::to_ullong(true_type) const +{ + return to_ullong(true_type(), integral_constant()); +} + +template +inline +unsigned long long +__bitset<_N_words, _Size>::to_ullong(true_type, false_type) const +{ + return __first_[0]; +} + +template +unsigned long long +__bitset<_N_words, _Size>::to_ullong(true_type, true_type) const +{ + unsigned long long __r = __first_[0]; + for (std::size_t __i = 1; __i < sizeof(unsigned long long) / sizeof(__storage_type); ++__i) + __r |= static_cast(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT); + return __r; +} + +template +bool +__bitset<_N_words, _Size>::all() const _NOEXCEPT +{ + // do middle whole words + size_type __n = _Size; + __const_storage_pointer __p = __first_; + for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word) + if (~*__p) + return false; + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + if (~*__p & __m) + return false; + } + return true; +} + +template +bool +__bitset<_N_words, _Size>::any() const _NOEXCEPT +{ + // do middle whole words + size_type __n = _Size; + __const_storage_pointer __p = __first_; + for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word) + if (*__p) + return true; + // do last partial word + if (__n > 0) + { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + if (*__p & __m) + return true; + } + return false; +} + +template +inline +size_t +__bitset<_N_words, _Size>::__hash_code() const _NOEXCEPT +{ + size_t __h = 0; + for (size_type __i = 0; __i < _N_words; ++__i) + __h ^= __first_[__i]; + return __h; +} + +template +class __bitset<1, _Size> +{ +public: + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef size_type __storage_type; +protected: + typedef __bitset __self; + typedef __storage_type* __storage_pointer; + typedef const __storage_type* __const_storage_pointer; + static const unsigned __bits_per_word = static_cast(sizeof(__storage_type) * CHAR_BIT); + + friend class __bit_reference<__bitset>; + friend class __bit_const_reference<__bitset>; + friend class __bit_iterator<__bitset, false>; + friend class __bit_iterator<__bitset, true>; + friend struct __bit_array<__bitset>; + + __storage_type __first_; + + typedef __bit_reference<__bitset> reference; + typedef __bit_const_reference<__bitset> const_reference; + typedef __bit_iterator<__bitset, false> iterator; + typedef __bit_iterator<__bitset, true> const_iterator; + + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t __pos) _NOEXCEPT + {return reference(&__first_, __storage_type(1) << __pos);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t __pos) const _NOEXCEPT + {return const_reference(&__first_, __storage_type(1) << __pos);} + _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t __pos) _NOEXCEPT + {return iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);} + _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t __pos) const _NOEXCEPT + {return const_iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);} + + _LIBCPP_INLINE_VISIBILITY + void operator&=(const __bitset& __v) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + void operator|=(const __bitset& __v) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + void operator^=(const __bitset& __v) _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + void flip() _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + unsigned long to_ulong() const; + _LIBCPP_INLINE_VISIBILITY + unsigned long long to_ullong() const; + + _LIBCPP_INLINE_VISIBILITY + bool all() const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + bool any() const _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + size_t __hash_code() const _NOEXCEPT; +}; + +template +inline +_LIBCPP_CONSTEXPR +__bitset<1, _Size>::__bitset() _NOEXCEPT + : __first_(0) +{ +} + +template +inline +_LIBCPP_CONSTEXPR +__bitset<1, _Size>::__bitset(unsigned long long __v) _NOEXCEPT + : __first_(static_cast<__storage_type>(__v)) +{ +} + +template +inline +void +__bitset<1, _Size>::operator&=(const __bitset& __v) _NOEXCEPT +{ + __first_ &= __v.__first_; +} + +template +inline +void +__bitset<1, _Size>::operator|=(const __bitset& __v) _NOEXCEPT +{ + __first_ |= __v.__first_; +} + +template +inline +void +__bitset<1, _Size>::operator^=(const __bitset& __v) _NOEXCEPT +{ + __first_ ^= __v.__first_; +} + +template +inline +void +__bitset<1, _Size>::flip() _NOEXCEPT +{ + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size); + __first_ = ~__first_; + __first_ &= __m; +} + +template +inline +unsigned long +__bitset<1, _Size>::to_ulong() const +{ + return __first_; +} + +template +inline +unsigned long long +__bitset<1, _Size>::to_ullong() const +{ + return __first_; +} + +template +inline +bool +__bitset<1, _Size>::all() const _NOEXCEPT +{ + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size); + return !(~__first_ & __m); +} + +template +inline +bool +__bitset<1, _Size>::any() const _NOEXCEPT +{ + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size); + return __first_ & __m; +} + +template +inline +size_t +__bitset<1, _Size>::__hash_code() const _NOEXCEPT +{ + return __first_; +} + +template <> +class __bitset<0, 0> +{ +public: + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef size_type __storage_type; +protected: + typedef __bitset __self; + typedef __storage_type* __storage_pointer; + typedef const __storage_type* __const_storage_pointer; + static const unsigned __bits_per_word = static_cast(sizeof(__storage_type) * CHAR_BIT); + + friend class __bit_reference<__bitset>; + friend class __bit_const_reference<__bitset>; + friend class __bit_iterator<__bitset, false>; + friend class __bit_iterator<__bitset, true>; + friend struct __bit_array<__bitset>; + + typedef __bit_reference<__bitset> reference; + typedef __bit_const_reference<__bitset> const_reference; + typedef __bit_iterator<__bitset, false> iterator; + typedef __bit_iterator<__bitset, true> const_iterator; + + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long) _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t) _NOEXCEPT + {return reference(0, 1);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t) const _NOEXCEPT + {return const_reference(0, 1);} + _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t) _NOEXCEPT + {return iterator(0, 0);} + _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t) const _NOEXCEPT + {return const_iterator(0, 0);} + + _LIBCPP_INLINE_VISIBILITY void operator&=(const __bitset&) _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY void operator|=(const __bitset&) _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY void operator^=(const __bitset&) _NOEXCEPT {} + + _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {} + + _LIBCPP_INLINE_VISIBILITY unsigned long to_ulong() const {return 0;} + _LIBCPP_INLINE_VISIBILITY unsigned long long to_ullong() const {return 0;} + + _LIBCPP_INLINE_VISIBILITY bool all() const _NOEXCEPT {return true;} + _LIBCPP_INLINE_VISIBILITY bool any() const _NOEXCEPT {return false;} + + _LIBCPP_INLINE_VISIBILITY size_t __hash_code() const _NOEXCEPT {return 0;} +}; + +inline +_LIBCPP_CONSTEXPR +__bitset<0, 0>::__bitset() _NOEXCEPT +{ +} + +inline +_LIBCPP_CONSTEXPR +__bitset<0, 0>::__bitset(unsigned long long) _NOEXCEPT +{ +} + +template class _LIBCPP_TYPE_VIS_ONLY bitset; +template struct _LIBCPP_TYPE_VIS_ONLY hash >; + +template +class _LIBCPP_TYPE_VIS_ONLY bitset + : private __bitset<_Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) * CHAR_BIT) + 1, _Size> +{ +public: + static const unsigned __n_words = _Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) * CHAR_BIT) + 1; + typedef __bitset<__n_words, _Size> base; + +public: + typedef typename base::reference reference; + typedef typename base::const_reference const_reference; + + // 23.3.5.1 constructors: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bitset(unsigned long long __v) _NOEXCEPT : base(__v) {} + template + explicit bitset(const _CharT* __str, + typename basic_string<_CharT>::size_type __n = basic_string<_CharT>::npos, + _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')); + template + explicit bitset(const basic_string<_CharT,_Traits,_Allocator>& __str, + typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos = 0, + typename basic_string<_CharT,_Traits,_Allocator>::size_type __n = + (basic_string<_CharT,_Traits,_Allocator>::npos), + _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')); + + // 23.3.5.2 bitset operations: + _LIBCPP_INLINE_VISIBILITY + bitset& operator&=(const bitset& __rhs) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + bitset& operator|=(const bitset& __rhs) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + bitset& operator^=(const bitset& __rhs) _NOEXCEPT; + bitset& operator<<=(size_t __pos) _NOEXCEPT; + bitset& operator>>=(size_t __pos) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + bitset& set() _NOEXCEPT; + bitset& set(size_t __pos, bool __val = true); + _LIBCPP_INLINE_VISIBILITY + bitset& reset() _NOEXCEPT; + bitset& reset(size_t __pos); + _LIBCPP_INLINE_VISIBILITY + bitset operator~() const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + bitset& flip() _NOEXCEPT; + bitset& flip(size_t __pos); + + // element access: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + const_reference operator[](size_t __p) const {return base::__make_ref(__p);} + _LIBCPP_INLINE_VISIBILITY reference operator[](size_t __p) {return base::__make_ref(__p);} + _LIBCPP_INLINE_VISIBILITY + unsigned long to_ulong() const; + _LIBCPP_INLINE_VISIBILITY + unsigned long long to_ullong() const; + template + basic_string<_CharT, _Traits, _Allocator> to_string(_CharT __zero = _CharT('0'), + _CharT __one = _CharT('1')) const; + template + _LIBCPP_INLINE_VISIBILITY + basic_string<_CharT, _Traits, allocator<_CharT> > to_string(_CharT __zero = _CharT('0'), + _CharT __one = _CharT('1')) const; + template + _LIBCPP_INLINE_VISIBILITY + basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> > to_string(_CharT __zero = _CharT('0'), + _CharT __one = _CharT('1')) const; + _LIBCPP_INLINE_VISIBILITY + basic_string, allocator > to_string(char __zero = '0', + char __one = '1') const; + _LIBCPP_INLINE_VISIBILITY + size_t count() const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT {return _Size;} + _LIBCPP_INLINE_VISIBILITY + bool operator==(const bitset& __rhs) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + bool operator!=(const bitset& __rhs) const _NOEXCEPT; + bool test(size_t __pos) const; + _LIBCPP_INLINE_VISIBILITY + bool all() const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + bool any() const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY bool none() const _NOEXCEPT {return !any();} + _LIBCPP_INLINE_VISIBILITY + bitset operator<<(size_t __pos) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + bitset operator>>(size_t __pos) const _NOEXCEPT; + +private: + + _LIBCPP_INLINE_VISIBILITY + size_t __hash_code() const _NOEXCEPT {return base::__hash_code();} + + friend struct hash; +}; + +template +template +bitset<_Size>::bitset(const _CharT* __str, + typename basic_string<_CharT>::size_type __n, + _CharT __zero, _CharT __one) +{ + size_t __rlen = _VSTD::min(__n, char_traits<_CharT>::length(__str)); + for (size_t __i = 0; __i < __rlen; ++__i) + if (__str[__i] != __zero && __str[__i] != __one) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw invalid_argument("bitset string ctor has invalid argument"); +#else + assert(!"bitset string ctor has invalid argument"); +#endif + size_t _Mp = _VSTD::min(__rlen, _Size); + size_t __i = 0; + for (; __i < _Mp; ++__i) + { + _CharT __c = __str[_Mp - 1 - __i]; + if (__c == __zero) + (*this)[__i] = false; + else + (*this)[__i] = true; + } + _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false); +} + +template +template +bitset<_Size>::bitset(const basic_string<_CharT,_Traits,_Allocator>& __str, + typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos, + typename basic_string<_CharT,_Traits,_Allocator>::size_type __n, + _CharT __zero, _CharT __one) +{ + if (__pos > __str.size()) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw out_of_range("bitset string pos out of range"); +#else + assert(!"bitset string pos out of range"); +#endif + size_t __rlen = _VSTD::min(__n, __str.size() - __pos); + for (size_t __i = __pos; __i < __pos + __rlen; ++__i) + if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one)) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw invalid_argument("bitset string ctor has invalid argument"); +#else + assert(!"bitset string ctor has invalid argument"); +#endif + size_t _Mp = _VSTD::min(__rlen, _Size); + size_t __i = 0; + for (; __i < _Mp; ++__i) + { + _CharT __c = __str[__pos + _Mp - 1 - __i]; + if (_Traits::eq(__c, __zero)) + (*this)[__i] = false; + else + (*this)[__i] = true; + } + _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false); +} + +template +inline +bitset<_Size>& +bitset<_Size>::operator&=(const bitset& __rhs) _NOEXCEPT +{ + base::operator&=(__rhs); + return *this; +} + +template +inline +bitset<_Size>& +bitset<_Size>::operator|=(const bitset& __rhs) _NOEXCEPT +{ + base::operator|=(__rhs); + return *this; +} + +template +inline +bitset<_Size>& +bitset<_Size>::operator^=(const bitset& __rhs) _NOEXCEPT +{ + base::operator^=(__rhs); + return *this; +} + +template +bitset<_Size>& +bitset<_Size>::operator<<=(size_t __pos) _NOEXCEPT +{ + __pos = _VSTD::min(__pos, _Size); + _VSTD::copy_backward(base::__make_iter(0), base::__make_iter(_Size - __pos), base::__make_iter(_Size)); + _VSTD::fill_n(base::__make_iter(0), __pos, false); + return *this; +} + +template +bitset<_Size>& +bitset<_Size>::operator>>=(size_t __pos) _NOEXCEPT +{ + __pos = _VSTD::min(__pos, _Size); + _VSTD::copy(base::__make_iter(__pos), base::__make_iter(_Size), base::__make_iter(0)); + _VSTD::fill_n(base::__make_iter(_Size - __pos), __pos, false); + return *this; +} + +template +inline +bitset<_Size>& +bitset<_Size>::set() _NOEXCEPT +{ + _VSTD::fill_n(base::__make_iter(0), _Size, true); + return *this; +} + +template +bitset<_Size>& +bitset<_Size>::set(size_t __pos, bool __val) +{ + if (__pos >= _Size) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw out_of_range("bitset set argument out of range"); +#else + assert(!"bitset set argument out of range"); +#endif + (*this)[__pos] = __val; + return *this; +} + +template +inline +bitset<_Size>& +bitset<_Size>::reset() _NOEXCEPT +{ + _VSTD::fill_n(base::__make_iter(0), _Size, false); + return *this; +} + +template +bitset<_Size>& +bitset<_Size>::reset(size_t __pos) +{ + if (__pos >= _Size) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw out_of_range("bitset reset argument out of range"); +#else + assert(!"bitset reset argument out of range"); +#endif + (*this)[__pos] = false; + return *this; +} + +template +inline +bitset<_Size> +bitset<_Size>::operator~() const _NOEXCEPT +{ + bitset __x(*this); + __x.flip(); + return __x; +} + +template +inline +bitset<_Size>& +bitset<_Size>::flip() _NOEXCEPT +{ + base::flip(); + return *this; +} + +template +bitset<_Size>& +bitset<_Size>::flip(size_t __pos) +{ + if (__pos >= _Size) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw out_of_range("bitset flip argument out of range"); +#else + assert(!"bitset flip argument out of range"); +#endif + reference r = base::__make_ref(__pos); + r = ~r; + return *this; +} + +template +inline +unsigned long +bitset<_Size>::to_ulong() const +{ + return base::to_ulong(); +} + +template +inline +unsigned long long +bitset<_Size>::to_ullong() const +{ + return base::to_ullong(); +} + +template +template +basic_string<_CharT, _Traits, _Allocator> +bitset<_Size>::to_string(_CharT __zero, _CharT __one) const +{ + basic_string<_CharT, _Traits, _Allocator> __r(_Size, __zero); + for (size_t __i = 0; __i < _Size; ++__i) + { + if ((*this)[__i]) + __r[_Size - 1 - __i] = __one; + } + return __r; +} + +template +template +inline +basic_string<_CharT, _Traits, allocator<_CharT> > +bitset<_Size>::to_string(_CharT __zero, _CharT __one) const +{ + return to_string<_CharT, _Traits, allocator<_CharT> >(__zero, __one); +} + +template +template +inline +basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> > +bitset<_Size>::to_string(_CharT __zero, _CharT __one) const +{ + return to_string<_CharT, char_traits<_CharT>, allocator<_CharT> >(__zero, __one); +} + +template +inline +basic_string, allocator > +bitset<_Size>::to_string(char __zero, char __one) const +{ + return to_string, allocator >(__zero, __one); +} + +template +inline +size_t +bitset<_Size>::count() const _NOEXCEPT +{ + return static_cast(_VSTD::count(base::__make_iter(0), base::__make_iter(_Size), true)); +} + +template +inline +bool +bitset<_Size>::operator==(const bitset& __rhs) const _NOEXCEPT +{ + return _VSTD::equal(base::__make_iter(0), base::__make_iter(_Size), __rhs.__make_iter(0)); +} + +template +inline +bool +bitset<_Size>::operator!=(const bitset& __rhs) const _NOEXCEPT +{ + return !(*this == __rhs); +} + +template +bool +bitset<_Size>::test(size_t __pos) const +{ + if (__pos >= _Size) +#ifndef _LIBCPP_NO_EXCEPTIONS + throw out_of_range("bitset test argument out of range"); +#else + assert(!"bitset test argument out of range"); +#endif + return (*this)[__pos]; +} + +template +inline +bool +bitset<_Size>::all() const _NOEXCEPT +{ + return base::all(); +} + +template +inline +bool +bitset<_Size>::any() const _NOEXCEPT +{ + return base::any(); +} + +template +inline +bitset<_Size> +bitset<_Size>::operator<<(size_t __pos) const _NOEXCEPT +{ + bitset __r = *this; + __r <<= __pos; + return __r; +} + +template +inline +bitset<_Size> +bitset<_Size>::operator>>(size_t __pos) const _NOEXCEPT +{ + bitset __r = *this; + __r >>= __pos; + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bitset<_Size> +operator&(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT +{ + bitset<_Size> __r = __x; + __r &= __y; + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bitset<_Size> +operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT +{ + bitset<_Size> __r = __x; + __r |= __y; + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bitset<_Size> +operator^(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT +{ + bitset<_Size> __r = __x; + __r ^= __y; + return __r; +} + +template +struct _LIBCPP_TYPE_VIS_ONLY hash > + : public unary_function, size_t> +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(const bitset<_Size>& __bs) const _NOEXCEPT + {return __bs.__hash_code();} +}; + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x); + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x); + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_BITSET diff --git a/headers/libs/libc++/cassert b/headers/libs/libc++/cassert new file mode 100644 index 0000000000..3775990640 --- /dev/null +++ b/headers/libs/libc++/cassert @@ -0,0 +1,25 @@ +// -*- C++ -*- +//===-------------------------- cassert -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +/* + cassert synopsis + +Macros: + + assert + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif diff --git a/headers/libs/libc++/ccomplex b/headers/libs/libc++/ccomplex new file mode 100644 index 0000000000..6ed116445e --- /dev/null +++ b/headers/libs/libc++/ccomplex @@ -0,0 +1,29 @@ +// -*- C++ -*- +//===--------------------------- ccomplex ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CCOMPLEX +#define _LIBCPP_CCOMPLEX + +/* + ccomplex synopsis + +#include + +*/ + +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +// hh 080623 Created + +#endif // _LIBCPP_CCOMPLEX diff --git a/headers/libs/libc++/cctype b/headers/libs/libc++/cctype new file mode 100644 index 0000000000..a68c2a0660 --- /dev/null +++ b/headers/libs/libc++/cctype @@ -0,0 +1,64 @@ +// -*- C++ -*- +//===---------------------------- cctype ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CCTYPE +#define _LIBCPP_CCTYPE + +/* + cctype synopsis + +namespace std +{ + +int isalnum(int c); +int isalpha(int c); +int isblank(int c); // C99 +int iscntrl(int c); +int isdigit(int c); +int isgraph(int c); +int islower(int c); +int isprint(int c); +int ispunct(int c); +int isspace(int c); +int isupper(int c); +int isxdigit(int c); +int tolower(int c); +int toupper(int c); + +} // std +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::isalnum; +using ::isalpha; +using ::isblank; +using ::iscntrl; +using ::isdigit; +using ::isgraph; +using ::islower; +using ::isprint; +using ::ispunct; +using ::isspace; +using ::isupper; +using ::isxdigit; +using ::tolower; +using ::toupper; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CCTYPE diff --git a/headers/libs/libc++/cerrno b/headers/libs/libc++/cerrno new file mode 100644 index 0000000000..bab13b8aa8 --- /dev/null +++ b/headers/libs/libc++/cerrno @@ -0,0 +1,33 @@ +// -*- C++ -*- +//===-------------------------- cerrno ------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CERRNO +#define _LIBCPP_CERRNO + +/* + cerrno synopsis + +Macros: + + EDOM + EILSEQ // C99 + ERANGE + errno + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#endif // _LIBCPP_CERRNO diff --git a/headers/libs/libc++/cfenv b/headers/libs/libc++/cfenv new file mode 100644 index 0000000000..4fc630419b --- /dev/null +++ b/headers/libs/libc++/cfenv @@ -0,0 +1,82 @@ +// -*- C++ -*- +//===---------------------------- cfenv -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CFENV +#define _LIBCPP_CFENV + +/* + cfenv synopsis + +This entire header is C99 / C++0X + +Macros: + + FE_DIVBYZERO + FE_INEXACT + FE_INVALID + FE_OVERFLOW + FE_UNDERFLOW + FE_ALL_EXCEPT + FE_DOWNWARD + FE_TONEAREST + FE_TOWARDZERO + FE_UPWARD + FE_DFL_ENV + +namespace std +{ + +Types: + + fenv_t + fexcept_t + +int feclearexcept(int excepts); +int fegetexceptflag(fexcept_t* flagp, int excepts); +int feraiseexcept(int excepts); +int fesetexceptflag(const fexcept_t* flagp, int excepts); +int fetestexcept(int excepts); +int fegetround(); +int fesetround(int round); +int fegetenv(fenv_t* envp); +int feholdexcept(fenv_t* envp); +int fesetenv(const fenv_t* envp); +int feupdateenv(const fenv_t* envp); + +} // std +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::fenv_t; +using ::fexcept_t; + +using ::feclearexcept; +using ::fegetexceptflag; +using ::feraiseexcept; +using ::fesetexceptflag; +using ::fetestexcept; +using ::fegetround; +using ::fesetround; +using ::fegetenv; +using ::feholdexcept; +using ::fesetenv; +using ::feupdateenv; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CFENV diff --git a/headers/libs/libc++/cfloat b/headers/libs/libc++/cfloat new file mode 100644 index 0000000000..176fa9de3c --- /dev/null +++ b/headers/libs/libc++/cfloat @@ -0,0 +1,70 @@ +// -*- C++ -*- +//===--------------------------- cfloat -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CFLOAT +#define _LIBCPP_CFLOAT + +/* + cfloat synopsis + +Macros: + + FLT_ROUNDS + FLT_EVAL_METHOD // C99 + FLT_RADIX + + FLT_MANT_DIG + DBL_MANT_DIG + LDBL_MANT_DIG + + DECIMAL_DIG // C99 + + FLT_DIG + DBL_DIG + LDBL_DIG + + FLT_MIN_EXP + DBL_MIN_EXP + LDBL_MIN_EXP + + FLT_MIN_10_EXP + DBL_MIN_10_EXP + LDBL_MIN_10_EXP + + FLT_MAX_EXP + DBL_MAX_EXP + LDBL_MAX_EXP + + FLT_MAX_10_EXP + DBL_MAX_10_EXP + LDBL_MAX_10_EXP + + FLT_MAX + DBL_MAX + LDBL_MAX + + FLT_EPSILON + DBL_EPSILON + LDBL_EPSILON + + FLT_MIN + DBL_MIN + LDBL_MIN + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#endif // _LIBCPP_CFLOAT diff --git a/headers/libs/libc++/chrono b/headers/libs/libc++/chrono new file mode 100644 index 0000000000..aac05870f5 --- /dev/null +++ b/headers/libs/libc++/chrono @@ -0,0 +1,1154 @@ +// -*- C++ -*- +//===---------------------------- chrono ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CHRONO +#define _LIBCPP_CHRONO + +/* + chrono synopsis + +namespace std +{ +namespace chrono +{ + +template +constexpr +ToDuration +duration_cast(const duration& fd); + +template struct treat_as_floating_point : is_floating_point {}; + +template +struct duration_values +{ +public: + static constexpr Rep zero(); + static constexpr Rep max(); + static constexpr Rep min(); +}; + +// duration + +template > +class duration +{ + static_assert(!__is_duration::value, "A duration representation can not be a duration"); + static_assert(__is_ratio::value, "Second template parameter of duration must be a std::ratio"); + static_assert(Period::num > 0, "duration period must be positive"); +public: + typedef Rep rep; + typedef Period period; + + constexpr duration() = default; + template + constexpr explicit duration(const Rep2& r, + typename enable_if + < + is_convertible::value && + (treat_as_floating_point::value || + !treat_as_floating_point::value && !treat_as_floating_point::value) + >::type* = 0); + + // conversions + template + constexpr duration(const duration& d, + typename enable_if + < + treat_as_floating_point::value || + ratio_divide::type::den == 1 + >::type* = 0); + + // observer + + constexpr rep count() const; + + // arithmetic + + constexpr duration operator+() const; + constexpr duration operator-() const; + duration& operator++(); + duration operator++(int); + duration& operator--(); + duration operator--(int); + + duration& operator+=(const duration& d); + duration& operator-=(const duration& d); + + duration& operator*=(const rep& rhs); + duration& operator/=(const rep& rhs); + + // special values + + static constexpr duration zero(); + static constexpr duration min(); + static constexpr duration max(); +}; + +typedef duration nanoseconds; +typedef duration microseconds; +typedef duration milliseconds; +typedef duration seconds; +typedef duration< long, ratio< 60> > minutes; +typedef duration< long, ratio<3600> > hours; + +template +class time_point +{ +public: + typedef Clock clock; + typedef Duration duration; + typedef typename duration::rep rep; + typedef typename duration::period period; +private: + duration d_; // exposition only + +public: + time_point(); // has value "epoch" // constexpr in C++14 + explicit time_point(const duration& d); // same as time_point() + d // constexpr in C++14 + + // conversions + template + time_point(const time_point& t); // constexpr in C++14 + + // observer + + duration time_since_epoch() const; // constexpr in C++14 + + // arithmetic + + time_point& operator+=(const duration& d); + time_point& operator-=(const duration& d); + + // special values + + static constexpr time_point min(); + static constexpr time_point max(); +}; + +} // chrono + +// common_type traits +template + struct common_type, chrono::duration>; + +template + struct common_type, chrono::time_point>; + +namespace chrono { + +// duration arithmetic +template + constexpr + typename common_type, duration>::type + operator+(const duration& lhs, const duration& rhs); +template + constexpr + typename common_type, duration>::type + operator-(const duration& lhs, const duration& rhs); +template + constexpr + duration::type, Period> + operator*(const duration& d, const Rep2& s); +template + constexpr + duration::type, Period> + operator*(const Rep1& s, const duration& d); +template + constexpr + duration::type, Period> + operator/(const duration& d, const Rep2& s); +template + constexpr + typename common_type::type + operator/(const duration& lhs, const duration& rhs); + +// duration comparisons +template + constexpr + bool operator==(const duration& lhs, const duration& rhs); +template + constexpr + bool operator!=(const duration& lhs, const duration& rhs); +template + constexpr + bool operator< (const duration& lhs, const duration& rhs); +template + constexpr + bool operator<=(const duration& lhs, const duration& rhs); +template + constexpr + bool operator> (const duration& lhs, const duration& rhs); +template + constexpr + bool operator>=(const duration& lhs, const duration& rhs); + +// duration_cast +template + ToDuration duration_cast(const duration& d); + +template + constexpr ToDuration floor(const duration& d); // C++17 +template + constexpr ToDuration ceil(const duration& d); // C++17 +template + constexpr ToDuration round(const duration& d); // C++17 + +// time_point arithmetic (all constexpr in C++14) +template + time_point>::type> + operator+(const time_point& lhs, const duration& rhs); +template + time_point, Duration2>::type> + operator+(const duration& lhs, const time_point& rhs); +template + time_point>::type> + operator-(const time_point& lhs, const duration& rhs); +template + typename common_type::type + operator-(const time_point& lhs, const time_point& rhs); + +// time_point comparisons (all constexpr in C++14) +template + bool operator==(const time_point& lhs, const time_point& rhs); +template + bool operator!=(const time_point& lhs, const time_point& rhs); +template + bool operator< (const time_point& lhs, const time_point& rhs); +template + bool operator<=(const time_point& lhs, const time_point& rhs); +template + bool operator> (const time_point& lhs, const time_point& rhs); +template + bool operator>=(const time_point& lhs, const time_point& rhs); + +// time_point_cast (constexpr in C++14) + +template + time_point time_point_cast(const time_point& t); + +template + constexpr time_point + floor(const time_point& tp); // C++17 + +template + constexpr time_point + ceil(const time_point& tp); // C++17 + +template + constexpr time_point + round(const time_point& tp); // C++17 + +template + constexpr duration abs(duration d); // C++17 +// Clocks + +class system_clock +{ +public: + typedef microseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + static const bool is_steady = false; // constexpr in C++14 + + static time_point now() noexcept; + static time_t to_time_t (const time_point& __t) noexcept; + static time_point from_time_t(time_t __t) noexcept; +}; + +class steady_clock +{ +public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + static const bool is_steady = true; // constexpr in C++14 + + static time_point now() noexcept; +}; + +typedef steady_clock high_resolution_clock; + +} // chrono + +constexpr chrono::hours operator "" h(unsigned long long); // C++14 +constexpr chrono::duration> operator "" h(long double); // C++14 +constexpr chrono::minutes operator "" min(unsigned long long); // C++14 +constexpr chrono::duration> operator "" min(long double); // C++14 +constexpr chrono::seconds operator "" s(unsigned long long); // C++14 +constexpr chrono::duration operator "" s(long double); // C++14 +constexpr chrono::milliseconds operator "" ms(unsigned long long); // C++14 +constexpr chrono::duration operator "" ms(long double); // C++14 +constexpr chrono::microseconds operator "" us(unsigned long long); // C++14 +constexpr chrono::duration operator "" us(long double); // C++14 +constexpr chrono::nanoseconds operator "" ns(unsigned long long); // C++14 +constexpr chrono::duration operator "" ns(long double); // C++14 + +} // std +*/ + +#include <__config> +#include +#include +#include +#include + +#include <__undef_min_max> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +template > class _LIBCPP_TYPE_VIS_ONLY duration; + +template +struct __is_duration : false_type {}; + +template +struct __is_duration > : true_type {}; + +template +struct __is_duration > : true_type {}; + +template +struct __is_duration > : true_type {}; + +template +struct __is_duration > : true_type {}; + +} // chrono + +template +struct _LIBCPP_TYPE_VIS_ONLY common_type, + chrono::duration<_Rep2, _Period2> > +{ + typedef chrono::duration::type, + typename __ratio_gcd<_Period1, _Period2>::type> type; +}; + +namespace chrono { + +// duration_cast + +template ::type, + bool = _Period::num == 1, + bool = _Period::den == 1> +struct __duration_cast; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + return _ToDuration(static_cast(__fd.count())); + } +}; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type::type _Ct; + return _ToDuration(static_cast( + static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den))); + } +}; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type::type _Ct; + return _ToDuration(static_cast( + static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num))); + } +}; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type::type _Ct; + return _ToDuration(static_cast( + static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num) + / static_cast<_Ct>(_Period::den))); + } +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +duration_cast(const duration<_Rep, _Period>& __fd) +{ + return __duration_cast, _ToDuration>()(__fd); +} + +template +struct _LIBCPP_TYPE_VIS_ONLY treat_as_floating_point : is_floating_point<_Rep> {}; + +template +struct _LIBCPP_TYPE_VIS_ONLY duration_values +{ +public: + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() {return _Rep(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max() {return numeric_limits<_Rep>::max();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() {return numeric_limits<_Rep>::lowest();} +}; + +#if _LIBCPP_STD_VER > 14 +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +floor(const duration<_Rep, _Period>& __d) +{ + _ToDuration __t = duration_cast<_ToDuration>(__d); + if (__t > __d) + __t = __t - _ToDuration{1}; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +ceil(const duration<_Rep, _Period>& __d) +{ + _ToDuration __t = duration_cast<_ToDuration>(__d); + if (__t < __d) + __t = __t + _ToDuration{1}; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +round(const duration<_Rep, _Period>& __d) +{ + _ToDuration __lower = floor<_ToDuration>(__d); + _ToDuration __upper = __lower + _ToDuration{1}; + auto __lowerDiff = __d - __lower; + auto __upperDiff = __upper - __d; + if (__lowerDiff < __upperDiff) + return __lower; + if (__lowerDiff > __upperDiff) + return __upper; + return __lower.count() & 1 ? __upper : __lower; +} +#endif + +// duration + +template +class _LIBCPP_TYPE_VIS_ONLY duration +{ + static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration"); + static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio"); + static_assert(_Period::num > 0, "duration period must be positive"); + + template + struct __no_overflow + { + private: + static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; + static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; + static const intmax_t __n1 = _R1::num / __gcd_n1_n2; + static const intmax_t __d1 = _R1::den / __gcd_d1_d2; + static const intmax_t __n2 = _R2::num / __gcd_n1_n2; + static const intmax_t __d2 = _R2::den / __gcd_d1_d2; + static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); + + template + struct __mul // __overflow == false + { + static const intmax_t value = _Xp * _Yp; + }; + + template + struct __mul<_Xp, _Yp, true> + { + static const intmax_t value = 1; + }; + + public: + static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1); + typedef ratio<__mul<__n1, __d2, !value>::value, + __mul<__n2, __d1, !value>::value> type; + }; + +public: + typedef _Rep rep; + typedef _Period period; +private: + rep __rep_; +public: + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS + duration() = default; +#else + duration() {} +#endif + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + explicit duration(const _Rep2& __r, + typename enable_if + < + is_convertible<_Rep2, rep>::value && + (treat_as_floating_point::value || + !treat_as_floating_point<_Rep2>::value) + >::type* = 0) + : __rep_(__r) {} + + // conversions + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + duration(const duration<_Rep2, _Period2>& __d, + typename enable_if + < + __no_overflow<_Period2, period>::value && ( + treat_as_floating_point::value || + (__no_overflow<_Period2, period>::type::den == 1 && + !treat_as_floating_point<_Rep2>::value)) + >::type* = 0) + : __rep_(_VSTD::chrono::duration_cast(__d).count()) {} + + // observer + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR rep count() const {return __rep_;} + + // arithmetic + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR duration operator+() const {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR duration operator-() const {return duration(-__rep_);} + _LIBCPP_INLINE_VISIBILITY duration& operator++() {++__rep_; return *this;} + _LIBCPP_INLINE_VISIBILITY duration operator++(int) {return duration(__rep_++);} + _LIBCPP_INLINE_VISIBILITY duration& operator--() {--__rep_; return *this;} + _LIBCPP_INLINE_VISIBILITY duration operator--(int) {return duration(__rep_--);} + + _LIBCPP_INLINE_VISIBILITY duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;} + _LIBCPP_INLINE_VISIBILITY duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;} + + _LIBCPP_INLINE_VISIBILITY duration& operator*=(const rep& rhs) {__rep_ *= rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY duration& operator/=(const rep& rhs) {__rep_ /= rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY duration& operator%=(const rep& rhs) {__rep_ %= rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY duration& operator%=(const duration& rhs) {__rep_ %= rhs.count(); return *this;} + + // special values + + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() {return duration(duration_values::zero());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min() {return duration(duration_values::min());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max() {return duration(duration_values::max());} +}; + +typedef duration nanoseconds; +typedef duration microseconds; +typedef duration milliseconds; +typedef duration seconds; +typedef duration< long, ratio< 60> > minutes; +typedef duration< long, ratio<3600> > hours; + +// Duration == + +template +struct __duration_eq +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const + { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() == _Ct(__rhs).count(); + } +}; + +template +struct __duration_eq<_LhsDuration, _LhsDuration> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const + {return __lhs.count() == __rhs.count();} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __duration_eq, duration<_Rep2, _Period2> >()(__lhs, __rhs); +} + +// Duration != + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__lhs == __rhs); +} + +// Duration < + +template +struct __duration_lt +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const + { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() < _Ct(__rhs).count(); + } +}; + +template +struct __duration_lt<_LhsDuration, _LhsDuration> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const + {return __lhs.count() < __rhs.count();} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __duration_lt, duration<_Rep2, _Period2> >()(__lhs, __rhs); +} + +// Duration > + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __rhs < __lhs; +} + +// Duration <= + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__rhs < __lhs); +} + +// Duration >= + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__lhs < __rhs); +} + +// Duration + + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type, duration<_Rep2, _Period2> >::type +operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count()); +} + +// Duration - + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type, duration<_Rep2, _Period2> >::type +operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count()); +} + +// Duration * + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration::type, _Period> +>::type +operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value, + duration::type, _Period> +>::type +operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) +{ + return __d * __s; +} + +// Duration / + +template ::value> +struct __duration_divide_result +{ +}; + +template ::type>::value> +struct __duration_divide_imp +{ +}; + +template +struct __duration_divide_imp, _Rep2, true> +{ + typedef duration::type, _Period> type; +}; + +template +struct __duration_divide_result, _Rep2, false> + : __duration_divide_imp, _Rep2> +{ +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename __duration_divide_result, _Rep2>::type +operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type<_Rep1, _Rep2>::type +operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type, duration<_Rep2, _Period2> >::type _Ct; + return _Ct(__lhs).count() / _Ct(__rhs).count(); +} + +// Duration % + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename __duration_divide_result, _Rep2>::type +operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type, duration<_Rep2, _Period2> >::type +operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count())); +} + +////////////////////////////////////////////////////////// +///////////////////// time_point ///////////////////////// +////////////////////////////////////////////////////////// + +template +class _LIBCPP_TYPE_VIS_ONLY time_point +{ + static_assert(__is_duration<_Duration>::value, + "Second template parameter of time_point must be a std::chrono::duration"); +public: + typedef _Clock clock; + typedef _Duration duration; + typedef typename duration::rep rep; + typedef typename duration::period period; +private: + duration __d_; + +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 time_point() : __d_(duration::zero()) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit time_point(const duration& __d) : __d_(__d) {} + + // conversions + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + time_point(const time_point& t, + typename enable_if + < + is_convertible<_Duration2, duration>::value + >::type* = 0) + : __d_(t.time_since_epoch()) {} + + // observer + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 duration time_since_epoch() const {return __d_;} + + // arithmetic + + _LIBCPP_INLINE_VISIBILITY time_point& operator+=(const duration& __d) {__d_ += __d; return *this;} + _LIBCPP_INLINE_VISIBILITY time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;} + + // special values + + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() {return time_point(duration::min());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() {return time_point(duration::max());} +}; + +} // chrono + +template +struct _LIBCPP_TYPE_VIS_ONLY common_type, + chrono::time_point<_Clock, _Duration2> > +{ + typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type; +}; + +namespace chrono { + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, _ToDuration> +time_point_cast(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>(_VSTD::chrono::duration_cast<_ToDuration>(__t.time_since_epoch())); +} + +#if _LIBCPP_STD_VER > 14 +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +floor(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{floor<_ToDuration>(__t.time_since_epoch())}; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +ceil(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{ceil<_ToDuration>(__t.time_since_epoch())}; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +round(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{round<_ToDuration>(__t.time_since_epoch())}; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + numeric_limits<_Rep>::is_signed, + duration<_Rep, _Period> +>::type +abs(duration<_Rep, _Period> __d) +{ + return __d >= __d.zero() ? __d : -__d; +} +#endif + +// time_point == + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() == __rhs.time_since_epoch(); +} + +// time_point != + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__lhs == __rhs); +} + +// time_point < + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() < __rhs.time_since_epoch(); +} + +// time_point > + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __rhs < __lhs; +} + +// time_point <= + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__rhs < __lhs); +} + +// time_point >= + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__lhs < __rhs); +} + +// time_point operator+(time_point x, duration y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> +operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr; + return _Tr (__lhs.time_since_epoch() + __rhs); +} + +// time_point operator+(duration x, time_point y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, typename common_type, _Duration2>::type> +operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __rhs + __lhs; +} + +// time_point operator-(time_point x, duration y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> +operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __lhs + (-__rhs); +} + +// duration operator-(time_point x, time_point y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +typename common_type<_Duration1, _Duration2>::type +operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() - __rhs.time_since_epoch(); +} + +////////////////////////////////////////////////////////// +/////////////////////// clocks /////////////////////////// +////////////////////////////////////////////////////////// + +class _LIBCPP_TYPE_VIS system_clock +{ +public: + typedef microseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; + + static time_point now() _NOEXCEPT; + static time_t to_time_t (const time_point& __t) _NOEXCEPT; + static time_point from_time_t(time_t __t) _NOEXCEPT; +}; + +#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK +class _LIBCPP_TYPE_VIS steady_clock +{ +public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = true; + + static time_point now() _NOEXCEPT; +}; + +typedef steady_clock high_resolution_clock; +#else +typedef system_clock high_resolution_clock; +#endif + +} // chrono + +#if _LIBCPP_STD_VER > 11 +// Suffixes for duration literals [time.duration.literals] +inline namespace literals +{ + inline namespace chrono_literals + { + + constexpr chrono::hours operator"" h(unsigned long long __h) + { + return chrono::hours(static_cast(__h)); + } + + constexpr chrono::duration> operator"" h(long double __h) + { + return chrono::duration>(__h); + } + + + constexpr chrono::minutes operator"" min(unsigned long long __m) + { + return chrono::minutes(static_cast(__m)); + } + + constexpr chrono::duration> operator"" min(long double __m) + { + return chrono::duration> (__m); + } + + + constexpr chrono::seconds operator"" s(unsigned long long __s) + { + return chrono::seconds(static_cast(__s)); + } + + constexpr chrono::duration operator"" s(long double __s) + { + return chrono::duration (__s); + } + + + constexpr chrono::milliseconds operator"" ms(unsigned long long __ms) + { + return chrono::milliseconds(static_cast(__ms)); + } + + constexpr chrono::duration operator"" ms(long double __ms) + { + return chrono::duration(__ms); + } + + + constexpr chrono::microseconds operator"" us(unsigned long long __us) + { + return chrono::microseconds(static_cast(__us)); + } + + constexpr chrono::duration operator"" us(long double __us) + { + return chrono::duration (__us); + } + + + constexpr chrono::nanoseconds operator"" ns(unsigned long long __ns) + { + return chrono::nanoseconds(static_cast(__ns)); + } + + constexpr chrono::duration operator"" ns(long double __ns) + { + return chrono::duration (__ns); + } + +}} + +namespace chrono { // hoist the literals into namespace std::chrono + using namespace literals::chrono_literals; +} + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CHRONO diff --git a/headers/libs/libc++/cinttypes b/headers/libs/libc++/cinttypes new file mode 100644 index 0000000000..3f61b0634b --- /dev/null +++ b/headers/libs/libc++/cinttypes @@ -0,0 +1,258 @@ +// -*- C++ -*- +//===--------------------------- cinttypes --------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CINTTYPES +#define _LIBCPP_CINTTYPES + +/* + cinttypes synopsis + +This entire header is C99 / C++0X + +#include // includes + +Macros: + + PRId8 + PRId16 + PRId32 + PRId64 + + PRIdLEAST8 + PRIdLEAST16 + PRIdLEAST32 + PRIdLEAST64 + + PRIdFAST8 + PRIdFAST16 + PRIdFAST32 + PRIdFAST64 + + PRIdMAX + PRIdPTR + + PRIi8 + PRIi16 + PRIi32 + PRIi64 + + PRIiLEAST8 + PRIiLEAST16 + PRIiLEAST32 + PRIiLEAST64 + + PRIiFAST8 + PRIiFAST16 + PRIiFAST32 + PRIiFAST64 + + PRIiMAX + PRIiPTR + + PRIo8 + PRIo16 + PRIo32 + PRIo64 + + PRIoLEAST8 + PRIoLEAST16 + PRIoLEAST32 + PRIoLEAST64 + + PRIoFAST8 + PRIoFAST16 + PRIoFAST32 + PRIoFAST64 + + PRIoMAX + PRIoPTR + + PRIu8 + PRIu16 + PRIu32 + PRIu64 + + PRIuLEAST8 + PRIuLEAST16 + PRIuLEAST32 + PRIuLEAST64 + + PRIuFAST8 + PRIuFAST16 + PRIuFAST32 + PRIuFAST64 + + PRIuMAX + PRIuPTR + + PRIx8 + PRIx16 + PRIx32 + PRIx64 + + PRIxLEAST8 + PRIxLEAST16 + PRIxLEAST32 + PRIxLEAST64 + + PRIxFAST8 + PRIxFAST16 + PRIxFAST32 + PRIxFAST64 + + PRIxMAX + PRIxPTR + + PRIX8 + PRIX16 + PRIX32 + PRIX64 + + PRIXLEAST8 + PRIXLEAST16 + PRIXLEAST32 + PRIXLEAST64 + + PRIXFAST8 + PRIXFAST16 + PRIXFAST32 + PRIXFAST64 + + PRIXMAX + PRIXPTR + + SCNd8 + SCNd16 + SCNd32 + SCNd64 + + SCNdLEAST8 + SCNdLEAST16 + SCNdLEAST32 + SCNdLEAST64 + + SCNdFAST8 + SCNdFAST16 + SCNdFAST32 + SCNdFAST64 + + SCNdMAX + SCNdPTR + + SCNi8 + SCNi16 + SCNi32 + SCNi64 + + SCNiLEAST8 + SCNiLEAST16 + SCNiLEAST32 + SCNiLEAST64 + + SCNiFAST8 + SCNiFAST16 + SCNiFAST32 + SCNiFAST64 + + SCNiMAX + SCNiPTR + + SCNo8 + SCNo16 + SCNo32 + SCNo64 + + SCNoLEAST8 + SCNoLEAST16 + SCNoLEAST32 + SCNoLEAST64 + + SCNoFAST8 + SCNoFAST16 + SCNoFAST32 + SCNoFAST64 + + SCNoMAX + SCNoPTR + + SCNu8 + SCNu16 + SCNu32 + SCNu64 + + SCNuLEAST8 + SCNuLEAST16 + SCNuLEAST32 + SCNuLEAST64 + + SCNuFAST8 + SCNuFAST16 + SCNuFAST32 + SCNuFAST64 + + SCNuMAX + SCNuPTR + + SCNx8 + SCNx16 + SCNx32 + SCNx64 + + SCNxLEAST8 + SCNxLEAST16 + SCNxLEAST32 + SCNxLEAST64 + + SCNxFAST8 + SCNxFAST16 + SCNxFAST32 + SCNxFAST64 + + SCNxMAX + SCNxPTR + +namespace std +{ + +Types: + + imaxdiv_t + +intmax_t imaxabs(intmax_t j); +imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); +intmax_t strtoimax(const char* restrict nptr, char** restrict endptr, int base); +uintmax_t strtoumax(const char* restrict nptr, char** restrict endptr, int base); +intmax_t wcstoimax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base); +uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base); + +} // std +*/ + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using::imaxdiv_t; +using::imaxabs; +using::imaxdiv; +using::strtoimax; +using::strtoumax; +using::wcstoimax; +using::wcstoumax; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CINTTYPES diff --git a/headers/libs/libc++/ciso646 b/headers/libs/libc++/ciso646 new file mode 100644 index 0000000000..b2efc72a9a --- /dev/null +++ b/headers/libs/libc++/ciso646 @@ -0,0 +1,25 @@ +// -*- C++ -*- +//===--------------------------- ciso646 ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CISO646 +#define _LIBCPP_CISO646 + +/* + ciso646 synopsis + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#endif // _LIBCPP_CISO646 diff --git a/headers/libs/libc++/climits b/headers/libs/libc++/climits new file mode 100644 index 0000000000..81ffecdf6e --- /dev/null +++ b/headers/libs/libc++/climits @@ -0,0 +1,48 @@ +// -*- C++ -*- +//===--------------------------- climits ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CLIMITS +#define _LIBCPP_CLIMITS + +/* + climits synopsis + +Macros: + + CHAR_BIT + SCHAR_MIN + SCHAR_MAX + UCHAR_MAX + CHAR_MIN + CHAR_MAX + MB_LEN_MAX + SHRT_MIN + SHRT_MAX + USHRT_MAX + INT_MIN + INT_MAX + UINT_MAX + LONG_MIN + LONG_MAX + ULONG_MAX + LLONG_MIN // C99 + LLONG_MAX // C99 + ULLONG_MAX // C99 + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#endif // _LIBCPP_CLIMITS diff --git a/headers/libs/libc++/clocale b/headers/libs/libc++/clocale new file mode 100644 index 0000000000..05fa9c6edd --- /dev/null +++ b/headers/libs/libc++/clocale @@ -0,0 +1,55 @@ +// -*- C++ -*- +//===--------------------------- clocale ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CLOCALE +#define _LIBCPP_CLOCALE + +/* + clocale synopsis + +Macros: + + LC_ALL + LC_COLLATE + LC_CTYPE + LC_MONETARY + LC_NUMERIC + LC_TIME + NULL + +namespace std +{ + +struct lconv; +char* setlocale(int category, const char* locale); +lconv* localeconv(); + +} // std + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::lconv; +#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS +using ::setlocale; +#endif +using ::localeconv; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CLOCALE diff --git a/headers/libs/libc++/cmath b/headers/libs/libc++/cmath new file mode 100644 index 0000000000..ebbde18168 --- /dev/null +++ b/headers/libs/libc++/cmath @@ -0,0 +1,553 @@ +// -*- C++ -*- +//===---------------------------- cmath -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CMATH +#define _LIBCPP_CMATH + +/* + cmath synopsis + +Macros: + + HUGE_VAL + HUGE_VALF // C99 + HUGE_VALL // C99 + INFINITY // C99 + NAN // C99 + FP_INFINITE // C99 + FP_NAN // C99 + FP_NORMAL // C99 + FP_SUBNORMAL // C99 + FP_ZERO // C99 + FP_FAST_FMA // C99 + FP_FAST_FMAF // C99 + FP_FAST_FMAL // C99 + FP_ILOGB0 // C99 + FP_ILOGBNAN // C99 + MATH_ERRNO // C99 + MATH_ERREXCEPT // C99 + math_errhandling // C99 + +namespace std +{ + +Types: + + float_t // C99 + double_t // C99 + +// C90 + +floating_point abs(floating_point x); + +floating_point acos (arithmetic x); +float acosf(float x); +long double acosl(long double x); + +floating_point asin (arithmetic x); +float asinf(float x); +long double asinl(long double x); + +floating_point atan (arithmetic x); +float atanf(float x); +long double atanl(long double x); + +floating_point atan2 (arithmetic y, arithmetic x); +float atan2f(float y, float x); +long double atan2l(long double y, long double x); + +floating_point ceil (arithmetic x); +float ceilf(float x); +long double ceill(long double x); + +floating_point cos (arithmetic x); +float cosf(float x); +long double cosl(long double x); + +floating_point cosh (arithmetic x); +float coshf(float x); +long double coshl(long double x); + +floating_point exp (arithmetic x); +float expf(float x); +long double expl(long double x); + +floating_point fabs (arithmetic x); +float fabsf(float x); +long double fabsl(long double x); + +floating_point floor (arithmetic x); +float floorf(float x); +long double floorl(long double x); + +floating_point fmod (arithmetic x, arithmetic y); +float fmodf(float x, float y); +long double fmodl(long double x, long double y); + +floating_point frexp (arithmetic value, int* exp); +float frexpf(float value, int* exp); +long double frexpl(long double value, int* exp); + +floating_point ldexp (arithmetic value, int exp); +float ldexpf(float value, int exp); +long double ldexpl(long double value, int exp); + +floating_point log (arithmetic x); +float logf(float x); +long double logl(long double x); + +floating_point log10 (arithmetic x); +float log10f(float x); +long double log10l(long double x); + +floating_point modf (floating_point value, floating_point* iptr); +float modff(float value, float* iptr); +long double modfl(long double value, long double* iptr); + +floating_point pow (arithmetic x, arithmetic y); +float powf(float x, float y); +long double powl(long double x, long double y); + +floating_point sin (arithmetic x); +float sinf(float x); +long double sinl(long double x); + +floating_point sinh (arithmetic x); +float sinhf(float x); +long double sinhl(long double x); + +floating_point sqrt (arithmetic x); +float sqrtf(float x); +long double sqrtl(long double x); + +floating_point tan (arithmetic x); +float tanf(float x); +long double tanl(long double x); + +floating_point tanh (arithmetic x); +float tanhf(float x); +long double tanhl(long double x); + +// C99 + +bool signbit(arithmetic x); + +int fpclassify(arithmetic x); + +bool isfinite(arithmetic x); +bool isinf(arithmetic x); +bool isnan(arithmetic x); +bool isnormal(arithmetic x); + +bool isgreater(arithmetic x, arithmetic y); +bool isgreaterequal(arithmetic x, arithmetic y); +bool isless(arithmetic x, arithmetic y); +bool islessequal(arithmetic x, arithmetic y); +bool islessgreater(arithmetic x, arithmetic y); +bool isunordered(arithmetic x, arithmetic y); + +floating_point acosh (arithmetic x); +float acoshf(float x); +long double acoshl(long double x); + +floating_point asinh (arithmetic x); +float asinhf(float x); +long double asinhl(long double x); + +floating_point atanh (arithmetic x); +float atanhf(float x); +long double atanhl(long double x); + +floating_point cbrt (arithmetic x); +float cbrtf(float x); +long double cbrtl(long double x); + +floating_point copysign (arithmetic x, arithmetic y); +float copysignf(float x, float y); +long double copysignl(long double x, long double y); + +floating_point erf (arithmetic x); +float erff(float x); +long double erfl(long double x); + +floating_point erfc (arithmetic x); +float erfcf(float x); +long double erfcl(long double x); + +floating_point exp2 (arithmetic x); +float exp2f(float x); +long double exp2l(long double x); + +floating_point expm1 (arithmetic x); +float expm1f(float x); +long double expm1l(long double x); + +floating_point fdim (arithmetic x, arithmetic y); +float fdimf(float x, float y); +long double fdiml(long double x, long double y); + +floating_point fma (arithmetic x, arithmetic y, arithmetic z); +float fmaf(float x, float y, float z); +long double fmal(long double x, long double y, long double z); + +floating_point fmax (arithmetic x, arithmetic y); +float fmaxf(float x, float y); +long double fmaxl(long double x, long double y); + +floating_point fmin (arithmetic x, arithmetic y); +float fminf(float x, float y); +long double fminl(long double x, long double y); + +floating_point hypot (arithmetic x, arithmetic y); +float hypotf(float x, float y); +long double hypotl(long double x, long double y); + +int ilogb (arithmetic x); +int ilogbf(float x); +int ilogbl(long double x); + +floating_point lgamma (arithmetic x); +float lgammaf(float x); +long double lgammal(long double x); + +long long llrint (arithmetic x); +long long llrintf(float x); +long long llrintl(long double x); + +long long llround (arithmetic x); +long long llroundf(float x); +long long llroundl(long double x); + +floating_point log1p (arithmetic x); +float log1pf(float x); +long double log1pl(long double x); + +floating_point log2 (arithmetic x); +float log2f(float x); +long double log2l(long double x); + +floating_point logb (arithmetic x); +float logbf(float x); +long double logbl(long double x); + +long lrint (arithmetic x); +long lrintf(float x); +long lrintl(long double x); + +long lround (arithmetic x); +long lroundf(float x); +long lroundl(long double x); + +double nan (const char* str); +float nanf(const char* str); +long double nanl(const char* str); + +floating_point nearbyint (arithmetic x); +float nearbyintf(float x); +long double nearbyintl(long double x); + +floating_point nextafter (arithmetic x, arithmetic y); +float nextafterf(float x, float y); +long double nextafterl(long double x, long double y); + +floating_point nexttoward (arithmetic x, long double y); +float nexttowardf(float x, long double y); +long double nexttowardl(long double x, long double y); + +floating_point remainder (arithmetic x, arithmetic y); +float remainderf(float x, float y); +long double remainderl(long double x, long double y); + +floating_point remquo (arithmetic x, arithmetic y, int* pquo); +float remquof(float x, float y, int* pquo); +long double remquol(long double x, long double y, int* pquo); + +floating_point rint (arithmetic x); +float rintf(float x); +long double rintl(long double x); + +floating_point round (arithmetic x); +float roundf(float x); +long double roundl(long double x); + +floating_point scalbln (arithmetic x, long ex); +float scalblnf(float x, long ex); +long double scalblnl(long double x, long ex); + +floating_point scalbn (arithmetic x, int ex); +float scalbnf(float x, int ex); +long double scalbnl(long double x, int ex); + +floating_point tgamma (arithmetic x); +float tgammaf(float x); +long double tgammal(long double x); + +floating_point trunc (arithmetic x); +float truncf(float x); +long double truncl(long double x); + +} // std + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::signbit; +using ::fpclassify; +using ::isfinite; +using ::isinf; +using ::isnan; +using ::isnormal; +using ::isgreater; +using ::isgreaterequal; +using ::isless; +using ::islessequal; +using ::islessgreater; +using ::isunordered; +using ::isunordered; + +using ::float_t; +using ::double_t; + +#ifndef _AIX +using ::abs; +#endif + +#ifndef __sun__ +using ::acos; +using ::acosf; +using ::asin; +using ::asinf; +using ::atan; +using ::atanf; +using ::atan2; +using ::atan2f; +using ::ceil; +using ::ceilf; +using ::cos; +using ::cosf; +using ::cosh; +using ::coshf; +#endif // __sun__ + +using ::exp; +using ::expf; + +#ifndef __sun__ +using ::fabs; +using ::fabsf; +using ::floor; +using ::floorf; +#endif //__sun__ + +using ::fmod; +using ::fmodf; + +#ifndef __sun__ +using ::frexp; +using ::frexpf; +using ::ldexp; +using ::ldexpf; +#endif // __sun__ + +using ::log; +using ::logf; + +#ifndef __sun__ +using ::log10; +using ::log10f; +using ::modf; +using ::modff; +#endif // __sun__ + +using ::pow; +using ::powf; + +#ifndef __sun__ +using ::sin; +using ::sinf; +using ::sinh; +using ::sinhf; +#endif // __sun__ + +using ::sqrt; +using ::sqrtf; +using ::tan; +using ::tanf; + +#ifndef __sun__ +using ::tanh; +using ::tanhf; + +#ifndef _LIBCPP_MSVCRT +using ::acosh; +using ::acoshf; +using ::asinh; +using ::asinhf; +using ::atanh; +using ::atanhf; +using ::cbrt; +using ::cbrtf; +#endif + +using ::copysign; +using ::copysignf; + +#ifndef _LIBCPP_MSVCRT +using ::erf; +using ::erff; +using ::erfc; +using ::erfcf; +using ::exp2; +using ::exp2f; +using ::expm1; +using ::expm1f; +using ::fdim; +using ::fdimf; +using ::fmaf; +using ::fma; +using ::fmax; +using ::fmaxf; +using ::fmin; +using ::fminf; +using ::hypot; +using ::hypotf; +using ::ilogb; +using ::ilogbf; +using ::lgamma; +using ::lgammaf; +using ::llrint; +using ::llrintf; +using ::llround; +using ::llroundf; +using ::log1p; +using ::log1pf; +using ::log2; +using ::log2f; +using ::logb; +using ::logbf; +using ::lrint; +using ::lrintf; +using ::lround; +using ::lroundf; +#endif // _LIBCPP_MSVCRT +#endif // __sun__ + +#ifndef _LIBCPP_MSVCRT +using ::nan; +using ::nanf; +#endif // _LIBCPP_MSVCRT + +#ifndef __sun__ +#ifndef _LIBCPP_MSVCRT +using ::nearbyint; +using ::nearbyintf; +using ::nextafter; +using ::nextafterf; +using ::nexttoward; +using ::nexttowardf; +using ::remainder; +using ::remainderf; +using ::remquo; +using ::remquof; +using ::rint; +using ::rintf; +using ::round; +using ::roundf; +using ::scalbln; +using ::scalblnf; +using ::scalbn; +using ::scalbnf; +using ::tgamma; +using ::tgammaf; +using ::trunc; +using ::truncf; +#endif // !_LIBCPP_MSVCRT + +using ::acosl; +using ::asinl; +using ::atanl; +using ::atan2l; +using ::ceill; +using ::cosl; +using ::coshl; +using ::expl; +using ::fabsl; +using ::floorl; +using ::fmodl; +using ::frexpl; +using ::ldexpl; +using ::logl; +using ::log10l; +using ::modfl; +using ::powl; +using ::sinl; +using ::sinhl; +using ::sqrtl; +using ::tanl; + +#ifndef _LIBCPP_MSVCRT +using ::tanhl; +using ::acoshl; +using ::asinhl; +using ::atanhl; +using ::cbrtl; +#endif // !_LIBCPP_MSVCRT + +using ::copysignl; + +#ifndef _LIBCPP_MSVCRT +using ::erfl; +using ::erfcl; +using ::exp2l; +using ::expm1l; +using ::fdiml; +using ::fmal; +using ::fmaxl; +using ::fminl; +using ::hypotl; +using ::ilogbl; +using ::lgammal; +using ::llrintl; +using ::llroundl; +using ::log1pl; +using ::log2l; +using ::logbl; +using ::lrintl; +using ::lroundl; +using ::nanl; +using ::nearbyintl; +using ::nextafterl; +using ::nexttowardl; +using ::remainderl; +using ::remquol; +using ::rintl; +using ::roundl; +using ::scalblnl; +using ::scalbnl; +using ::tgammal; +using ::truncl; +#endif // !_LIBCPP_MSVCRT + +#else +using ::lgamma; +using ::lgammaf; +#endif // __sun__ + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CMATH diff --git a/headers/libs/libc++/codecvt b/headers/libs/libc++/codecvt new file mode 100644 index 0000000000..6eff107cd1 --- /dev/null +++ b/headers/libs/libc++/codecvt @@ -0,0 +1,550 @@ +// -*- C++ -*- +//===-------------------------- codecvt -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CODECVT +#define _LIBCPP_CODECVT + +/* + codecvt synopsis + +namespace std +{ + +enum codecvt_mode +{ + consume_header = 4, + generate_header = 2, + little_endian = 1 +}; + +template +class codecvt_utf8 + : public codecvt +{ + explicit codecvt_utf8(size_t refs = 0); + ~codecvt_utf8(); +}; + +template +class codecvt_utf16 + : public codecvt +{ + explicit codecvt_utf16(size_t refs = 0); + ~codecvt_utf16(); +}; + +template +class codecvt_utf8_utf16 + : public codecvt +{ + explicit codecvt_utf8_utf16(size_t refs = 0); + ~codecvt_utf8_utf16(); +}; + +} // std + +*/ + +#include <__config> +#include <__locale> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +enum codecvt_mode +{ + consume_header = 4, + generate_header = 2, + little_endian = 1 +}; + +// codecvt_utf8 + +template class __codecvt_utf8; + +template <> +class _LIBCPP_TYPE_VIS __codecvt_utf8 + : public codecvt +{ + unsigned long _Maxcode_; + codecvt_mode _Mode_; +public: + typedef wchar_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode, + codecvt_mode _Mode) + : codecvt(__refs), _Maxcode_(_Maxcode), + _Mode_(_Mode) {} +protected: + virtual result + do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result + do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result + do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const throw(); + virtual bool do_always_noconv() const throw(); + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, + size_t __mx) const; + virtual int do_max_length() const throw(); +}; + +template <> +class _LIBCPP_TYPE_VIS __codecvt_utf8 + : public codecvt +{ + unsigned long _Maxcode_; + codecvt_mode _Mode_; +public: + typedef char16_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode, + codecvt_mode _Mode) + : codecvt(__refs), _Maxcode_(_Maxcode), + _Mode_(_Mode) {} +protected: + virtual result + do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result + do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result + do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const throw(); + virtual bool do_always_noconv() const throw(); + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, + size_t __mx) const; + virtual int do_max_length() const throw(); +}; + +template <> +class _LIBCPP_TYPE_VIS __codecvt_utf8 + : public codecvt +{ + unsigned long _Maxcode_; + codecvt_mode _Mode_; +public: + typedef char32_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode, + codecvt_mode _Mode) + : codecvt(__refs), _Maxcode_(_Maxcode), + _Mode_(_Mode) {} +protected: + virtual result + do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result + do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result + do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const throw(); + virtual bool do_always_noconv() const throw(); + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, + size_t __mx) const; + virtual int do_max_length() const throw(); +}; + +template +class _LIBCPP_TYPE_VIS_ONLY codecvt_utf8 + : public __codecvt_utf8<_Elem> +{ +public: + _LIBCPP_ALWAYS_INLINE + explicit codecvt_utf8(size_t __refs = 0) + : __codecvt_utf8<_Elem>(__refs, _Maxcode, _Mode) {} + + _LIBCPP_ALWAYS_INLINE + ~codecvt_utf8() {} +}; + +// codecvt_utf16 + +template class __codecvt_utf16; + +template <> +class _LIBCPP_TYPE_VIS __codecvt_utf16 + : public codecvt +{ + unsigned long _Maxcode_; + codecvt_mode _Mode_; +public: + typedef wchar_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, + codecvt_mode _Mode) + : codecvt(__refs), _Maxcode_(_Maxcode), + _Mode_(_Mode) {} +protected: + virtual result + do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result + do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result + do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const throw(); + virtual bool do_always_noconv() const throw(); + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, + size_t __mx) const; + virtual int do_max_length() const throw(); +}; + +template <> +class _LIBCPP_TYPE_VIS __codecvt_utf16 + : public codecvt +{ + unsigned long _Maxcode_; + codecvt_mode _Mode_; +public: + typedef wchar_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, + codecvt_mode _Mode) + : codecvt(__refs), _Maxcode_(_Maxcode), + _Mode_(_Mode) {} +protected: + virtual result + do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result + do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result + do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const throw(); + virtual bool do_always_noconv() const throw(); + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, + size_t __mx) const; + virtual int do_max_length() const throw(); +}; + +template <> +class _LIBCPP_TYPE_VIS __codecvt_utf16 + : public codecvt +{ + unsigned long _Maxcode_; + codecvt_mode _Mode_; +public: + typedef char16_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, + codecvt_mode _Mode) + : codecvt(__refs), _Maxcode_(_Maxcode), + _Mode_(_Mode) {} +protected: + virtual result + do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result + do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result + do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const throw(); + virtual bool do_always_noconv() const throw(); + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, + size_t __mx) const; + virtual int do_max_length() const throw(); +}; + +template <> +class _LIBCPP_TYPE_VIS __codecvt_utf16 + : public codecvt +{ + unsigned long _Maxcode_; + codecvt_mode _Mode_; +public: + typedef char16_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, + codecvt_mode _Mode) + : codecvt(__refs), _Maxcode_(_Maxcode), + _Mode_(_Mode) {} +protected: + virtual result + do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result + do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result + do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const throw(); + virtual bool do_always_noconv() const throw(); + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, + size_t __mx) const; + virtual int do_max_length() const throw(); +}; + +template <> +class _LIBCPP_TYPE_VIS __codecvt_utf16 + : public codecvt +{ + unsigned long _Maxcode_; + codecvt_mode _Mode_; +public: + typedef char32_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, + codecvt_mode _Mode) + : codecvt(__refs), _Maxcode_(_Maxcode), + _Mode_(_Mode) {} +protected: + virtual result + do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result + do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result + do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const throw(); + virtual bool do_always_noconv() const throw(); + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, + size_t __mx) const; + virtual int do_max_length() const throw(); +}; + +template <> +class _LIBCPP_TYPE_VIS __codecvt_utf16 + : public codecvt +{ + unsigned long _Maxcode_; + codecvt_mode _Mode_; +public: + typedef char32_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, + codecvt_mode _Mode) + : codecvt(__refs), _Maxcode_(_Maxcode), + _Mode_(_Mode) {} +protected: + virtual result + do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result + do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result + do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const throw(); + virtual bool do_always_noconv() const throw(); + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, + size_t __mx) const; + virtual int do_max_length() const throw(); +}; + +template +class _LIBCPP_TYPE_VIS_ONLY codecvt_utf16 + : public __codecvt_utf16<_Elem, _Mode & little_endian> +{ +public: + _LIBCPP_ALWAYS_INLINE + explicit codecvt_utf16(size_t __refs = 0) + : __codecvt_utf16<_Elem, _Mode & little_endian>(__refs, _Maxcode, _Mode) {} + + _LIBCPP_ALWAYS_INLINE + ~codecvt_utf16() {} +}; + +// codecvt_utf8_utf16 + +template class __codecvt_utf8_utf16; + +template <> +class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16 + : public codecvt +{ + unsigned long _Maxcode_; + codecvt_mode _Mode_; +public: + typedef wchar_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode, + codecvt_mode _Mode) + : codecvt(__refs), _Maxcode_(_Maxcode), + _Mode_(_Mode) {} +protected: + virtual result + do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result + do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result + do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const throw(); + virtual bool do_always_noconv() const throw(); + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, + size_t __mx) const; + virtual int do_max_length() const throw(); +}; + +template <> +class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16 + : public codecvt +{ + unsigned long _Maxcode_; + codecvt_mode _Mode_; +public: + typedef char32_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode, + codecvt_mode _Mode) + : codecvt(__refs), _Maxcode_(_Maxcode), + _Mode_(_Mode) {} +protected: + virtual result + do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result + do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result + do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const throw(); + virtual bool do_always_noconv() const throw(); + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, + size_t __mx) const; + virtual int do_max_length() const throw(); +}; + +template <> +class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16 + : public codecvt +{ + unsigned long _Maxcode_; + codecvt_mode _Mode_; +public: + typedef char16_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + _LIBCPP_ALWAYS_INLINE + explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode, + codecvt_mode _Mode) + : codecvt(__refs), _Maxcode_(_Maxcode), + _Mode_(_Mode) {} +protected: + virtual result + do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result + do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result + do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const throw(); + virtual bool do_always_noconv() const throw(); + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, + size_t __mx) const; + virtual int do_max_length() const throw(); +}; + +template +class _LIBCPP_TYPE_VIS_ONLY codecvt_utf8_utf16 + : public __codecvt_utf8_utf16<_Elem> +{ +public: + _LIBCPP_ALWAYS_INLINE + explicit codecvt_utf8_utf16(size_t __refs = 0) + : __codecvt_utf8_utf16<_Elem>(__refs, _Maxcode, _Mode) {} + + _LIBCPP_ALWAYS_INLINE + ~codecvt_utf8_utf16() {} +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CODECVT diff --git a/headers/libs/libc++/complex b/headers/libs/libc++/complex new file mode 100644 index 0000000000..2943da1d77 --- /dev/null +++ b/headers/libs/libc++/complex @@ -0,0 +1,1567 @@ +// -*- C++ -*- +//===--------------------------- complex ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_COMPLEX +#define _LIBCPP_COMPLEX + +/* + complex synopsis + +namespace std +{ + +template +class complex +{ +public: + typedef T value_type; + + complex(const T& re = T(), const T& im = T()); // constexpr in C++14 + complex(const complex&); // constexpr in C++14 + template complex(const complex&); // constexpr in C++14 + + T real() const; // constexpr in C++14 + T imag() const; // constexpr in C++14 + + void real(T); + void imag(T); + + complex& operator= (const T&); + complex& operator+=(const T&); + complex& operator-=(const T&); + complex& operator*=(const T&); + complex& operator/=(const T&); + + complex& operator=(const complex&); + template complex& operator= (const complex&); + template complex& operator+=(const complex&); + template complex& operator-=(const complex&); + template complex& operator*=(const complex&); + template complex& operator/=(const complex&); +}; + +template<> +class complex +{ +public: + typedef float value_type; + + constexpr complex(float re = 0.0f, float im = 0.0f); + explicit constexpr complex(const complex&); + explicit constexpr complex(const complex&); + + constexpr float real() const; + void real(float); + constexpr float imag() const; + void imag(float); + + complex& operator= (float); + complex& operator+=(float); + complex& operator-=(float); + complex& operator*=(float); + complex& operator/=(float); + + complex& operator=(const complex&); + template complex& operator= (const complex&); + template complex& operator+=(const complex&); + template complex& operator-=(const complex&); + template complex& operator*=(const complex&); + template complex& operator/=(const complex&); +}; + +template<> +class complex +{ +public: + typedef double value_type; + + constexpr complex(double re = 0.0, double im = 0.0); + constexpr complex(const complex&); + explicit constexpr complex(const complex&); + + constexpr double real() const; + void real(double); + constexpr double imag() const; + void imag(double); + + complex& operator= (double); + complex& operator+=(double); + complex& operator-=(double); + complex& operator*=(double); + complex& operator/=(double); + complex& operator=(const complex&); + + template complex& operator= (const complex&); + template complex& operator+=(const complex&); + template complex& operator-=(const complex&); + template complex& operator*=(const complex&); + template complex& operator/=(const complex&); +}; + +template<> +class complex +{ +public: + typedef long double value_type; + + constexpr complex(long double re = 0.0L, long double im = 0.0L); + constexpr complex(const complex&); + constexpr complex(const complex&); + + constexpr long double real() const; + void real(long double); + constexpr long double imag() const; + void imag(long double); + + complex& operator=(const complex&); + complex& operator= (long double); + complex& operator+=(long double); + complex& operator-=(long double); + complex& operator*=(long double); + complex& operator/=(long double); + + template complex& operator= (const complex&); + template complex& operator+=(const complex&); + template complex& operator-=(const complex&); + template complex& operator*=(const complex&); + template complex& operator/=(const complex&); +}; + +// 26.3.6 operators: +template complex operator+(const complex&, const complex&); +template complex operator+(const complex&, const T&); +template complex operator+(const T&, const complex&); +template complex operator-(const complex&, const complex&); +template complex operator-(const complex&, const T&); +template complex operator-(const T&, const complex&); +template complex operator*(const complex&, const complex&); +template complex operator*(const complex&, const T&); +template complex operator*(const T&, const complex&); +template complex operator/(const complex&, const complex&); +template complex operator/(const complex&, const T&); +template complex operator/(const T&, const complex&); +template complex operator+(const complex&); +template complex operator-(const complex&); +template bool operator==(const complex&, const complex&); // constexpr in C++14 +template bool operator==(const complex&, const T&); // constexpr in C++14 +template bool operator==(const T&, const complex&); // constexpr in C++14 +template bool operator!=(const complex&, const complex&); // constexpr in C++14 +template bool operator!=(const complex&, const T&); // constexpr in C++14 +template bool operator!=(const T&, const complex&); // constexpr in C++14 + +template + basic_istream& + operator>>(basic_istream&, complex&); +template + basic_ostream& + operator<<(basic_ostream&, const complex&); + +// 26.3.7 values: + +template T real(const complex&); // constexpr in C++14 + long double real(long double); // constexpr in C++14 + double real(double); // constexpr in C++14 +template double real(T); // constexpr in C++14 + float real(float); // constexpr in C++14 + +template T imag(const complex&); // constexpr in C++14 + long double imag(long double); // constexpr in C++14 + double imag(double); // constexpr in C++14 +template double imag(T); // constexpr in C++14 + float imag(float); // constexpr in C++14 + +template T abs(const complex&); + +template T arg(const complex&); + long double arg(long double); + double arg(double); +template double arg(T); + float arg(float); + +template T norm(const complex&); + long double norm(long double); + double norm(double); +template double norm(T); + float norm(float); + +template complex conj(const complex&); + complex conj(long double); + complex conj(double); +template complex conj(T); + complex conj(float); + +template complex proj(const complex&); + complex proj(long double); + complex proj(double); +template complex proj(T); + complex proj(float); + +template complex polar(const T&, const T& = 0); + +// 26.3.8 transcendentals: +template complex acos(const complex&); +template complex asin(const complex&); +template complex atan(const complex&); +template complex acosh(const complex&); +template complex asinh(const complex&); +template complex atanh(const complex&); +template complex cos (const complex&); +template complex cosh (const complex&); +template complex exp (const complex&); +template complex log (const complex&); +template complex log10(const complex&); + +template complex pow(const complex&, const T&); +template complex pow(const complex&, const complex&); +template complex pow(const T&, const complex&); + +template complex sin (const complex&); +template complex sinh (const complex&); +template complex sqrt (const complex&); +template complex tan (const complex&); +template complex tanh (const complex&); + +template + basic_istream& + operator>>(basic_istream& is, complex& x); + +template + basic_ostream& + operator<<(basic_ostream& o, const complex& x); + +} // std + +*/ + +#include <__config> +#include +#include +#include +#include +#if defined(_LIBCPP_NO_EXCEPTIONS) + #include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template class _LIBCPP_TYPE_VIS_ONLY complex; + +template complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w); +template complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y); + +template +class _LIBCPP_TYPE_VIS_ONLY complex +{ +public: + typedef _Tp value_type; +private: + value_type __re_; + value_type __im_; +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + complex(const value_type& __re = value_type(), const value_type& __im = value_type()) + : __re_(__re), __im_(__im) {} + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + complex(const complex<_Xp>& __c) + : __re_(__c.real()), __im_(__c.imag()) {} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;} + + _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} + _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} + + _LIBCPP_INLINE_VISIBILITY complex& operator= (const value_type& __re) + {__re_ = __re; __im_ = value_type(); return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator+=(const value_type& __re) {__re_ += __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;} + + template _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) + { + __re_ = __c.real(); + __im_ = __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) + { + __re_ += __c.real(); + __im_ += __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) + { + __re_ -= __c.real(); + __im_ -= __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) + { + *this = *this * complex(__c.real(), __c.imag()); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) + { + *this = *this / complex(__c.real(), __c.imag()); + return *this; + } +}; + +template<> class _LIBCPP_TYPE_VIS_ONLY complex; +template<> class _LIBCPP_TYPE_VIS_ONLY complex; + +template<> +class _LIBCPP_TYPE_VIS_ONLY complex +{ + float __re_; + float __im_; +public: + typedef float value_type; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f) + : __re_(__re), __im_(__im) {} + explicit _LIBCPP_CONSTEXPR complex(const complex& __c); + explicit _LIBCPP_CONSTEXPR complex(const complex& __c); + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;} + + _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} + _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} + + _LIBCPP_INLINE_VISIBILITY complex& operator= (float __re) + {__re_ = __re; __im_ = value_type(); return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator+=(float __re) {__re_ += __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator-=(float __re) {__re_ -= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;} + + template _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) + { + __re_ = __c.real(); + __im_ = __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) + { + __re_ += __c.real(); + __im_ += __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) + { + __re_ -= __c.real(); + __im_ -= __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) + { + *this = *this * complex(__c.real(), __c.imag()); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) + { + *this = *this / complex(__c.real(), __c.imag()); + return *this; + } +}; + +template<> +class _LIBCPP_TYPE_VIS_ONLY complex +{ + double __re_; + double __im_; +public: + typedef double value_type; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0) + : __re_(__re), __im_(__im) {} + _LIBCPP_CONSTEXPR complex(const complex& __c); + explicit _LIBCPP_CONSTEXPR complex(const complex& __c); + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;} + + _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} + _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} + + _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re) + {__re_ = __re; __im_ = value_type(); return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;} + + template _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) + { + __re_ = __c.real(); + __im_ = __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) + { + __re_ += __c.real(); + __im_ += __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) + { + __re_ -= __c.real(); + __im_ -= __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) + { + *this = *this * complex(__c.real(), __c.imag()); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) + { + *this = *this / complex(__c.real(), __c.imag()); + return *this; + } +}; + +template<> +class _LIBCPP_TYPE_VIS_ONLY complex +{ + long double __re_; + long double __im_; +public: + typedef long double value_type; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L) + : __re_(__re), __im_(__im) {} + _LIBCPP_CONSTEXPR complex(const complex& __c); + _LIBCPP_CONSTEXPR complex(const complex& __c); + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;} + + _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} + _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} + + _LIBCPP_INLINE_VISIBILITY complex& operator= (long double __re) + {__re_ = __re; __im_ = value_type(); return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator+=(long double __re) {__re_ += __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator-=(long double __re) {__re_ -= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;} + + template _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) + { + __re_ = __c.real(); + __im_ = __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) + { + __re_ += __c.real(); + __im_ += __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) + { + __re_ -= __c.real(); + __im_ -= __c.imag(); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) + { + *this = *this * complex(__c.real(), __c.imag()); + return *this; + } + template _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) + { + *this = *this / complex(__c.real(), __c.imag()); + return *this; + } +}; + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +complex::complex(const complex& __c) + : __re_(__c.real()), __im_(__c.imag()) {} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +complex::complex(const complex& __c) + : __re_(__c.real()), __im_(__c.imag()) {} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +complex::complex(const complex& __c) + : __re_(__c.real()), __im_(__c.imag()) {} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +complex::complex(const complex& __c) + : __re_(__c.real()), __im_(__c.imag()) {} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +complex::complex(const complex& __c) + : __re_(__c.real()), __im_(__c.imag()) {} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +complex::complex(const complex& __c) + : __re_(__c.real()), __im_(__c.imag()) {} + +// 26.3.6 operators: + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) +{ + complex<_Tp> __t(__x); + __t += __y; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator+(const complex<_Tp>& __x, const _Tp& __y) +{ + complex<_Tp> __t(__x); + __t += __y; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator+(const _Tp& __x, const complex<_Tp>& __y) +{ + complex<_Tp> __t(__y); + __t += __x; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) +{ + complex<_Tp> __t(__x); + __t -= __y; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator-(const complex<_Tp>& __x, const _Tp& __y) +{ + complex<_Tp> __t(__x); + __t -= __y; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator-(const _Tp& __x, const complex<_Tp>& __y) +{ + complex<_Tp> __t(-__y); + __t += __x; + return __t; +} + +template +complex<_Tp> +operator*(const complex<_Tp>& __z, const complex<_Tp>& __w) +{ + _Tp __a = __z.real(); + _Tp __b = __z.imag(); + _Tp __c = __w.real(); + _Tp __d = __w.imag(); + _Tp __ac = __a * __c; + _Tp __bd = __b * __d; + _Tp __ad = __a * __d; + _Tp __bc = __b * __c; + _Tp __x = __ac - __bd; + _Tp __y = __ad + __bc; + if (isnan(__x) && isnan(__y)) + { + bool __recalc = false; + if (isinf(__a) || isinf(__b)) + { + __a = copysign(isinf(__a) ? _Tp(1) : _Tp(0), __a); + __b = copysign(isinf(__b) ? _Tp(1) : _Tp(0), __b); + if (isnan(__c)) + __c = copysign(_Tp(0), __c); + if (isnan(__d)) + __d = copysign(_Tp(0), __d); + __recalc = true; + } + if (isinf(__c) || isinf(__d)) + { + __c = copysign(isinf(__c) ? _Tp(1) : _Tp(0), __c); + __d = copysign(isinf(__d) ? _Tp(1) : _Tp(0), __d); + if (isnan(__a)) + __a = copysign(_Tp(0), __a); + if (isnan(__b)) + __b = copysign(_Tp(0), __b); + __recalc = true; + } + if (!__recalc && (isinf(__ac) || isinf(__bd) || + isinf(__ad) || isinf(__bc))) + { + if (isnan(__a)) + __a = copysign(_Tp(0), __a); + if (isnan(__b)) + __b = copysign(_Tp(0), __b); + if (isnan(__c)) + __c = copysign(_Tp(0), __c); + if (isnan(__d)) + __d = copysign(_Tp(0), __d); + __recalc = true; + } + if (__recalc) + { + __x = _Tp(INFINITY) * (__a * __c - __b * __d); + __y = _Tp(INFINITY) * (__a * __d + __b * __c); + } + } + return complex<_Tp>(__x, __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator*(const complex<_Tp>& __x, const _Tp& __y) +{ + complex<_Tp> __t(__x); + __t *= __y; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator*(const _Tp& __x, const complex<_Tp>& __y) +{ + complex<_Tp> __t(__y); + __t *= __x; + return __t; +} + +template +complex<_Tp> +operator/(const complex<_Tp>& __z, const complex<_Tp>& __w) +{ + int __ilogbw = 0; + _Tp __a = __z.real(); + _Tp __b = __z.imag(); + _Tp __c = __w.real(); + _Tp __d = __w.imag(); + _Tp __logbw = logb(fmax(fabs(__c), fabs(__d))); + if (isfinite(__logbw)) + { + __ilogbw = static_cast(__logbw); + __c = scalbn(__c, -__ilogbw); + __d = scalbn(__d, -__ilogbw); + } + _Tp __denom = __c * __c + __d * __d; + _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); + _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw); + if (isnan(__x) && isnan(__y)) + { + if ((__denom == _Tp(0)) && (!isnan(__a) || !isnan(__b))) + { + __x = copysign(_Tp(INFINITY), __c) * __a; + __y = copysign(_Tp(INFINITY), __c) * __b; + } + else if ((isinf(__a) || isinf(__b)) && isfinite(__c) && isfinite(__d)) + { + __a = copysign(isinf(__a) ? _Tp(1) : _Tp(0), __a); + __b = copysign(isinf(__b) ? _Tp(1) : _Tp(0), __b); + __x = _Tp(INFINITY) * (__a * __c + __b * __d); + __y = _Tp(INFINITY) * (__b * __c - __a * __d); + } + else if (isinf(__logbw) && __logbw > _Tp(0) && isfinite(__a) && isfinite(__b)) + { + __c = copysign(isinf(__c) ? _Tp(1) : _Tp(0), __c); + __d = copysign(isinf(__d) ? _Tp(1) : _Tp(0), __d); + __x = _Tp(0) * (__a * __c + __b * __d); + __y = _Tp(0) * (__b * __c - __a * __d); + } + } + return complex<_Tp>(__x, __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator/(const complex<_Tp>& __x, const _Tp& __y) +{ + return complex<_Tp>(__x.real() / __y, __x.imag() / __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator/(const _Tp& __x, const complex<_Tp>& __y) +{ + complex<_Tp> __t(__x); + __t /= __y; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator+(const complex<_Tp>& __x) +{ + return __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +operator-(const complex<_Tp>& __x) +{ + return complex<_Tp>(-__x.real(), -__x.imag()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) +{ + return __x.real() == __y.real() && __x.imag() == __y.imag(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator==(const complex<_Tp>& __x, const _Tp& __y) +{ + return __x.real() == __y && __x.imag() == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator==(const _Tp& __x, const complex<_Tp>& __y) +{ + return __x == __y.real() && 0 == __y.imag(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator!=(const complex<_Tp>& __x, const _Tp& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator!=(const _Tp& __x, const complex<_Tp>& __y) +{ + return !(__x == __y); +} + +// 26.3.7 values: + +// real + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp +real(const complex<_Tp>& __c) +{ + return __c.real(); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +long double +real(long double __re) +{ + return __re; +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +double +real(double __re) +{ + return __re; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +typename enable_if +< + is_integral<_Tp>::value, + double +>::type +real(_Tp __re) +{ + return __re; +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +float +real(float __re) +{ + return __re; +} + +// imag + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp +imag(const complex<_Tp>& __c) +{ + return __c.imag(); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +long double +imag(long double __re) +{ + return 0; +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +double +imag(double __re) +{ + return 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +typename enable_if +< + is_integral<_Tp>::value, + double +>::type +imag(_Tp __re) +{ + return 0; +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +float +imag(float __re) +{ + return 0; +} + +// abs + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +abs(const complex<_Tp>& __c) +{ + return hypot(__c.real(), __c.imag()); +} + +// arg + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +arg(const complex<_Tp>& __c) +{ + return atan2(__c.imag(), __c.real()); +} + +inline _LIBCPP_INLINE_VISIBILITY +long double +arg(long double __re) +{ + return atan2l(0.L, __re); +} + +inline _LIBCPP_INLINE_VISIBILITY +double +arg(double __re) +{ + return atan2(0., __re); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value, + double +>::type +arg(_Tp __re) +{ + return atan2(0., __re); +} + +inline _LIBCPP_INLINE_VISIBILITY +float +arg(float __re) +{ + return atan2f(0.F, __re); +} + +// norm + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +norm(const complex<_Tp>& __c) +{ + if (isinf(__c.real())) + return abs(__c.real()); + if (isinf(__c.imag())) + return abs(__c.imag()); + return __c.real() * __c.real() + __c.imag() * __c.imag(); +} + +inline _LIBCPP_INLINE_VISIBILITY +long double +norm(long double __re) +{ + return __re * __re; +} + +inline _LIBCPP_INLINE_VISIBILITY +double +norm(double __re) +{ + return __re * __re; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value, + double +>::type +norm(_Tp __re) +{ + return (double)__re * __re; +} + +inline _LIBCPP_INLINE_VISIBILITY +float +norm(float __re) +{ + return __re * __re; +} + +// conj + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +conj(const complex<_Tp>& __c) +{ + return complex<_Tp>(__c.real(), -__c.imag()); +} + +inline _LIBCPP_INLINE_VISIBILITY +complex +conj(long double __re) +{ + return complex(__re); +} + +inline _LIBCPP_INLINE_VISIBILITY +complex +conj(double __re) +{ + return complex(__re); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value, + complex +>::type +conj(_Tp __re) +{ + return complex(__re); +} + +inline _LIBCPP_INLINE_VISIBILITY +complex +conj(float __re) +{ + return complex(__re); +} + +// proj + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +proj(const complex<_Tp>& __c) +{ + std::complex<_Tp> __r = __c; + if (isinf(__c.real()) || isinf(__c.imag())) + __r = complex<_Tp>(INFINITY, copysign(_Tp(0), __c.imag())); + return __r; +} + +inline _LIBCPP_INLINE_VISIBILITY +complex +proj(long double __re) +{ + if (isinf(__re)) + __re = abs(__re); + return complex(__re); +} + +inline _LIBCPP_INLINE_VISIBILITY +complex +proj(double __re) +{ + if (isinf(__re)) + __re = abs(__re); + return complex(__re); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_integral<_Tp>::value, + complex +>::type +proj(_Tp __re) +{ + return complex(__re); +} + +inline _LIBCPP_INLINE_VISIBILITY +complex +proj(float __re) +{ + if (isinf(__re)) + __re = abs(__re); + return complex(__re); +} + +// polar + +template +complex<_Tp> +polar(const _Tp& __rho, const _Tp& __theta = _Tp(0)) +{ + if (isnan(__rho) || signbit(__rho)) + return complex<_Tp>(_Tp(NAN), _Tp(NAN)); + if (isnan(__theta)) + { + if (isinf(__rho)) + return complex<_Tp>(__rho, __theta); + return complex<_Tp>(__theta, __theta); + } + if (isinf(__theta)) + { + if (isinf(__rho)) + return complex<_Tp>(__rho, _Tp(NAN)); + return complex<_Tp>(_Tp(NAN), _Tp(NAN)); + } + _Tp __x = __rho * cos(__theta); + if (isnan(__x)) + __x = 0; + _Tp __y = __rho * sin(__theta); + if (isnan(__y)) + __y = 0; + return complex<_Tp>(__x, __y); +} + +// log + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +log(const complex<_Tp>& __x) +{ + return complex<_Tp>(log(abs(__x)), arg(__x)); +} + +// log10 + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +log10(const complex<_Tp>& __x) +{ + return log(__x) / log(_Tp(10)); +} + +// sqrt + +template +complex<_Tp> +sqrt(const complex<_Tp>& __x) +{ + if (isinf(__x.imag())) + return complex<_Tp>(_Tp(INFINITY), __x.imag()); + if (isinf(__x.real())) + { + if (__x.real() > _Tp(0)) + return complex<_Tp>(__x.real(), isnan(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag())); + return complex<_Tp>(isnan(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag())); + } + return polar(sqrt(abs(__x)), arg(__x) / _Tp(2)); +} + +// exp + +template +complex<_Tp> +exp(const complex<_Tp>& __x) +{ + _Tp __i = __x.imag(); + if (isinf(__x.real())) + { + if (__x.real() < _Tp(0)) + { + if (!isfinite(__i)) + __i = _Tp(1); + } + else if (__i == 0 || !isfinite(__i)) + { + if (isinf(__i)) + __i = _Tp(NAN); + return complex<_Tp>(__x.real(), __i); + } + } + else if (isnan(__x.real()) && __x.imag() == 0) + return __x; + _Tp __e = exp(__x.real()); + return complex<_Tp>(__e * cos(__i), __e * sin(__i)); +} + +// pow + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +pow(const complex<_Tp>& __x, const complex<_Tp>& __y) +{ + return exp(__y * log(__x)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +complex::type> +pow(const complex<_Tp>& __x, const complex<_Up>& __y) +{ + typedef complex::type> result_type; + return _VSTD::pow(result_type(__x), result_type(__y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_arithmetic<_Up>::value, + complex::type> +>::type +pow(const complex<_Tp>& __x, const _Up& __y) +{ + typedef complex::type> result_type; + return _VSTD::pow(result_type(__x), result_type(__y)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_arithmetic<_Tp>::value, + complex::type> +>::type +pow(const _Tp& __x, const complex<_Up>& __y) +{ + typedef complex::type> result_type; + return _VSTD::pow(result_type(__x), result_type(__y)); +} + +// asinh + +template +complex<_Tp> +asinh(const complex<_Tp>& __x) +{ + const _Tp __pi(atan2(+0., -0.)); + if (isinf(__x.real())) + { + if (isnan(__x.imag())) + return __x; + if (isinf(__x.imag())) + return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag())); + return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag())); + } + if (isnan(__x.real())) + { + if (isinf(__x.imag())) + return complex<_Tp>(__x.imag(), __x.real()); + if (__x.imag() == 0) + return __x; + return complex<_Tp>(__x.real(), __x.real()); + } + if (isinf(__x.imag())) + return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag())); + complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) + _Tp(1))); + return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag())); +} + +// acosh + +template +complex<_Tp> +acosh(const complex<_Tp>& __x) +{ + const _Tp __pi(atan2(+0., -0.)); + if (isinf(__x.real())) + { + if (isnan(__x.imag())) + return complex<_Tp>(abs(__x.real()), __x.imag()); + if (isinf(__x.imag())) + { + if (__x.real() > 0) + return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag())); + else + return complex<_Tp>(-__x.real(), copysign(__pi * _Tp(0.75), __x.imag())); + } + if (__x.real() < 0) + return complex<_Tp>(-__x.real(), copysign(__pi, __x.imag())); + return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag())); + } + if (isnan(__x.real())) + { + if (isinf(__x.imag())) + return complex<_Tp>(abs(__x.imag()), __x.real()); + return complex<_Tp>(__x.real(), __x.real()); + } + if (isinf(__x.imag())) + return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag())); + complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) - _Tp(1))); + return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag())); +} + +// atanh + +template +complex<_Tp> +atanh(const complex<_Tp>& __x) +{ + const _Tp __pi(atan2(+0., -0.)); + if (isinf(__x.imag())) + { + return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag())); + } + if (isnan(__x.imag())) + { + if (isinf(__x.real()) || __x.real() == 0) + return complex<_Tp>(copysign(_Tp(0), __x.real()), __x.imag()); + return complex<_Tp>(__x.imag(), __x.imag()); + } + if (isnan(__x.real())) + { + return complex<_Tp>(__x.real(), __x.real()); + } + if (isinf(__x.real())) + { + return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag())); + } + if (abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0)) + { + return complex<_Tp>(copysign(_Tp(INFINITY), __x.real()), copysign(_Tp(0), __x.imag())); + } + complex<_Tp> __z = log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2); + return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag())); +} + +// sinh + +template +complex<_Tp> +sinh(const complex<_Tp>& __x) +{ + if (isinf(__x.real()) && !isfinite(__x.imag())) + return complex<_Tp>(__x.real(), _Tp(NAN)); + if (__x.real() == 0 && !isfinite(__x.imag())) + return complex<_Tp>(__x.real(), _Tp(NAN)); + if (__x.imag() == 0 && !isfinite(__x.real())) + return __x; + return complex<_Tp>(sinh(__x.real()) * cos(__x.imag()), cosh(__x.real()) * sin(__x.imag())); +} + +// cosh + +template +complex<_Tp> +cosh(const complex<_Tp>& __x) +{ + if (isinf(__x.real()) && !isfinite(__x.imag())) + return complex<_Tp>(abs(__x.real()), _Tp(NAN)); + if (__x.real() == 0 && !isfinite(__x.imag())) + return complex<_Tp>(_Tp(NAN), __x.real()); + if (__x.real() == 0 && __x.imag() == 0) + return complex<_Tp>(_Tp(1), __x.imag()); + if (__x.imag() == 0 && !isfinite(__x.real())) + return complex<_Tp>(abs(__x.real()), __x.imag()); + return complex<_Tp>(cosh(__x.real()) * cos(__x.imag()), sinh(__x.real()) * sin(__x.imag())); +} + +// tanh + +template +complex<_Tp> +tanh(const complex<_Tp>& __x) +{ + if (isinf(__x.real())) + { + if (!isfinite(__x.imag())) + return complex<_Tp>(_Tp(1), _Tp(0)); + return complex<_Tp>(_Tp(1), copysign(_Tp(0), sin(_Tp(2) * __x.imag()))); + } + if (isnan(__x.real()) && __x.imag() == 0) + return __x; + _Tp __2r(_Tp(2) * __x.real()); + _Tp __2i(_Tp(2) * __x.imag()); + _Tp __d(cosh(__2r) + cos(__2i)); + _Tp __2rsh(sinh(__2r)); + if (isinf(__2rsh) && isinf(__d)) + return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1), + __2i > _Tp(0) ? _Tp(0) : _Tp(-0.)); + return complex<_Tp>(__2rsh/__d, sin(__2i)/__d); +} + +// asin + +template +complex<_Tp> +asin(const complex<_Tp>& __x) +{ + complex<_Tp> __z = asinh(complex<_Tp>(-__x.imag(), __x.real())); + return complex<_Tp>(__z.imag(), -__z.real()); +} + +// acos + +template +complex<_Tp> +acos(const complex<_Tp>& __x) +{ + const _Tp __pi(atan2(+0., -0.)); + if (isinf(__x.real())) + { + if (isnan(__x.imag())) + return complex<_Tp>(__x.imag(), __x.real()); + if (isinf(__x.imag())) + { + if (__x.real() < _Tp(0)) + return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag()); + return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag()); + } + if (__x.real() < _Tp(0)) + return complex<_Tp>(__pi, signbit(__x.imag()) ? -__x.real() : __x.real()); + return complex<_Tp>(_Tp(0), signbit(__x.imag()) ? __x.real() : -__x.real()); + } + if (isnan(__x.real())) + { + if (isinf(__x.imag())) + return complex<_Tp>(__x.real(), -__x.imag()); + return complex<_Tp>(__x.real(), __x.real()); + } + if (isinf(__x.imag())) + return complex<_Tp>(__pi/_Tp(2), -__x.imag()); + if (__x.real() == 0) + return complex<_Tp>(__pi/_Tp(2), -__x.imag()); + complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) - _Tp(1))); + if (signbit(__x.imag())) + return complex<_Tp>(abs(__z.imag()), abs(__z.real())); + return complex<_Tp>(abs(__z.imag()), -abs(__z.real())); +} + +// atan + +template +complex<_Tp> +atan(const complex<_Tp>& __x) +{ + complex<_Tp> __z = atanh(complex<_Tp>(-__x.imag(), __x.real())); + return complex<_Tp>(__z.imag(), -__z.real()); +} + +// sin + +template +complex<_Tp> +sin(const complex<_Tp>& __x) +{ + complex<_Tp> __z = sinh(complex<_Tp>(-__x.imag(), __x.real())); + return complex<_Tp>(__z.imag(), -__z.real()); +} + +// cos + +template +inline _LIBCPP_INLINE_VISIBILITY +complex<_Tp> +cos(const complex<_Tp>& __x) +{ + return cosh(complex<_Tp>(-__x.imag(), __x.real())); +} + +// tan + +template +complex<_Tp> +tan(const complex<_Tp>& __x) +{ + complex<_Tp> __z = tanh(complex<_Tp>(-__x.imag(), __x.real())); + return complex<_Tp>(__z.imag(), -__z.real()); +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) +{ + if (__is.good()) + { + ws(__is); + if (__is.peek() == _CharT('(')) + { + __is.get(); + _Tp __r; + __is >> __r; + if (!__is.fail()) + { + ws(__is); + _CharT __c = __is.peek(); + if (__c == _CharT(',')) + { + __is.get(); + _Tp __i; + __is >> __i; + if (!__is.fail()) + { + ws(__is); + __c = __is.peek(); + if (__c == _CharT(')')) + { + __is.get(); + __x = complex<_Tp>(__r, __i); + } + else + __is.setstate(ios_base::failbit); + } + else + __is.setstate(ios_base::failbit); + } + else if (__c == _CharT(')')) + { + __is.get(); + __x = complex<_Tp>(__r, _Tp(0)); + } + else + __is.setstate(ios_base::failbit); + } + else + __is.setstate(ios_base::failbit); + } + else + { + _Tp __r; + __is >> __r; + if (!__is.fail()) + __x = complex<_Tp>(__r, _Tp(0)); + else + __is.setstate(ios_base::failbit); + } + } + else + __is.setstate(ios_base::failbit); + return __is; +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) +{ + basic_ostringstream<_CharT, _Traits> __s; + __s.flags(__os.flags()); + __s.imbue(__os.getloc()); + __s.precision(__os.precision()); + __s << '(' << __x.real() << ',' << __x.imag() << ')'; + return __os << __s.str(); +} + +#if _LIBCPP_STD_VER > 11 +// Literal suffix for complex number literals [complex.literals] +inline namespace literals +{ + inline namespace complex_literals + { + constexpr complex operator""il(long double __im) + { + return { 0.0l, __im }; + } + + constexpr complex operator""il(unsigned long long __im) + { + return { 0.0l, static_cast(__im) }; + } + + + constexpr complex operator""i(long double __im) + { + return { 0.0, static_cast(__im) }; + } + + constexpr complex operator""i(unsigned long long __im) + { + return { 0.0, static_cast(__im) }; + } + + + constexpr complex operator""if(long double __im) + { + return { 0.0f, static_cast(__im) }; + } + + constexpr complex operator""if(unsigned long long __im) + { + return { 0.0f, static_cast(__im) }; + } + } +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_COMPLEX diff --git a/headers/libs/libc++/complex.h b/headers/libs/libc++/complex.h new file mode 100644 index 0000000000..c2359665ad --- /dev/null +++ b/headers/libs/libc++/complex.h @@ -0,0 +1,37 @@ +// -*- C++ -*- +//===--------------------------- complex.h --------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_COMPLEX_H +#define _LIBCPP_COMPLEX_H + +/* + complex.h synopsis + +#include + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifdef __cplusplus + +#include + +#else // __cplusplus + +#include_next + +#endif // __cplusplus + +#endif // _LIBCPP_COMPLEX_H diff --git a/headers/libs/libc++/condition_variable b/headers/libs/libc++/condition_variable new file mode 100644 index 0000000000..10e0077016 --- /dev/null +++ b/headers/libs/libc++/condition_variable @@ -0,0 +1,267 @@ +// -*- C++ -*- +//===---------------------- condition_variable ----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CONDITION_VARIABLE +#define _LIBCPP_CONDITION_VARIABLE + +/* + condition_variable synopsis + +namespace std +{ + +enum class cv_status { no_timeout, timeout }; + +class condition_variable +{ +public: + condition_variable(); + ~condition_variable(); + + condition_variable(const condition_variable&) = delete; + condition_variable& operator=(const condition_variable&) = delete; + + void notify_one() noexcept; + void notify_all() noexcept; + + void wait(unique_lock& lock); + template + void wait(unique_lock& lock, Predicate pred); + + template + cv_status + wait_until(unique_lock& lock, + const chrono::time_point& abs_time); + + template + bool + wait_until(unique_lock& lock, + const chrono::time_point& abs_time, + Predicate pred); + + template + cv_status + wait_for(unique_lock& lock, + const chrono::duration& rel_time); + + template + bool + wait_for(unique_lock& lock, + const chrono::duration& rel_time, + Predicate pred); + + typedef pthread_cond_t* native_handle_type; + native_handle_type native_handle(); +}; + +void notify_all_at_thread_exit(condition_variable& cond, unique_lock lk); + +class condition_variable_any +{ +public: + condition_variable_any(); + ~condition_variable_any(); + + condition_variable_any(const condition_variable_any&) = delete; + condition_variable_any& operator=(const condition_variable_any&) = delete; + + void notify_one() noexcept; + void notify_all() noexcept; + + template + void wait(Lock& lock); + template + void wait(Lock& lock, Predicate pred); + + template + cv_status + wait_until(Lock& lock, + const chrono::time_point& abs_time); + + template + bool + wait_until(Lock& lock, + const chrono::time_point& abs_time, + Predicate pred); + + template + cv_status + wait_for(Lock& lock, + const chrono::duration& rel_time); + + template + bool + wait_for(Lock& lock, + const chrono::duration& rel_time, + Predicate pred); +}; + +} // std + +*/ + +#include <__config> +#include <__mutex_base> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifndef _LIBCPP_HAS_NO_THREADS + +_LIBCPP_BEGIN_NAMESPACE_STD + +class _LIBCPP_TYPE_VIS condition_variable_any +{ + condition_variable __cv_; + shared_ptr __mut_; +public: + _LIBCPP_INLINE_VISIBILITY + condition_variable_any(); + + _LIBCPP_INLINE_VISIBILITY + void notify_one() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + void notify_all() _NOEXCEPT; + + template + void wait(_Lock& __lock); + template + _LIBCPP_INLINE_VISIBILITY + void wait(_Lock& __lock, _Predicate __pred); + + template + cv_status + wait_until(_Lock& __lock, + const chrono::time_point<_Clock, _Duration>& __t); + + template + bool + _LIBCPP_INLINE_VISIBILITY + wait_until(_Lock& __lock, + const chrono::time_point<_Clock, _Duration>& __t, + _Predicate __pred); + + template + cv_status + _LIBCPP_INLINE_VISIBILITY + wait_for(_Lock& __lock, + const chrono::duration<_Rep, _Period>& __d); + + template + bool + _LIBCPP_INLINE_VISIBILITY + wait_for(_Lock& __lock, + const chrono::duration<_Rep, _Period>& __d, + _Predicate __pred); +}; + +inline +condition_variable_any::condition_variable_any() + : __mut_(make_shared()) {} + +inline +void +condition_variable_any::notify_one() _NOEXCEPT +{ + {lock_guard __lx(*__mut_);} + __cv_.notify_one(); +} + +inline +void +condition_variable_any::notify_all() _NOEXCEPT +{ + {lock_guard __lx(*__mut_);} + __cv_.notify_all(); +} + +struct __lock_external +{ + template + void operator()(_Lock* __m) {__m->lock();} +}; + +template +void +condition_variable_any::wait(_Lock& __lock) +{ + shared_ptr __mut = __mut_; + unique_lock __lk(*__mut); + __lock.unlock(); + unique_ptr<_Lock, __lock_external> __lxx(&__lock); + lock_guard > __lx(__lk, adopt_lock); + __cv_.wait(__lk); +} // __mut_.unlock(), __lock.lock() + +template +inline +void +condition_variable_any::wait(_Lock& __lock, _Predicate __pred) +{ + while (!__pred()) + wait(__lock); +} + +template +cv_status +condition_variable_any::wait_until(_Lock& __lock, + const chrono::time_point<_Clock, _Duration>& __t) +{ + shared_ptr __mut = __mut_; + unique_lock __lk(*__mut); + __lock.unlock(); + unique_ptr<_Lock, __lock_external> __lxx(&__lock); + lock_guard > __lx(__lk, adopt_lock); + return __cv_.wait_until(__lk, __t); +} // __mut_.unlock(), __lock.lock() + +template +inline +bool +condition_variable_any::wait_until(_Lock& __lock, + const chrono::time_point<_Clock, _Duration>& __t, + _Predicate __pred) +{ + while (!__pred()) + if (wait_until(__lock, __t) == cv_status::timeout) + return __pred(); + return true; +} + +template +inline +cv_status +condition_variable_any::wait_for(_Lock& __lock, + const chrono::duration<_Rep, _Period>& __d) +{ + return wait_until(__lock, chrono::steady_clock::now() + __d); +} + +template +inline +bool +condition_variable_any::wait_for(_Lock& __lock, + const chrono::duration<_Rep, _Period>& __d, + _Predicate __pred) +{ + return wait_until(__lock, chrono::steady_clock::now() + __d, + _VSTD::move(__pred)); +} + +_LIBCPP_FUNC_VIS +void notify_all_at_thread_exit(condition_variable& cond, unique_lock lk); + +_LIBCPP_END_NAMESPACE_STD + +#endif // !_LIBCPP_HAS_NO_THREADS + +#endif // _LIBCPP_CONDITION_VARIABLE diff --git a/headers/libs/libc++/config_elast.h b/headers/libs/libc++/config_elast.h new file mode 100644 index 0000000000..9d6a76b0c0 --- /dev/null +++ b/headers/libs/libc++/config_elast.h @@ -0,0 +1,36 @@ +//===----------------------- config_elast.h -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CONFIG_ELAST +#define _LIBCPP_CONFIG_ELAST + +#if defined(_WIN32) +#include +#else +#include +#endif + +#if defined(ELAST) +#define _LIBCPP_ELAST ELAST +#elif defined(_NEWLIB_VERSION) +#define _LIBCPP_ELAST __ELASTERROR +#elif defined(__linux__) +#define _LIBCPP_ELAST 4095 +#elif defined(__APPLE__) +// No _LIBCPP_ELAST needed on Apple +#elif defined(__sun__) +#define _LIBCPP_ELAST ESTALE +#elif defined(_WIN32) +#define _LIBCPP_ELAST _sys_nerr +#else +// Warn here so that the person doing the libcxx port has an easier time: +#warning ELAST for this platform not yet implemented +#endif + +#endif // _LIBCPP_CONFIG_ELAST diff --git a/headers/libs/libc++/csetjmp b/headers/libs/libc++/csetjmp new file mode 100644 index 0000000000..58a9c73ab5 --- /dev/null +++ b/headers/libs/libc++/csetjmp @@ -0,0 +1,48 @@ +// -*- C++ -*- +//===--------------------------- csetjmp ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CSETJMP +#define _LIBCPP_CSETJMP + +/* + csetjmp synopsis + +Macros: + + setjmp + +namespace std +{ + +Types: + + jmp_buf + +void longjmp(jmp_buf env, int val); + +} // std + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::jmp_buf; +using ::longjmp; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CSETJMP diff --git a/headers/libs/libc++/csignal b/headers/libs/libc++/csignal new file mode 100644 index 0000000000..9728266187 --- /dev/null +++ b/headers/libs/libc++/csignal @@ -0,0 +1,58 @@ +// -*- C++ -*- +//===--------------------------- csignal ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CSIGNAL +#define _LIBCPP_CSIGNAL + +/* + csignal synopsis + +Macros: + + SIG_DFL + SIG_ERR + SIG_IGN + SIGABRT + SIGFPE + SIGILL + SIGINT + SIGSEGV + SIGTERM + +namespace std +{ + +Types: + + sig_atomic_t + +void (*signal(int sig, void (*func)(int)))(int); +int raise(int sig); + +} // std + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::sig_atomic_t; +using ::signal; +using ::raise; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CSIGNAL diff --git a/headers/libs/libc++/cstdarg b/headers/libs/libc++/cstdarg new file mode 100644 index 0000000000..c8b6999242 --- /dev/null +++ b/headers/libs/libc++/cstdarg @@ -0,0 +1,48 @@ +// -*- C++ -*- +//===--------------------------- cstdarg ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CSTDARG +#define _LIBCPP_CSTDARG + +/* + cstdarg synopsis + +Macros: + + type va_arg(va_list ap, type); + void va_copy(va_list dest, va_list src); // C99 + void va_end(va_list ap); + void va_start(va_list ap, parmN); + +namespace std +{ + +Types: + + va_list + +} // std + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::va_list; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CSTDARG diff --git a/headers/libs/libc++/cstdbool b/headers/libs/libc++/cstdbool new file mode 100644 index 0000000000..2c764a61f2 --- /dev/null +++ b/headers/libs/libc++/cstdbool @@ -0,0 +1,32 @@ +// -*- C++ -*- +//===--------------------------- cstdbool ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CSTDBOOL +#define _LIBCPP_CSTDBOOL + +/* + cstdbool synopsis + +Macros: + + __bool_true_false_are_defined + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#undef __bool_true_false_are_defined +#define __bool_true_false_are_defined 1 + +#endif // _LIBCPP_CSTDBOOL diff --git a/headers/libs/libc++/cstddef b/headers/libs/libc++/cstddef new file mode 100644 index 0000000000..edd106c001 --- /dev/null +++ b/headers/libs/libc++/cstddef @@ -0,0 +1,60 @@ +// -*- C++ -*- +//===--------------------------- cstddef ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CSTDDEF +#define _LIBCPP_CSTDDEF + +/* + cstddef synopsis + +Macros: + + offsetof(type,member-designator) + NULL + +namespace std +{ + +Types: + + ptrdiff_t + size_t + max_align_t + nullptr_t + +} // std + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +// Don't include our own ; we don't want to declare ::nullptr_t. +#include_next +#include <__nullptr> + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::ptrdiff_t; +using ::size_t; + +#if defined(__CLANG_MAX_ALIGN_T_DEFINED) || defined(_GCC_MAX_ALIGN_T) +// Re-use the compiler's max_align_t where possible. +using ::max_align_t; +#else +typedef long double max_align_t; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CSTDDEF diff --git a/headers/libs/libc++/cstdint b/headers/libs/libc++/cstdint new file mode 100644 index 0000000000..7a187d3ebf --- /dev/null +++ b/headers/libs/libc++/cstdint @@ -0,0 +1,191 @@ +// -*- C++ -*- +//===--------------------------- cstdint ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CSTDINT +#define _LIBCPP_CSTDINT + +/* + cstdint synopsis + +Macros: + + INT8_MIN + INT16_MIN + INT32_MIN + INT64_MIN + + INT8_MAX + INT16_MAX + INT32_MAX + INT64_MAX + + UINT8_MAX + UINT16_MAX + UINT32_MAX + UINT64_MAX + + INT_LEAST8_MIN + INT_LEAST16_MIN + INT_LEAST32_MIN + INT_LEAST64_MIN + + INT_LEAST8_MAX + INT_LEAST16_MAX + INT_LEAST32_MAX + INT_LEAST64_MAX + + UINT_LEAST8_MAX + UINT_LEAST16_MAX + UINT_LEAST32_MAX + UINT_LEAST64_MAX + + INT_FAST8_MIN + INT_FAST16_MIN + INT_FAST32_MIN + INT_FAST64_MIN + + INT_FAST8_MAX + INT_FAST16_MAX + INT_FAST32_MAX + INT_FAST64_MAX + + UINT_FAST8_MAX + UINT_FAST16_MAX + UINT_FAST32_MAX + UINT_FAST64_MAX + + INTPTR_MIN + INTPTR_MAX + UINTPTR_MAX + + INTMAX_MIN + INTMAX_MAX + + UINTMAX_MAX + + PTRDIFF_MIN + PTRDIFF_MAX + + SIG_ATOMIC_MIN + SIG_ATOMIC_MAX + + SIZE_MAX + + WCHAR_MIN + WCHAR_MAX + + WINT_MIN + WINT_MAX + + INT8_C(value) + INT16_C(value) + INT32_C(value) + INT64_C(value) + + UINT8_C(value) + UINT16_C(value) + UINT32_C(value) + UINT64_C(value) + + INTMAX_C(value) + UINTMAX_C(value) + +namespace std +{ + +Types: + + int8_t + int16_t + int32_t + int64_t + + uint8_t + uint16_t + uint32_t + uint64_t + + int_least8_t + int_least16_t + int_least32_t + int_least64_t + + uint_least8_t + uint_least16_t + uint_least32_t + uint_least64_t + + int_fast8_t + int_fast16_t + int_fast32_t + int_fast64_t + + uint_fast8_t + uint_fast16_t + uint_fast32_t + uint_fast64_t + + intptr_t + uintptr_t + + intmax_t + uintmax_t + +} // std +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using::int8_t; +using::int16_t; +using::int32_t; +using::int64_t; + +using::uint8_t; +using::uint16_t; +using::uint32_t; +using::uint64_t; + +using::int_least8_t; +using::int_least16_t; +using::int_least32_t; +using::int_least64_t; + +using::uint_least8_t; +using::uint_least16_t; +using::uint_least32_t; +using::uint_least64_t; + +using::int_fast8_t; +using::int_fast16_t; +using::int_fast32_t; +using::int_fast64_t; + +using::uint_fast8_t; +using::uint_fast16_t; +using::uint_fast32_t; +using::uint_fast64_t; + +using::intptr_t; +using::uintptr_t; + +using::intmax_t; +using::uintmax_t; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CSTDINT diff --git a/headers/libs/libc++/cstdio b/headers/libs/libc++/cstdio new file mode 100644 index 0000000000..50fdd34574 --- /dev/null +++ b/headers/libs/libc++/cstdio @@ -0,0 +1,174 @@ +// -*- C++ -*- +//===---------------------------- cstdio ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CSTDIO +#define _LIBCPP_CSTDIO + +/* + cstdio synopsis + +Macros: + + BUFSIZ + EOF + FILENAME_MAX + FOPEN_MAX + L_tmpnam + NULL + SEEK_CUR + SEEK_END + SEEK_SET + TMP_MAX + _IOFBF + _IOLBF + _IONBF + stderr + stdin + stdout + +namespace std +{ + +Types: + +FILE +fpos_t +size_t + +int remove(const char* filename); +int rename(const char* old, const char* new); +FILE* tmpfile(void); +char* tmpnam(char* s); +int fclose(FILE* stream); +int fflush(FILE* stream); +FILE* fopen(const char* restrict filename, const char* restrict mode); +FILE* freopen(const char* restrict filename, const char * restrict mode, + FILE * restrict stream); +void setbuf(FILE* restrict stream, char* restrict buf); +int setvbuf(FILE* restrict stream, char* restrict buf, int mode, size_t size); +int fprintf(FILE* restrict stream, const char* restrict format, ...); +int fscanf(FILE* restrict stream, const char * restrict format, ...); +int printf(const char* restrict format, ...); +int scanf(const char* restrict format, ...); +int snprintf(char* restrict s, size_t n, const char* restrict format, ...); // C99 +int sprintf(char* restrict s, const char* restrict format, ...); +int sscanf(const char* restrict s, const char* restrict format, ...); +int vfprintf(FILE* restrict stream, const char* restrict format, va_list arg); +int vfscanf(FILE* restrict stream, const char* restrict format, va_list arg); // C99 +int vprintf(const char* restrict format, va_list arg); +int vscanf(const char* restrict format, va_list arg); // C99 +int vsnprintf(char* restrict s, size_t n, const char* restrict format, // C99 + va_list arg); +int vsprintf(char* restrict s, const char* restrict format, va_list arg); +int vsscanf(const char* restrict s, const char* restrict format, va_list arg); // C99 +int fgetc(FILE* stream); +char* fgets(char* restrict s, int n, FILE* restrict stream); +int fputc(int c, FILE* stream); +int fputs(const char* restrict s, FILE* restrict stream); +int getc(FILE* stream); +int getchar(void); +char* gets(char* s); // removed in C++14 +int putc(int c, FILE* stream); +int putchar(int c); +int puts(const char* s); +int ungetc(int c, FILE* stream); +size_t fread(void* restrict ptr, size_t size, size_t nmemb, + FILE* restrict stream); +size_t fwrite(const void* restrict ptr, size_t size, size_t nmemb, + FILE* restrict stream); +int fgetpos(FILE* restrict stream, fpos_t* restrict pos); +int fseek(FILE* stream, long offset, int whence); +int fsetpos(FILE*stream, const fpos_t* pos); +long ftell(FILE* stream); +void rewind(FILE* stream); +void clearerr(FILE* stream); +int feof(FILE* stream); +int ferror(FILE* stream); +void perror(const char* s); + +} // std +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::FILE; +using ::fpos_t; +using ::size_t; + +using ::fclose; +using ::fflush; +using ::setbuf; +using ::setvbuf; +using ::fprintf; +using ::fscanf; +using ::snprintf; +using ::sprintf; +using ::sscanf; +#ifndef _LIBCPP_MSVCRT +using ::vfprintf; +using ::vfscanf; +using ::vsscanf; +#endif // _LIBCPP_MSVCRT +using ::vsnprintf; +using ::vsprintf; +using ::fgetc; +using ::fgets; +using ::fputc; +using ::fputs; +using ::getc; +using ::putc; +using ::ungetc; +using ::fread; +using ::fwrite; +using ::fgetpos; +using ::fseek; +using ::fsetpos; +using ::ftell; +using ::rewind; +using ::clearerr; +using ::feof; +using ::ferror; +using ::perror; + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +using ::fopen; +using ::freopen; +using ::remove; +using ::rename; +using ::tmpfile; +using ::tmpnam; +#endif + +#ifndef _LIBCPP_HAS_NO_STDIN +using ::getchar; +#if _LIBCPP_STD_VER <= 11 +using ::gets; +#endif +using ::scanf; +using ::vscanf; +#endif + +#ifndef _LIBCPP_HAS_NO_STDOUT +using ::printf; +using ::putchar; +using ::puts; +using ::vprintf; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CSTDIO diff --git a/headers/libs/libc++/cstdlib b/headers/libs/libc++/cstdlib new file mode 100644 index 0000000000..10ed231078 --- /dev/null +++ b/headers/libs/libc++/cstdlib @@ -0,0 +1,158 @@ +// -*- C++ -*- +//===--------------------------- cstdlib ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CSTDLIB +#define _LIBCPP_CSTDLIB + +/* + cstdlib synopsis + +Macros: + + EXIT_FAILURE + EXIT_SUCCESS + MB_CUR_MAX + NULL + RAND_MAX + +namespace std +{ + +Types: + + size_t + div_t + ldiv_t + lldiv_t // C99 + +double atof (const char* nptr); +int atoi (const char* nptr); +long atol (const char* nptr); +long long atoll(const char* nptr); // C99 +double strtod (const char* restrict nptr, char** restrict endptr); +float strtof (const char* restrict nptr, char** restrict endptr); // C99 +long double strtold (const char* restrict nptr, char** restrict endptr); // C99 +long strtol (const char* restrict nptr, char** restrict endptr, int base); +long long strtoll (const char* restrict nptr, char** restrict endptr, int base); // C99 +unsigned long strtoul (const char* restrict nptr, char** restrict endptr, int base); +unsigned long long strtoull(const char* restrict nptr, char** restrict endptr, int base); // C99 +int rand(void); +void srand(unsigned int seed); +void* calloc(size_t nmemb, size_t size); +void free(void* ptr); +void* malloc(size_t size); +void* realloc(void* ptr, size_t size); +void abort(void); +int atexit(void (*func)(void)); +void exit(int status); +void _Exit(int status); +char* getenv(const char* name); +int system(const char* string); +void* bsearch(const void* key, const void* base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)); +void qsort(void* base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)); +int abs( int j); +long abs( long j); +long long abs(long long j); // C++0X +long labs( long j); +long long llabs(long long j); // C99 +div_t div( int numer, int denom); +ldiv_t div( long numer, long denom); +lldiv_t div(long long numer, long long denom); // C++0X +ldiv_t ldiv( long numer, long denom); +lldiv_t lldiv(long long numer, long long denom); // C99 +int mblen(const char* s, size_t n); +int mbtowc(wchar_t* restrict pwc, const char* restrict s, size_t n); +int wctomb(char* s, wchar_t wchar); +size_t mbstowcs(wchar_t* restrict pwcs, const char* restrict s, size_t n); +size_t wcstombs(char* restrict s, const wchar_t* restrict pwcs, size_t n); +int at_quick_exit(void (*func)(void)) // C++11 +void quick_exit(int status); // C++11 +void *aligned_alloc(size_t alignment, size_t size); // C11 + +} // std + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::size_t; +using ::div_t; +using ::ldiv_t; +#ifndef _LIBCPP_HAS_NO_LONG_LONG +using ::lldiv_t; +#endif // _LIBCPP_HAS_NO_LONG_LONG +using ::atof; +using ::atoi; +using ::atol; +#ifndef _LIBCPP_HAS_NO_LONG_LONG +using ::atoll; +#endif // _LIBCPP_HAS_NO_LONG_LONG +using ::strtod; +using ::strtof; +using ::strtold; +using ::strtol; +#ifndef _LIBCPP_HAS_NO_LONG_LONG +using ::strtoll; +#endif // _LIBCPP_HAS_NO_LONG_LONG +using ::strtoul; +#ifndef _LIBCPP_HAS_NO_LONG_LONG +using ::strtoull; +#endif // _LIBCPP_HAS_NO_LONG_LONG +using ::rand; +using ::srand; +using ::calloc; +using ::free; +using ::malloc; +using ::realloc; +using ::abort; +using ::atexit; +using ::exit; +using ::_Exit; +using ::getenv; +using ::system; +using ::bsearch; +using ::qsort; +using ::abs; +using ::labs; +#ifndef _LIBCPP_HAS_NO_LONG_LONG +using ::llabs; +#endif // _LIBCPP_HAS_NO_LONG_LONG +using ::div; +using ::ldiv; +#ifndef _LIBCPP_HAS_NO_LONG_LONG +using ::lldiv; +#endif // _LIBCPP_HAS_NO_LONG_LONG +#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS +using ::mblen; +using ::mbtowc; +using ::wctomb; +#endif +using ::mbstowcs; +using ::wcstombs; +#ifdef _LIBCPP_HAS_QUICK_EXIT +using ::at_quick_exit; +using ::quick_exit; +#endif +#ifdef _LIBCPP_HAS_C11_FEATURES +using ::aligned_alloc; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CSTDLIB diff --git a/headers/libs/libc++/cstring b/headers/libs/libc++/cstring new file mode 100644 index 0000000000..d60b9923c6 --- /dev/null +++ b/headers/libs/libc++/cstring @@ -0,0 +1,114 @@ +// -*- C++ -*- +//===--------------------------- cstring ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CSTRING +#define _LIBCPP_CSTRING + +/* + cstring synopsis + +Macros: + + NULL + +namespace std +{ + +Types: + + size_t + +void* memcpy(void* restrict s1, const void* restrict s2, size_t n); +void* memmove(void* s1, const void* s2, size_t n); +char* strcpy (char* restrict s1, const char* restrict s2); +char* strncpy(char* restrict s1, const char* restrict s2, size_t n); +char* strcat (char* restrict s1, const char* restrict s2); +char* strncat(char* restrict s1, const char* restrict s2, size_t n); +int memcmp(const void* s1, const void* s2, size_t n); +int strcmp (const char* s1, const char* s2); +int strncmp(const char* s1, const char* s2, size_t n); +int strcoll(const char* s1, const char* s2); +size_t strxfrm(char* restrict s1, const char* restrict s2, size_t n); +const void* memchr(const void* s, int c, size_t n); + void* memchr( void* s, int c, size_t n); +const char* strchr(const char* s, int c); + char* strchr( char* s, int c); +size_t strcspn(const char* s1, const char* s2); +const char* strpbrk(const char* s1, const char* s2); + char* strpbrk( char* s1, const char* s2); +const char* strrchr(const char* s, int c); + char* strrchr( char* s, int c); +size_t strspn(const char* s1, const char* s2); +const char* strstr(const char* s1, const char* s2); + char* strstr( char* s1, const char* s2); +char* strtok(char* restrict s1, const char* restrict s2); +void* memset(void* s, int c, size_t n); +char* strerror(int errnum); +size_t strlen(const char* s); + +} // std + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::size_t; +using ::memcpy; +using ::memmove; +using ::strcpy; +using ::strncpy; +using ::strcat; +using ::strncat; +using ::memcmp; +using ::strcmp; +using ::strncmp; +using ::strcoll; +using ::strxfrm; + +using ::memchr; + +using ::strchr; + +using ::strcspn; + +using ::strpbrk; + +using ::strrchr; + +using ::strspn; + +using ::strstr; + +// MSVCRT, GNU libc and its derivates already have the correct prototype in #ifdef __cplusplus +#if !defined(__GLIBC__) && !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_) +inline _LIBCPP_INLINE_VISIBILITY char* strchr( char* __s, int __c) {return ::strchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY char* strpbrk( char* __s1, const char* __s2) {return ::strpbrk(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY char* strrchr( char* __s, int __c) {return ::strrchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY void* memchr( void* __s, int __c, size_t __n) {return ::memchr(__s, __c, __n);} +inline _LIBCPP_INLINE_VISIBILITY char* strstr( char* __s1, const char* __s2) {return ::strstr(__s1, __s2);} +#endif + +#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS +using ::strtok; +#endif +using ::memset; +using ::strerror; +using ::strlen; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CSTRING diff --git a/headers/libs/libc++/ctgmath b/headers/libs/libc++/ctgmath new file mode 100644 index 0000000000..535eb7dccd --- /dev/null +++ b/headers/libs/libc++/ctgmath @@ -0,0 +1,29 @@ +// -*- C++ -*- +//===-------------------------- ctgmath -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CTGMATH +#define _LIBCPP_CTGMATH + +/* + ctgmath synopsis + +#include +#include + +*/ + +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#endif // _LIBCPP_CTGMATH diff --git a/headers/libs/libc++/ctime b/headers/libs/libc++/ctime new file mode 100644 index 0000000000..da9e3290bb --- /dev/null +++ b/headers/libs/libc++/ctime @@ -0,0 +1,74 @@ +// -*- C++ -*- +//===---------------------------- ctime -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CTIME +#define _LIBCPP_CTIME + +/* + ctime synopsis + +Macros: + + NULL + CLOCKS_PER_SEC + +namespace std +{ + +Types: + + clock_t + size_t + time_t + tm + +clock_t clock(); +double difftime(time_t time1, time_t time0); +time_t mktime(tm* timeptr); +time_t time(time_t* timer); +char* asctime(const tm* timeptr); +char* ctime(const time_t* timer); +tm* gmtime(const time_t* timer); +tm* localtime(const time_t* timer); +size_t strftime(char* restrict s, size_t maxsize, const char* restrict format, + const tm* restrict timeptr); + +} // std + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::clock_t; +using ::size_t; +using ::time_t; +using ::tm; +using ::clock; +using ::difftime; +using ::mktime; +using ::time; +#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS +using ::asctime; +using ::ctime; +using ::gmtime; +using ::localtime; +#endif +using ::strftime; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CTIME diff --git a/headers/libs/libc++/ctype.h b/headers/libs/libc++/ctype.h new file mode 100644 index 0000000000..22d6c49be9 --- /dev/null +++ b/headers/libs/libc++/ctype.h @@ -0,0 +1,69 @@ +// -*- C++ -*- +//===---------------------------- ctype.h ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CTYPE_H +#define _LIBCPP_CTYPE_H + +/* + ctype.h synopsis + +int isalnum(int c); +int isalpha(int c); +int isblank(int c); // C99 +int iscntrl(int c); +int isdigit(int c); +int isgraph(int c); +int islower(int c); +int isprint(int c); +int ispunct(int c); +int isspace(int c); +int isupper(int c); +int isxdigit(int c); +int tolower(int c); +int toupper(int c); +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#include_next + +#ifdef __cplusplus + +#if defined(_LIBCPP_MSVCRT) +// We support including .h headers inside 'extern "C"' contexts, so switch +// back to C++ linkage before including these C++ headers. +extern "C++" { + #include "support/win32/support.h" + #include "support/win32/locale_win32.h" +} +#endif // _LIBCPP_MSVCRT + +#undef isalnum +#undef isalpha +#undef isblank +#undef iscntrl +#undef isdigit +#undef isgraph +#undef islower +#undef isprint +#undef ispunct +#undef isspace +#undef isupper +#undef isxdigit +#undef tolower +#undef toupper + +#endif + +#endif // _LIBCPP_CTYPE_H diff --git a/headers/libs/libc++/cwchar b/headers/libs/libc++/cwchar new file mode 100644 index 0000000000..ef4806db2b --- /dev/null +++ b/headers/libs/libc++/cwchar @@ -0,0 +1,218 @@ +// -*- C++ -*- +//===--------------------------- cwchar -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CWCHAR +#define _LIBCPP_CWCHAR + +/* + cwchar synopsis + +Macros: + + NULL + WCHAR_MAX + WCHAR_MIN + WEOF + +namespace std +{ + +Types: + + mbstate_t + size_t + tm + wint_t + +int fwprintf(FILE* restrict stream, const wchar_t* restrict format, ...); +int fwscanf(FILE* restrict stream, const wchar_t* restrict format, ...); +int swprintf(wchar_t* restrict s, size_t n, const wchar_t* restrict format, ...); +int swscanf(const wchar_t* restrict s, const wchar_t* restrict format, ...); +int vfwprintf(FILE* restrict stream, const wchar_t* restrict format, va_list arg); +int vfwscanf(FILE* restrict stream, const wchar_t* restrict format, va_list arg); // C99 +int vswprintf(wchar_t* restrict s, size_t n, const wchar_t* restrict format, va_list arg); +int vswscanf(const wchar_t* restrict s, const wchar_t* restrict format, va_list arg); // C99 +int vwprintf(const wchar_t* restrict format, va_list arg); +int vwscanf(const wchar_t* restrict format, va_list arg); // C99 +int wprintf(const wchar_t* restrict format, ...); +int wscanf(const wchar_t* restrict format, ...); +wint_t fgetwc(FILE* stream); +wchar_t* fgetws(wchar_t* restrict s, int n, FILE* restrict stream); +wint_t fputwc(wchar_t c, FILE* stream); +int fputws(const wchar_t* restrict s, FILE* restrict stream); +int fwide(FILE* stream, int mode); +wint_t getwc(FILE* stream); +wint_t getwchar(); +wint_t putwc(wchar_t c, FILE* stream); +wint_t putwchar(wchar_t c); +wint_t ungetwc(wint_t c, FILE* stream); +double wcstod(const wchar_t* restrict nptr, wchar_t** restrict endptr); +float wcstof(const wchar_t* restrict nptr, wchar_t** restrict endptr); // C99 +long double wcstold(const wchar_t* restrict nptr, wchar_t** restrict endptr); // C99 +long wcstol(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base); +long long wcstoll(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base); // C99 +unsigned long wcstoul(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base); +unsigned long long wcstoull(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base); // C99 +wchar_t* wcscpy(wchar_t* restrict s1, const wchar_t* restrict s2); +wchar_t* wcsncpy(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n); +wchar_t* wcscat(wchar_t* restrict s1, const wchar_t* restrict s2); +wchar_t* wcsncat(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n); +int wcscmp(const wchar_t* s1, const wchar_t* s2); +int wcscoll(const wchar_t* s1, const wchar_t* s2); +int wcsncmp(const wchar_t* s1, const wchar_t* s2, size_t n); +size_t wcsxfrm(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n); +const wchar_t* wcschr(const wchar_t* s, wchar_t c); + wchar_t* wcschr( wchar_t* s, wchar_t c); +size_t wcscspn(const wchar_t* s1, const wchar_t* s2); +size_t wcslen(const wchar_t* s); +const wchar_t* wcspbrk(const wchar_t* s1, const wchar_t* s2); + wchar_t* wcspbrk( wchar_t* s1, const wchar_t* s2); +const wchar_t* wcsrchr(const wchar_t* s, wchar_t c); + wchar_t* wcsrchr( wchar_t* s, wchar_t c); +size_t wcsspn(const wchar_t* s1, const wchar_t* s2); +const wchar_t* wcsstr(const wchar_t* s1, const wchar_t* s2); + wchar_t* wcsstr( wchar_t* s1, const wchar_t* s2); +wchar_t* wcstok(wchar_t* restrict s1, const wchar_t* restrict s2, wchar_t** restrict ptr); +const wchar_t* wmemchr(const wchar_t* s, wchar_t c, size_t n); + wchar_t* wmemchr( wchar_t* s, wchar_t c, size_t n); +int wmemcmp(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n); +wchar_t* wmemcpy(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n); +wchar_t* wmemmove(wchar_t* s1, const wchar_t* s2, size_t n); +wchar_t* wmemset(wchar_t* s, wchar_t c, size_t n); +size_t wcsftime(wchar_t* restrict s, size_t maxsize, const wchar_t* restrict format, + const tm* restrict timeptr); +wint_t btowc(int c); +int wctob(wint_t c); +int mbsinit(const mbstate_t* ps); +size_t mbrlen(const char* restrict s, size_t n, mbstate_t* restrict ps); +size_t mbrtowc(wchar_t* restrict pwc, const char* restrict s, size_t n, mbstate_t* restrict ps); +size_t wcrtomb(char* restrict s, wchar_t wc, mbstate_t* restrict ps); +size_t mbsrtowcs(wchar_t* restrict dst, const char** restrict src, size_t len, + mbstate_t* restrict ps); +size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len, + mbstate_t* restrict ps); + +} // std + +*/ + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::mbstate_t; +using ::size_t; +using ::tm; +using ::wint_t; +using ::FILE; +using ::fwprintf; +using ::fwscanf; +using ::swprintf; +using ::vfwprintf; +using ::vswprintf; +#ifndef _LIBCPP_MSVCRT +using ::swscanf; +using ::vfwscanf; +using ::vswscanf; +#endif // _LIBCPP_MSVCRT +using ::fgetwc; +using ::fgetws; +using ::fputwc; +using ::fputws; +using ::fwide; +using ::getwc; +using ::putwc; +using ::ungetwc; +using ::wcstod; +#ifndef _LIBCPP_MSVCRT +using ::wcstof; +using ::wcstold; +#endif // _LIBCPP_MSVCRT +using ::wcstol; +#ifndef _LIBCPP_HAS_NO_LONG_LONG +using ::wcstoll; +#endif // _LIBCPP_HAS_NO_LONG_LONG +using ::wcstoul; +#ifndef _LIBCPP_HAS_NO_LONG_LONG +using ::wcstoull; +#endif // _LIBCPP_HAS_NO_LONG_LONG +using ::wcscpy; +using ::wcsncpy; +using ::wcscat; +using ::wcsncat; +using ::wcscmp; +using ::wcscoll; +using ::wcsncmp; +using ::wcsxfrm; + +#ifdef _LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS +using ::wcschr; +using ::wcspbrk; +using ::wcsrchr; +using ::wcsstr; +using ::wmemchr; +#else +inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcschr(const wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY wchar_t* wcschr( wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);} + +inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcspbrk(const wchar_t* __s1, const wchar_t* __s2) {return ::wcspbrk(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY wchar_t* wcspbrk( wchar_t* __s1, const wchar_t* __s2) {return ::wcspbrk(__s1, __s2);} + +inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcsrchr(const wchar_t* __s, wchar_t __c) {return ::wcsrchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY wchar_t* wcsrchr( wchar_t* __s, wchar_t __c) {return ::wcsrchr(__s, __c);} + +inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcsstr(const wchar_t* __s1, const wchar_t* __s2) {return ::wcsstr(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY wchar_t* wcsstr( wchar_t* __s1, const wchar_t* __s2) {return ::wcsstr(__s1, __s2);} + +inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wmemchr(const wchar_t* __s, wchar_t __c, size_t __n) {return ::wmemchr(__s, __c, __n);} +inline _LIBCPP_INLINE_VISIBILITY wchar_t* wmemchr( wchar_t* __s, wchar_t __c, size_t __n) {return ::wmemchr(__s, __c, __n);} +#endif + +using ::wcscspn; +using ::wcslen; +using ::wcsspn; +using ::wcstok; +using ::wmemcmp; +using ::wmemcpy; +using ::wmemmove; +using ::wmemset; +using ::wcsftime; +using ::btowc; +using ::wctob; +using ::mbsinit; +using ::mbrlen; +using ::mbrtowc; +using ::wcrtomb; +using ::mbsrtowcs; +using ::wcsrtombs; + +#ifndef _LIBCPP_HAS_NO_STDIN +using ::getwchar; +#ifndef _LIBCPP_MSVCRT +using ::vwscanf; +#endif // _LIBCPP_MSVCRT +using ::wscanf; +#endif + +#ifndef _LIBCPP_HAS_NO_STDOUT +using ::putwchar; +using ::vwprintf; +using ::wprintf; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CWCHAR diff --git a/headers/libs/libc++/cwctype b/headers/libs/libc++/cwctype new file mode 100644 index 0000000000..25b2489edf --- /dev/null +++ b/headers/libs/libc++/cwctype @@ -0,0 +1,87 @@ +// -*- C++ -*- +//===--------------------------- cwctype ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CWCTYPE +#define _LIBCPP_CWCTYPE + +/* + cwctype synopsis + +Macros: + + WEOF + +namespace std +{ + +Types: + + wint_t + wctrans_t + wctype_t + +int iswalnum(wint_t wc); +int iswalpha(wint_t wc); +int iswblank(wint_t wc); // C99 +int iswcntrl(wint_t wc); +int iswdigit(wint_t wc); +int iswgraph(wint_t wc); +int iswlower(wint_t wc); +int iswprint(wint_t wc); +int iswpunct(wint_t wc); +int iswspace(wint_t wc); +int iswupper(wint_t wc); +int iswxdigit(wint_t wc); +int iswctype(wint_t wc, wctype_t desc); +wctype_t wctype(const char* property); +wint_t towlower(wint_t wc); +wint_t towupper(wint_t wc); +wint_t towctrans(wint_t wc, wctrans_t desc); +wctrans_t wctrans(const char* property); + +} // std + +*/ + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::wint_t; +using ::wctrans_t; +using ::wctype_t; +using ::iswalnum; +using ::iswalpha; +using ::iswblank; +using ::iswcntrl; +using ::iswdigit; +using ::iswgraph; +using ::iswlower; +using ::iswprint; +using ::iswpunct; +using ::iswspace; +using ::iswupper; +using ::iswxdigit; +using ::iswctype; +using ::wctype; +using ::towlower; +using ::towupper; +using ::towctrans; +using ::wctrans; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CWCTYPE diff --git a/headers/libs/libc++/deque b/headers/libs/libc++/deque new file mode 100644 index 0000000000..b0b778a56c --- /dev/null +++ b/headers/libs/libc++/deque @@ -0,0 +1,2906 @@ +// -*- C++ -*- +//===---------------------------- deque -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_DEQUE +#define _LIBCPP_DEQUE + +/* + deque synopsis + +namespace std +{ + +template > +class deque +{ +public: + // types: + typedef T value_type; + typedef Allocator allocator_type; + + typedef typename allocator_type::reference reference; + typedef typename allocator_type::const_reference const_reference; + typedef implementation-defined iterator; + typedef implementation-defined const_iterator; + typedef typename allocator_type::size_type size_type; + typedef typename allocator_type::difference_type difference_type; + + typedef typename allocator_type::pointer pointer; + typedef typename allocator_type::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // construct/copy/destroy: + deque() noexcept(is_nothrow_default_constructible::value); + explicit deque(const allocator_type& a); + explicit deque(size_type n); + explicit deque(size_type n, const allocator_type& a); // C++14 + deque(size_type n, const value_type& v); + deque(size_type n, const value_type& v, const allocator_type& a); + template + deque(InputIterator f, InputIterator l); + template + deque(InputIterator f, InputIterator l, const allocator_type& a); + deque(const deque& c); + deque(deque&& c) + noexcept(is_nothrow_move_constructible::value); + deque(initializer_list il, const Allocator& a = allocator_type()); + deque(const deque& c, const allocator_type& a); + deque(deque&& c, const allocator_type& a); + ~deque(); + + deque& operator=(const deque& c); + deque& operator=(deque&& c) + noexcept( + allocator_type::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value); + deque& operator=(initializer_list il); + + template + void assign(InputIterator f, InputIterator l); + void assign(size_type n, const value_type& v); + void assign(initializer_list il); + + allocator_type get_allocator() const noexcept; + + // iterators: + + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + // capacity: + size_type size() const noexcept; + size_type max_size() const noexcept; + void resize(size_type n); + void resize(size_type n, const value_type& v); + void shrink_to_fit(); + bool empty() const noexcept; + + // element access: + reference operator[](size_type i); + const_reference operator[](size_type i) const; + reference at(size_type i); + const_reference at(size_type i) const; + reference front(); + const_reference front() const; + reference back(); + const_reference back() const; + + // modifiers: + void push_front(const value_type& v); + void push_front(value_type&& v); + void push_back(const value_type& v); + void push_back(value_type&& v); + template void emplace_front(Args&&... args); + template void emplace_back(Args&&... args); + template iterator emplace(const_iterator p, Args&&... args); + iterator insert(const_iterator p, const value_type& v); + iterator insert(const_iterator p, value_type&& v); + iterator insert(const_iterator p, size_type n, const value_type& v); + template + iterator insert(const_iterator p, InputIterator f, InputIterator l); + iterator insert(const_iterator p, initializer_list il); + void pop_front(); + void pop_back(); + iterator erase(const_iterator p); + iterator erase(const_iterator f, const_iterator l); + void swap(deque& c) + noexcept(allocator_traits::is_always_equal::value); // C++17 + void clear() noexcept; +}; + +template + bool operator==(const deque& x, const deque& y); +template + bool operator< (const deque& x, const deque& y); +template + bool operator!=(const deque& x, const deque& y); +template + bool operator> (const deque& x, const deque& y); +template + bool operator>=(const deque& x, const deque& y); +template + bool operator<=(const deque& x, const deque& y); + +// specialized algorithms: +template + void swap(deque& x, deque& y) + noexcept(noexcept(x.swap(y))); + +} // std + +*/ + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#include <__config> +#include <__split_buffer> +#include +#include +#include +#include +#include + +#include <__undef_min_max> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template class __deque_base; +template > class _LIBCPP_TYPE_VIS_ONLY deque; + +template +class _LIBCPP_TYPE_VIS_ONLY __deque_iterator; + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +copy(_RAIter __f, + _RAIter __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, + typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0); + +template +_OutputIterator +copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + _OutputIterator __r); + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r); + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +copy_backward(_RAIter __f, + _RAIter __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, + typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0); + +template +_OutputIterator +copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + _OutputIterator __r); + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r); + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +move(_RAIter __f, + _RAIter __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, + typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0); + +template +_OutputIterator +move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + _OutputIterator __r); + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r); + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +move_backward(_RAIter __f, + _RAIter __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, + typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0); + +template +_OutputIterator +move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + _OutputIterator __r); + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r); + +template +struct __deque_block_size { + static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16; +}; + +template ::value +#endif + > +class _LIBCPP_TYPE_VIS_ONLY __deque_iterator +{ + typedef _MapPointer __map_iterator; +public: + typedef _Pointer pointer; + typedef _DiffType difference_type; +private: + __map_iterator __m_iter_; + pointer __ptr_; + + static const difference_type __block_size; +public: + typedef _ValueType value_type; + typedef random_access_iterator_tag iterator_category; + typedef _Reference reference; + + _LIBCPP_INLINE_VISIBILITY __deque_iterator() _NOEXCEPT +#if _LIBCPP_STD_VER > 11 + : __m_iter_(nullptr), __ptr_(nullptr) +#endif + {} + + template + _LIBCPP_INLINE_VISIBILITY + __deque_iterator(const __deque_iterator& __it, + typename enable_if::value>::type* = 0) _NOEXCEPT + : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {} + + _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *__ptr_;} + _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return __ptr_;} + + _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator++() + { + if (++__ptr_ - *__m_iter_ == __block_size) + { + ++__m_iter_; + __ptr_ = *__m_iter_; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY __deque_iterator operator++(int) + { + __deque_iterator __tmp = *this; + ++(*this); + return __tmp; + } + + _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator--() + { + if (__ptr_ == *__m_iter_) + { + --__m_iter_; + __ptr_ = *__m_iter_ + __block_size; + } + --__ptr_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY __deque_iterator operator--(int) + { + __deque_iterator __tmp = *this; + --(*this); + return __tmp; + } + + _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator+=(difference_type __n) + { + if (__n != 0) + { + __n += __ptr_ - *__m_iter_; + if (__n > 0) + { + __m_iter_ += __n / __block_size; + __ptr_ = *__m_iter_ + __n % __block_size; + } + else // (__n < 0) + { + difference_type __z = __block_size - 1 - __n; + __m_iter_ -= __z / __block_size; + __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size); + } + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator-=(difference_type __n) + { + return *this += -__n; + } + + _LIBCPP_INLINE_VISIBILITY __deque_iterator operator+(difference_type __n) const + { + __deque_iterator __t(*this); + __t += __n; + return __t; + } + + _LIBCPP_INLINE_VISIBILITY __deque_iterator operator-(difference_type __n) const + { + __deque_iterator __t(*this); + __t -= __n; + return __t; + } + + _LIBCPP_INLINE_VISIBILITY + friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it) + {return __it + __n;} + + _LIBCPP_INLINE_VISIBILITY + friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y) + { + if (__x != __y) + return (__x.__m_iter_ - __y.__m_iter_) * __block_size + + (__x.__ptr_ - *__x.__m_iter_) + - (__y.__ptr_ - *__y.__m_iter_); + return 0; + } + + _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const + {return *(*this + __n);} + + _LIBCPP_INLINE_VISIBILITY friend + bool operator==(const __deque_iterator& __x, const __deque_iterator& __y) + {return __x.__ptr_ == __y.__ptr_;} + + _LIBCPP_INLINE_VISIBILITY friend + bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y) + {return !(__x == __y);} + + _LIBCPP_INLINE_VISIBILITY friend + bool operator<(const __deque_iterator& __x, const __deque_iterator& __y) + {return __x.__m_iter_ < __y.__m_iter_ || + (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);} + + _LIBCPP_INLINE_VISIBILITY friend + bool operator>(const __deque_iterator& __x, const __deque_iterator& __y) + {return __y < __x;} + + _LIBCPP_INLINE_VISIBILITY friend + bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y) + {return !(__y < __x);} + + _LIBCPP_INLINE_VISIBILITY friend + bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y) + {return !(__x < __y);} + +private: + _LIBCPP_INLINE_VISIBILITY __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT + : __m_iter_(__m), __ptr_(__p) {} + + template friend class __deque_base; + template friend class _LIBCPP_TYPE_VIS_ONLY deque; + template + friend class _LIBCPP_TYPE_VIS_ONLY __deque_iterator; + + template + friend + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> + copy(_RAIter __f, + _RAIter __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, + typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*); + + template + friend + _OutputIterator + copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + _OutputIterator __r); + + template + friend + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> + copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r); + + template + friend + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> + copy_backward(_RAIter __f, + _RAIter __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, + typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*); + + template + friend + _OutputIterator + copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + _OutputIterator __r); + + template + friend + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> + copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r); + + template + friend + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> + move(_RAIter __f, + _RAIter __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, + typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*); + + template + friend + _OutputIterator + move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + _OutputIterator __r); + + template + friend + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> + move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r); + + template + friend + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> + move_backward(_RAIter __f, + _RAIter __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, + typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*); + + template + friend + _OutputIterator + move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + _OutputIterator __r); + + template + friend + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> + move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r); +}; + +template +const _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, + _DiffType, _BlockSize>::__block_size = + __deque_block_size<_ValueType, _DiffType>::value; + +// copy + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +copy(_RAIter __f, + _RAIter __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, + typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*) +{ + typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type; + typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer; + const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size; + while (__f != __l) + { + pointer __rb = __r.__ptr_; + pointer __re = *__r.__m_iter_ + __block_size; + difference_type __bs = __re - __rb; + difference_type __n = __l - __f; + _RAIter __m = __l; + if (__n > __bs) + { + __n = __bs; + __m = __f + __n; + } + _VSTD::copy(__f, __m, __rb); + __f = __m; + __r += __n; + } + return __r; +} + +template +_OutputIterator +copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + _OutputIterator __r) +{ + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type; + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer; + const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size; + difference_type __n = __l - __f; + while (__n > 0) + { + pointer __fb = __f.__ptr_; + pointer __fe = *__f.__m_iter_ + __block_size; + difference_type __bs = __fe - __fb; + if (__bs > __n) + { + __bs = __n; + __fe = __fb + __bs; + } + __r = _VSTD::copy(__fb, __fe, __r); + __n -= __bs; + __f += __bs; + } + return __r; +} + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r) +{ + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type; + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer; + const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size; + difference_type __n = __l - __f; + while (__n > 0) + { + pointer __fb = __f.__ptr_; + pointer __fe = *__f.__m_iter_ + __block_size; + difference_type __bs = __fe - __fb; + if (__bs > __n) + { + __bs = __n; + __fe = __fb + __bs; + } + __r = _VSTD::copy(__fb, __fe, __r); + __n -= __bs; + __f += __bs; + } + return __r; +} + +// copy_backward + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +copy_backward(_RAIter __f, + _RAIter __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, + typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*) +{ + typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type; + typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer; + while (__f != __l) + { + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r); + pointer __rb = *__rp.__m_iter_; + pointer __re = __rp.__ptr_ + 1; + difference_type __bs = __re - __rb; + difference_type __n = __l - __f; + _RAIter __m = __f; + if (__n > __bs) + { + __n = __bs; + __m = __l - __n; + } + _VSTD::copy_backward(__m, __l, __re); + __l = __m; + __r -= __n; + } + return __r; +} + +template +_OutputIterator +copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + _OutputIterator __r) +{ + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type; + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer; + difference_type __n = __l - __f; + while (__n > 0) + { + --__l; + pointer __lb = *__l.__m_iter_; + pointer __le = __l.__ptr_ + 1; + difference_type __bs = __le - __lb; + if (__bs > __n) + { + __bs = __n; + __lb = __le - __bs; + } + __r = _VSTD::copy_backward(__lb, __le, __r); + __n -= __bs; + __l -= __bs - 1; + } + return __r; +} + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r) +{ + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type; + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer; + difference_type __n = __l - __f; + while (__n > 0) + { + --__l; + pointer __lb = *__l.__m_iter_; + pointer __le = __l.__ptr_ + 1; + difference_type __bs = __le - __lb; + if (__bs > __n) + { + __bs = __n; + __lb = __le - __bs; + } + __r = _VSTD::copy_backward(__lb, __le, __r); + __n -= __bs; + __l -= __bs - 1; + } + return __r; +} + +// move + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +move(_RAIter __f, + _RAIter __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, + typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*) +{ + typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type; + typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer; + const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size; + while (__f != __l) + { + pointer __rb = __r.__ptr_; + pointer __re = *__r.__m_iter_ + __block_size; + difference_type __bs = __re - __rb; + difference_type __n = __l - __f; + _RAIter __m = __l; + if (__n > __bs) + { + __n = __bs; + __m = __f + __n; + } + _VSTD::move(__f, __m, __rb); + __f = __m; + __r += __n; + } + return __r; +} + +template +_OutputIterator +move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + _OutputIterator __r) +{ + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type; + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer; + const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size; + difference_type __n = __l - __f; + while (__n > 0) + { + pointer __fb = __f.__ptr_; + pointer __fe = *__f.__m_iter_ + __block_size; + difference_type __bs = __fe - __fb; + if (__bs > __n) + { + __bs = __n; + __fe = __fb + __bs; + } + __r = _VSTD::move(__fb, __fe, __r); + __n -= __bs; + __f += __bs; + } + return __r; +} + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r) +{ + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type; + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer; + const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size; + difference_type __n = __l - __f; + while (__n > 0) + { + pointer __fb = __f.__ptr_; + pointer __fe = *__f.__m_iter_ + __block_size; + difference_type __bs = __fe - __fb; + if (__bs > __n) + { + __bs = __n; + __fe = __fb + __bs; + } + __r = _VSTD::move(__fb, __fe, __r); + __n -= __bs; + __f += __bs; + } + return __r; +} + +// move_backward + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +move_backward(_RAIter __f, + _RAIter __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, + typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*) +{ + typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type; + typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer; + while (__f != __l) + { + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r); + pointer __rb = *__rp.__m_iter_; + pointer __re = __rp.__ptr_ + 1; + difference_type __bs = __re - __rb; + difference_type __n = __l - __f; + _RAIter __m = __f; + if (__n > __bs) + { + __n = __bs; + __m = __l - __n; + } + _VSTD::move_backward(__m, __l, __re); + __l = __m; + __r -= __n; + } + return __r; +} + +template +_OutputIterator +move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + _OutputIterator __r) +{ + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type; + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer; + difference_type __n = __l - __f; + while (__n > 0) + { + --__l; + pointer __lb = *__l.__m_iter_; + pointer __le = __l.__ptr_ + 1; + difference_type __bs = __le - __lb; + if (__bs > __n) + { + __bs = __n; + __lb = __le - __bs; + } + __r = _VSTD::move_backward(__lb, __le, __r); + __n -= __bs; + __l -= __bs - 1; + } + return __r; +} + +template +__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> +move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f, + __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l, + __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r) +{ + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type; + typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer; + difference_type __n = __l - __f; + while (__n > 0) + { + --__l; + pointer __lb = *__l.__m_iter_; + pointer __le = __l.__ptr_ + 1; + difference_type __bs = __le - __lb; + if (__bs > __n) + { + __bs = __n; + __lb = __le - __bs; + } + __r = _VSTD::move_backward(__lb, __le, __r); + __n -= __bs; + __l -= __bs - 1; + } + return __r; +} + +template +class __deque_base_common +{ +protected: + void __throw_length_error() const; + void __throw_out_of_range() const; +}; + +template +void +__deque_base_common<__b>::__throw_length_error() const +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw length_error("deque"); +#endif +} + +template +void +__deque_base_common<__b>::__throw_out_of_range() const +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw out_of_range("deque"); +#endif +} + +template +class __deque_base + : protected __deque_base_common +{ + __deque_base(const __deque_base& __c); + __deque_base& operator=(const __deque_base& __c); +protected: + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef allocator_traits __alloc_traits; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::difference_type difference_type; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; + + static const difference_type __block_size; + + typedef typename __rebind_alloc_helper<__alloc_traits, pointer>::type __pointer_allocator; + typedef allocator_traits<__pointer_allocator> __map_traits; + typedef typename __map_traits::pointer __map_pointer; + typedef typename __rebind_alloc_helper<__alloc_traits, const_pointer>::type __const_pointer_allocator; + typedef typename allocator_traits<__const_pointer_allocator>::const_pointer __map_const_pointer; + typedef __split_buffer __map; + + typedef __deque_iterator iterator; + typedef __deque_iterator const_iterator; + + __map __map_; + size_type __start_; + __compressed_pair __size_; + + iterator begin() _NOEXCEPT; + const_iterator begin() const _NOEXCEPT; + iterator end() _NOEXCEPT; + const_iterator end() const _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY size_type& size() {return __size_.first();} + _LIBCPP_INLINE_VISIBILITY + const size_type& size() const _NOEXCEPT {return __size_.first();} + _LIBCPP_INLINE_VISIBILITY allocator_type& __alloc() {return __size_.second();} + _LIBCPP_INLINE_VISIBILITY + const allocator_type& __alloc() const _NOEXCEPT {return __size_.second();} + + _LIBCPP_INLINE_VISIBILITY + __deque_base() + _NOEXCEPT_(is_nothrow_default_constructible::value); + _LIBCPP_INLINE_VISIBILITY + explicit __deque_base(const allocator_type& __a); +public: + ~__deque_base(); + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + + __deque_base(__deque_base&& __c) + _NOEXCEPT_(is_nothrow_move_constructible::value); + __deque_base(__deque_base&& __c, const allocator_type& __a); + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + void swap(__deque_base& __c) +#if _LIBCPP_STD_VER >= 14 + _NOEXCEPT; +#else + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + __is_nothrow_swappable::value); +#endif +protected: + void clear() _NOEXCEPT; + + bool __invariants() const; + + _LIBCPP_INLINE_VISIBILITY + void __move_assign(__deque_base& __c) + _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value) + { + __map_ = _VSTD::move(__c.__map_); + __start_ = __c.__start_; + size() = __c.size(); + __move_assign_alloc(__c); + __c.__start_ = __c.size() = 0; + } + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__deque_base& __c) + _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value || + is_nothrow_move_assignable::value) + {__move_assign_alloc(__c, integral_constant());} + +private: + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__deque_base& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value) + { + __alloc() = _VSTD::move(__c.__alloc()); + } + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__deque_base&, false_type) _NOEXCEPT + {} +}; + +template +const typename __deque_base<_Tp, _Allocator>::difference_type + __deque_base<_Tp, _Allocator>::__block_size = + __deque_block_size::value; + +template +bool +__deque_base<_Tp, _Allocator>::__invariants() const +{ + if (!__map_.__invariants()) + return false; + if (__map_.size() >= size_type(-1) / __block_size) + return false; + for (typename __map::const_iterator __i = __map_.begin(), __e = __map_.end(); + __i != __e; ++__i) + if (*__i == nullptr) + return false; + if (__map_.size() != 0) + { + if (size() >= __map_.size() * __block_size) + return false; + if (__start_ >= __map_.size() * __block_size - size()) + return false; + } + else + { + if (size() != 0) + return false; + if (__start_ != 0) + return false; + } + return true; +} + +template +typename __deque_base<_Tp, _Allocator>::iterator +__deque_base<_Tp, _Allocator>::begin() _NOEXCEPT +{ + __map_pointer __mp = __map_.begin() + __start_ / __block_size; + return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); +} + +template +typename __deque_base<_Tp, _Allocator>::const_iterator +__deque_base<_Tp, _Allocator>::begin() const _NOEXCEPT +{ + __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size); + return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); +} + +template +typename __deque_base<_Tp, _Allocator>::iterator +__deque_base<_Tp, _Allocator>::end() _NOEXCEPT +{ + size_type __p = size() + __start_; + __map_pointer __mp = __map_.begin() + __p / __block_size; + return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); +} + +template +typename __deque_base<_Tp, _Allocator>::const_iterator +__deque_base<_Tp, _Allocator>::end() const _NOEXCEPT +{ + size_type __p = size() + __start_; + __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size); + return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); +} + +template +inline +__deque_base<_Tp, _Allocator>::__deque_base() + _NOEXCEPT_(is_nothrow_default_constructible::value) + : __start_(0), __size_(0) {} + +template +inline +__deque_base<_Tp, _Allocator>::__deque_base(const allocator_type& __a) + : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {} + +template +__deque_base<_Tp, _Allocator>::~__deque_base() +{ + clear(); + typename __map::iterator __i = __map_.begin(); + typename __map::iterator __e = __map_.end(); + for (; __i != __e; ++__i) + __alloc_traits::deallocate(__alloc(), *__i, __block_size); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c) + _NOEXCEPT_(is_nothrow_move_constructible::value) + : __map_(_VSTD::move(__c.__map_)), + __start_(_VSTD::move(__c.__start_)), + __size_(_VSTD::move(__c.__size_)) +{ + __c.__start_ = 0; + __c.size() = 0; +} + +template +__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c, const allocator_type& __a) + : __map_(_VSTD::move(__c.__map_), __pointer_allocator(__a)), + __start_(_VSTD::move(__c.__start_)), + __size_(_VSTD::move(__c.size()), __a) +{ + if (__a == __c.__alloc()) + { + __c.__start_ = 0; + __c.size() = 0; + } + else + { + __map_.clear(); + __start_ = 0; + size() = 0; + } +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +__deque_base<_Tp, _Allocator>::swap(__deque_base& __c) +#if _LIBCPP_STD_VER >= 14 + _NOEXCEPT +#else + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + __is_nothrow_swappable::value) +#endif +{ + __map_.swap(__c.__map_); + _VSTD::swap(__start_, __c.__start_); + _VSTD::swap(size(), __c.size()); + __swap_allocator(__alloc(), __c.__alloc()); +} + +template +void +__deque_base<_Tp, _Allocator>::clear() _NOEXCEPT +{ + allocator_type& __a = __alloc(); + for (iterator __i = begin(), __e = end(); __i != __e; ++__i) + __alloc_traits::destroy(__a, _VSTD::addressof(*__i)); + size() = 0; + while (__map_.size() > 2) + { + __alloc_traits::deallocate(__a, __map_.front(), __block_size); + __map_.pop_front(); + } + switch (__map_.size()) + { + case 1: + __start_ = __block_size / 2; + break; + case 2: + __start_ = __block_size; + break; + } +} + +template */> +class _LIBCPP_TYPE_VIS_ONLY deque + : private __deque_base<_Tp, _Allocator> +{ +public: + // types: + + typedef _Tp value_type; + typedef _Allocator allocator_type; + + typedef __deque_base __base; + + typedef typename __base::__alloc_traits __alloc_traits; + typedef typename __base::reference reference; + typedef typename __base::const_reference const_reference; + typedef typename __base::iterator iterator; + typedef typename __base::const_iterator const_iterator; + typedef typename __base::size_type size_type; + typedef typename __base::difference_type difference_type; + + typedef typename __base::pointer pointer; + typedef typename __base::const_pointer const_pointer; + typedef _VSTD::reverse_iterator reverse_iterator; + typedef _VSTD::reverse_iterator const_reverse_iterator; + + // construct/copy/destroy: + _LIBCPP_INLINE_VISIBILITY + deque() + _NOEXCEPT_(is_nothrow_default_constructible::value) + {} + _LIBCPP_INLINE_VISIBILITY explicit deque(const allocator_type& __a) : __base(__a) {} + explicit deque(size_type __n); +#if _LIBCPP_STD_VER > 11 + explicit deque(size_type __n, const _Allocator& __a); +#endif + deque(size_type __n, const value_type& __v); + deque(size_type __n, const value_type& __v, const allocator_type& __a); + template + deque(_InputIter __f, _InputIter __l, + typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0); + template + deque(_InputIter __f, _InputIter __l, const allocator_type& __a, + typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0); + deque(const deque& __c); + deque(const deque& __c, const allocator_type& __a); +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + deque(initializer_list __il); + deque(initializer_list __il, const allocator_type& __a); +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + deque& operator=(const deque& __c); +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY + deque& operator=(initializer_list __il) {assign(__il); return *this;} +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value); + _LIBCPP_INLINE_VISIBILITY + deque(deque&& __c, const allocator_type& __a); + _LIBCPP_INLINE_VISIBILITY + deque& operator=(deque&& __c) + _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + template + void assign(_InputIter __f, _InputIter __l, + typename enable_if<__is_input_iterator<_InputIter>::value && + !__is_random_access_iterator<_InputIter>::value>::type* = 0); + template + void assign(_RAIter __f, _RAIter __l, + typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0); + void assign(size_type __n, const value_type& __v); +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY + void assign(initializer_list __il) {assign(__il.begin(), __il.end());} +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const _NOEXCEPT; + + // iterators: + + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT {return __base::begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT {return __base::begin();} + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT {return __base::end();} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT {return __base::end();} + + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rbegin() _NOEXCEPT + {return reverse_iterator(__base::end());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rbegin() const _NOEXCEPT + {return const_reverse_iterator(__base::end());} + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rend() _NOEXCEPT + {return reverse_iterator(__base::begin());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rend() const _NOEXCEPT + {return const_reverse_iterator(__base::begin());} + + _LIBCPP_INLINE_VISIBILITY + const_iterator cbegin() const _NOEXCEPT + {return __base::begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator cend() const _NOEXCEPT + {return __base::end();} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crbegin() const _NOEXCEPT + {return const_reverse_iterator(__base::end());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crend() const _NOEXCEPT + {return const_reverse_iterator(__base::begin());} + + // capacity: + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT {return __base::size();} + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT + {return __alloc_traits::max_size(__base::__alloc());} + void resize(size_type __n); + void resize(size_type __n, const value_type& __v); + void shrink_to_fit() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + bool empty() const _NOEXCEPT {return __base::size() == 0;} + + // element access: + _LIBCPP_INLINE_VISIBILITY + reference operator[](size_type __i); + _LIBCPP_INLINE_VISIBILITY + const_reference operator[](size_type __i) const; + _LIBCPP_INLINE_VISIBILITY + reference at(size_type __i); + _LIBCPP_INLINE_VISIBILITY + const_reference at(size_type __i) const; + _LIBCPP_INLINE_VISIBILITY + reference front(); + _LIBCPP_INLINE_VISIBILITY + const_reference front() const; + _LIBCPP_INLINE_VISIBILITY + reference back(); + _LIBCPP_INLINE_VISIBILITY + const_reference back() const; + + // 23.2.2.3 modifiers: + void push_front(const value_type& __v); + void push_back(const value_type& __v); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + template void emplace_front(_Args&&... __args); + template void emplace_back(_Args&&... __args); + template iterator emplace(const_iterator __p, _Args&&... __args); +#endif // _LIBCPP_HAS_NO_VARIADICS + void push_front(value_type&& __v); + void push_back(value_type&& __v); + iterator insert(const_iterator __p, value_type&& __v); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + iterator insert(const_iterator __p, const value_type& __v); + iterator insert(const_iterator __p, size_type __n, const value_type& __v); + template + iterator insert(const_iterator __p, _InputIter __f, _InputIter __l, + typename enable_if<__is_input_iterator<_InputIter>::value + &&!__is_forward_iterator<_InputIter>::value>::type* = 0); + template + iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l, + typename enable_if<__is_forward_iterator<_ForwardIterator>::value + &&!__is_bidirectional_iterator<_ForwardIterator>::value>::type* = 0); + template + iterator insert(const_iterator __p, _BiIter __f, _BiIter __l, + typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type* = 0); +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __p, initializer_list __il) + {return insert(__p, __il.begin(), __il.end());} +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + void pop_front(); + void pop_back(); + iterator erase(const_iterator __p); + iterator erase(const_iterator __f, const_iterator __l); + + _LIBCPP_INLINE_VISIBILITY + void swap(deque& __c) +#if _LIBCPP_STD_VER >= 14 + _NOEXCEPT; +#else + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + __is_nothrow_swappable::value); +#endif + _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + bool __invariants() const {return __base::__invariants();} +private: + typedef typename __base::__map_const_pointer __map_const_pointer; + + _LIBCPP_INLINE_VISIBILITY + static size_type __recommend_blocks(size_type __n) + { + return __n / __base::__block_size + (__n % __base::__block_size != 0); + } + _LIBCPP_INLINE_VISIBILITY + size_type __capacity() const + { + return __base::__map_.size() == 0 ? 0 : __base::__map_.size() * __base::__block_size - 1; + } + _LIBCPP_INLINE_VISIBILITY + size_type __front_spare() const + { + return __base::__start_; + } + _LIBCPP_INLINE_VISIBILITY + size_type __back_spare() const + { + return __capacity() - (__base::__start_ + __base::size()); + } + + template + void __append(_InpIter __f, _InpIter __l, + typename enable_if<__is_input_iterator<_InpIter>::value && + !__is_forward_iterator<_InpIter>::value>::type* = 0); + template + void __append(_ForIter __f, _ForIter __l, + typename enable_if<__is_forward_iterator<_ForIter>::value>::type* = 0); + void __append(size_type __n); + void __append(size_type __n, const value_type& __v); + void __erase_to_end(const_iterator __f); + void __add_front_capacity(); + void __add_front_capacity(size_type __n); + void __add_back_capacity(); + void __add_back_capacity(size_type __n); + iterator __move_and_check(iterator __f, iterator __l, iterator __r, + const_pointer& __vt); + iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r, + const_pointer& __vt); + void __move_construct_and_check(iterator __f, iterator __l, + iterator __r, const_pointer& __vt); + void __move_construct_backward_and_check(iterator __f, iterator __l, + iterator __r, const_pointer& __vt); + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const deque& __c) + {__copy_assign_alloc(__c, integral_constant());} + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const deque& __c, true_type) + { + if (__base::__alloc() != __c.__alloc()) + { + clear(); + shrink_to_fit(); + } + __base::__alloc() = __c.__alloc(); + __base::__map_.__alloc() = __c.__map_.__alloc(); + } + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const deque&, false_type) + {} + + void __move_assign(deque& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value); + void __move_assign(deque& __c, false_type); +}; + +template +deque<_Tp, _Allocator>::deque(size_type __n) +{ + if (__n > 0) + __append(__n); +} + +#if _LIBCPP_STD_VER > 11 +template +deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a) + : __base(__a) +{ + if (__n > 0) + __append(__n); +} +#endif + +template +deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) +{ + if (__n > 0) + __append(__n, __v); +} + +template +deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const allocator_type& __a) + : __base(__a) +{ + if (__n > 0) + __append(__n, __v); +} + +template +template +deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, + typename enable_if<__is_input_iterator<_InputIter>::value>::type*) +{ + __append(__f, __l); +} + +template +template +deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a, + typename enable_if<__is_input_iterator<_InputIter>::value>::type*) + : __base(__a) +{ + __append(__f, __l); +} + +template +deque<_Tp, _Allocator>::deque(const deque& __c) + : __base(__alloc_traits::select_on_container_copy_construction(__c.__alloc())) +{ + __append(__c.begin(), __c.end()); +} + +template +deque<_Tp, _Allocator>::deque(const deque& __c, const allocator_type& __a) + : __base(__a) +{ + __append(__c.begin(), __c.end()); +} + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +template +deque<_Tp, _Allocator>::deque(initializer_list __il) +{ + __append(__il.begin(), __il.end()); +} + +template +deque<_Tp, _Allocator>::deque(initializer_list __il, const allocator_type& __a) + : __base(__a) +{ + __append(__il.begin(), __il.end()); +} + +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +template +deque<_Tp, _Allocator>& +deque<_Tp, _Allocator>::operator=(const deque& __c) +{ + if (this != &__c) + { + __copy_assign_alloc(__c); + assign(__c.begin(), __c.end()); + } + return *this; +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline +deque<_Tp, _Allocator>::deque(deque&& __c) + _NOEXCEPT_(is_nothrow_move_constructible<__base>::value) + : __base(_VSTD::move(__c)) +{ +} + +template +inline +deque<_Tp, _Allocator>::deque(deque&& __c, const allocator_type& __a) + : __base(_VSTD::move(__c), __a) +{ + if (__a != __c.__alloc()) + { + typedef move_iterator _Ip; + assign(_Ip(__c.begin()), _Ip(__c.end())); + } +} + +template +inline +deque<_Tp, _Allocator>& +deque<_Tp, _Allocator>::operator=(deque&& __c) + _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value) +{ + __move_assign(__c, integral_constant()); + return *this; +} + +template +void +deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type) +{ + if (__base::__alloc() != __c.__alloc()) + { + typedef move_iterator _Ip; + assign(_Ip(__c.begin()), _Ip(__c.end())); + } + else + __move_assign(__c, true_type()); +} + +template +void +deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value) +{ + clear(); + shrink_to_fit(); + __base::__move_assign(__c); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +template +void +deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l, + typename enable_if<__is_input_iterator<_InputIter>::value && + !__is_random_access_iterator<_InputIter>::value>::type*) +{ + iterator __i = __base::begin(); + iterator __e = __base::end(); + for (; __f != __l && __i != __e; ++__f, (void) ++__i) + *__i = *__f; + if (__f != __l) + __append(__f, __l); + else + __erase_to_end(__i); +} + +template +template +void +deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l, + typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*) +{ + if (static_cast(__l - __f) > __base::size()) + { + _RAIter __m = __f + __base::size(); + _VSTD::copy(__f, __m, __base::begin()); + __append(__m, __l); + } + else + __erase_to_end(_VSTD::copy(__f, __l, __base::begin())); +} + +template +void +deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v) +{ + if (__n > __base::size()) + { + _VSTD::fill_n(__base::begin(), __base::size(), __v); + __n -= __base::size(); + __append(__n, __v); + } + else + __erase_to_end(_VSTD::fill_n(__base::begin(), __n, __v)); +} + +template +inline +_Allocator +deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT +{ + return __base::__alloc(); +} + +template +void +deque<_Tp, _Allocator>::resize(size_type __n) +{ + if (__n > __base::size()) + __append(__n - __base::size()); + else if (__n < __base::size()) + __erase_to_end(__base::begin() + __n); +} + +template +void +deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v) +{ + if (__n > __base::size()) + __append(__n - __base::size(), __v); + else if (__n < __base::size()) + __erase_to_end(__base::begin() + __n); +} + +template +void +deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT +{ + allocator_type& __a = __base::__alloc(); + if (empty()) + { + while (__base::__map_.size() > 0) + { + __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size); + __base::__map_.pop_back(); + } + __base::__start_ = 0; + } + else + { + if (__front_spare() >= __base::__block_size) + { + __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size); + __base::__map_.pop_front(); + __base::__start_ -= __base::__block_size; + } + if (__back_spare() >= __base::__block_size) + { + __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size); + __base::__map_.pop_back(); + } + } + __base::__map_.shrink_to_fit(); +} + +template +inline +typename deque<_Tp, _Allocator>::reference +deque<_Tp, _Allocator>::operator[](size_type __i) +{ + size_type __p = __base::__start_ + __i; + return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size); +} + +template +inline +typename deque<_Tp, _Allocator>::const_reference +deque<_Tp, _Allocator>::operator[](size_type __i) const +{ + size_type __p = __base::__start_ + __i; + return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size); +} + +template +inline +typename deque<_Tp, _Allocator>::reference +deque<_Tp, _Allocator>::at(size_type __i) +{ + if (__i >= __base::size()) + __base::__throw_out_of_range(); + size_type __p = __base::__start_ + __i; + return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size); +} + +template +inline +typename deque<_Tp, _Allocator>::const_reference +deque<_Tp, _Allocator>::at(size_type __i) const +{ + if (__i >= __base::size()) + __base::__throw_out_of_range(); + size_type __p = __base::__start_ + __i; + return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size); +} + +template +inline +typename deque<_Tp, _Allocator>::reference +deque<_Tp, _Allocator>::front() +{ + return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size) + + __base::__start_ % __base::__block_size); +} + +template +inline +typename deque<_Tp, _Allocator>::const_reference +deque<_Tp, _Allocator>::front() const +{ + return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size) + + __base::__start_ % __base::__block_size); +} + +template +inline +typename deque<_Tp, _Allocator>::reference +deque<_Tp, _Allocator>::back() +{ + size_type __p = __base::size() + __base::__start_ - 1; + return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size); +} + +template +inline +typename deque<_Tp, _Allocator>::const_reference +deque<_Tp, _Allocator>::back() const +{ + size_type __p = __base::size() + __base::__start_ - 1; + return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size); +} + +template +void +deque<_Tp, _Allocator>::push_back(const value_type& __v) +{ + allocator_type& __a = __base::__alloc(); + if (__back_spare() == 0) + __add_back_capacity(); + // __back_spare() >= 1 + __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v); + ++__base::size(); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +deque<_Tp, _Allocator>::push_back(value_type&& __v) +{ + allocator_type& __a = __base::__alloc(); + if (__back_spare() == 0) + __add_back_capacity(); + // __back_spare() >= 1 + __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v)); + ++__base::size(); +} + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +template +template +void +deque<_Tp, _Allocator>::emplace_back(_Args&&... __args) +{ + allocator_type& __a = __base::__alloc(); + if (__back_spare() == 0) + __add_back_capacity(); + // __back_spare() >= 1 + __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::forward<_Args>(__args)...); + ++__base::size(); +} + +#endif // _LIBCPP_HAS_NO_VARIADICS +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +deque<_Tp, _Allocator>::push_front(const value_type& __v) +{ + allocator_type& __a = __base::__alloc(); + if (__front_spare() == 0) + __add_front_capacity(); + // __front_spare() >= 1 + __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v); + --__base::__start_; + ++__base::size(); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +deque<_Tp, _Allocator>::push_front(value_type&& __v) +{ + allocator_type& __a = __base::__alloc(); + if (__front_spare() == 0) + __add_front_capacity(); + // __front_spare() >= 1 + __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v)); + --__base::__start_; + ++__base::size(); +} + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +template +template +void +deque<_Tp, _Allocator>::emplace_front(_Args&&... __args) +{ + allocator_type& __a = __base::__alloc(); + if (__front_spare() == 0) + __add_front_capacity(); + // __front_spare() >= 1 + __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...); + --__base::__start_; + ++__base::size(); +} + +#endif // _LIBCPP_HAS_NO_VARIADICS +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +typename deque<_Tp, _Allocator>::iterator +deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v) +{ + size_type __pos = __p - __base::begin(); + size_type __to_end = __base::size() - __pos; + allocator_type& __a = __base::__alloc(); + if (__pos < __to_end) + { // insert by shifting things backward + if (__front_spare() == 0) + __add_front_capacity(); + // __front_spare() >= 1 + if (__pos == 0) + { + __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v); + --__base::__start_; + ++__base::size(); + } + else + { + const_pointer __vt = pointer_traits::pointer_to(__v); + iterator __b = __base::begin(); + iterator __bm1 = _VSTD::prev(__b); + if (__vt == pointer_traits::pointer_to(*__b)) + __vt = pointer_traits::pointer_to(*__bm1); + __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b)); + --__base::__start_; + ++__base::size(); + if (__pos > 1) + __b = __move_and_check(_VSTD::next(__b), __b + __pos, __b, __vt); + *__b = *__vt; + } + } + else + { // insert by shifting things forward + if (__back_spare() == 0) + __add_back_capacity(); + // __back_capacity >= 1 + size_type __de = __base::size() - __pos; + if (__de == 0) + { + __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v); + ++__base::size(); + } + else + { + const_pointer __vt = pointer_traits::pointer_to(__v); + iterator __e = __base::end(); + iterator __em1 = _VSTD::prev(__e); + if (__vt == pointer_traits::pointer_to(*__em1)) + __vt = pointer_traits::pointer_to(*__e); + __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1)); + ++__base::size(); + if (__de > 1) + __e = __move_backward_and_check(__e - __de, __em1, __e, __vt); + *--__e = *__vt; + } + } + return __base::begin() + __pos; +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +typename deque<_Tp, _Allocator>::iterator +deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v) +{ + size_type __pos = __p - __base::begin(); + size_type __to_end = __base::size() - __pos; + allocator_type& __a = __base::__alloc(); + if (__pos < __to_end) + { // insert by shifting things backward + if (__front_spare() == 0) + __add_front_capacity(); + // __front_spare() >= 1 + if (__pos == 0) + { + __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v)); + --__base::__start_; + ++__base::size(); + } + else + { + iterator __b = __base::begin(); + iterator __bm1 = _VSTD::prev(__b); + __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b)); + --__base::__start_; + ++__base::size(); + if (__pos > 1) + __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b); + *__b = _VSTD::move(__v); + } + } + else + { // insert by shifting things forward + if (__back_spare() == 0) + __add_back_capacity(); + // __back_capacity >= 1 + size_type __de = __base::size() - __pos; + if (__de == 0) + { + __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v)); + ++__base::size(); + } + else + { + iterator __e = __base::end(); + iterator __em1 = _VSTD::prev(__e); + __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1)); + ++__base::size(); + if (__de > 1) + __e = _VSTD::move_backward(__e - __de, __em1, __e); + *--__e = _VSTD::move(__v); + } + } + return __base::begin() + __pos; +} + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +template +template +typename deque<_Tp, _Allocator>::iterator +deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) +{ + size_type __pos = __p - __base::begin(); + size_type __to_end = __base::size() - __pos; + allocator_type& __a = __base::__alloc(); + if (__pos < __to_end) + { // insert by shifting things backward + if (__front_spare() == 0) + __add_front_capacity(); + // __front_spare() >= 1 + if (__pos == 0) + { + __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...); + --__base::__start_; + ++__base::size(); + } + else + { + value_type __tmp(_VSTD::forward<_Args>(__args)...); + iterator __b = __base::begin(); + iterator __bm1 = _VSTD::prev(__b); + __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b)); + --__base::__start_; + ++__base::size(); + if (__pos > 1) + __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b); + *__b = _VSTD::move(__tmp); + } + } + else + { // insert by shifting things forward + if (__back_spare() == 0) + __add_back_capacity(); + // __back_capacity >= 1 + size_type __de = __base::size() - __pos; + if (__de == 0) + { + __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::forward<_Args>(__args)...); + ++__base::size(); + } + else + { + value_type __tmp(_VSTD::forward<_Args>(__args)...); + iterator __e = __base::end(); + iterator __em1 = _VSTD::prev(__e); + __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1)); + ++__base::size(); + if (__de > 1) + __e = _VSTD::move_backward(__e - __de, __em1, __e); + *--__e = _VSTD::move(__tmp); + } + } + return __base::begin() + __pos; +} + +#endif // _LIBCPP_HAS_NO_VARIADICS +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +typename deque<_Tp, _Allocator>::iterator +deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v) +{ + size_type __pos = __p - __base::begin(); + size_type __to_end = __base::size() - __pos; + allocator_type& __a = __base::__alloc(); + if (__pos < __to_end) + { // insert by shifting things backward + if (__n > __front_spare()) + __add_front_capacity(__n - __front_spare()); + // __n <= __front_spare() + iterator __old_begin = __base::begin(); + iterator __i = __old_begin; + if (__n > __pos) + { + for (size_type __m = __n - __pos; __m; --__m, --__base::__start_, ++__base::size()) + __alloc_traits::construct(__a, _VSTD::addressof(*--__i), __v); + __n = __pos; + } + if (__n > 0) + { + const_pointer __vt = pointer_traits::pointer_to(__v); + iterator __obn = __old_begin + __n; + __move_construct_backward_and_check(__old_begin, __obn, __i, __vt); + if (__n < __pos) + __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt); + _VSTD::fill_n(__old_begin, __n, *__vt); + } + } + else + { // insert by shifting things forward + size_type __back_capacity = __back_spare(); + if (__n > __back_capacity) + __add_back_capacity(__n - __back_capacity); + // __n <= __back_capacity + iterator __old_end = __base::end(); + iterator __i = __old_end; + size_type __de = __base::size() - __pos; + if (__n > __de) + { + for (size_type __m = __n - __de; __m; --__m, ++__i, ++__base::size()) + __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v); + __n = __de; + } + if (__n > 0) + { + const_pointer __vt = pointer_traits::pointer_to(__v); + iterator __oen = __old_end - __n; + __move_construct_and_check(__oen, __old_end, __i, __vt); + if (__n < __de) + __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt); + _VSTD::fill_n(__old_end - __n, __n, *__vt); + } + } + return __base::begin() + __pos; +} + +template +template +typename deque<_Tp, _Allocator>::iterator +deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l, + typename enable_if<__is_input_iterator<_InputIter>::value + &&!__is_forward_iterator<_InputIter>::value>::type*) +{ + __split_buffer __buf(__base::__alloc()); + __buf.__construct_at_end(__f, __l); + typedef typename __split_buffer::iterator __bi; + return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end())); +} + +template +template +typename deque<_Tp, _Allocator>::iterator +deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l, + typename enable_if<__is_forward_iterator<_ForwardIterator>::value + &&!__is_bidirectional_iterator<_ForwardIterator>::value>::type*) +{ + size_type __n = _VSTD::distance(__f, __l); + __split_buffer __buf(__n, 0, __base::__alloc()); + __buf.__construct_at_end(__f, __l); + typedef typename __split_buffer::iterator __fwd; + return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end())); +} + +template +template +typename deque<_Tp, _Allocator>::iterator +deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l, + typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type*) +{ + size_type __n = _VSTD::distance(__f, __l); + size_type __pos = __p - __base::begin(); + size_type __to_end = __base::size() - __pos; + allocator_type& __a = __base::__alloc(); + if (__pos < __to_end) + { // insert by shifting things backward + if (__n > __front_spare()) + __add_front_capacity(__n - __front_spare()); + // __n <= __front_spare() + iterator __old_begin = __base::begin(); + iterator __i = __old_begin; + _BiIter __m = __f; + if (__n > __pos) + { + __m = __pos < __n / 2 ? _VSTD::prev(__l, __pos) : _VSTD::next(__f, __n - __pos); + for (_BiIter __j = __m; __j != __f; --__base::__start_, ++__base::size()) + __alloc_traits::construct(__a, _VSTD::addressof(*--__i), *--__j); + __n = __pos; + } + if (__n > 0) + { + iterator __obn = __old_begin + __n; + for (iterator __j = __obn; __j != __old_begin;) + { + __alloc_traits::construct(__a, _VSTD::addressof(*--__i), _VSTD::move(*--__j)); + --__base::__start_; + ++__base::size(); + } + if (__n < __pos) + __old_begin = _VSTD::move(__obn, __old_begin + __pos, __old_begin); + _VSTD::copy(__m, __l, __old_begin); + } + } + else + { // insert by shifting things forward + size_type __back_capacity = __back_spare(); + if (__n > __back_capacity) + __add_back_capacity(__n - __back_capacity); + // __n <= __back_capacity + iterator __old_end = __base::end(); + iterator __i = __old_end; + _BiIter __m = __l; + size_type __de = __base::size() - __pos; + if (__n > __de) + { + __m = __de < __n / 2 ? _VSTD::next(__f, __de) : _VSTD::prev(__l, __n - __de); + for (_BiIter __j = __m; __j != __l; ++__i, (void) ++__j, ++__base::size()) + __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__j); + __n = __de; + } + if (__n > 0) + { + iterator __oen = __old_end - __n; + for (iterator __j = __oen; __j != __old_end; ++__i, ++__j, ++__base::size()) + __alloc_traits::construct(__a, _VSTD::addressof(*__i), _VSTD::move(*__j)); + if (__n < __de) + __old_end = _VSTD::move_backward(__old_end - __de, __oen, __old_end); + _VSTD::copy_backward(__f, __m, __old_end); + } + } + return __base::begin() + __pos; +} + +template +template +void +deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l, + typename enable_if<__is_input_iterator<_InpIter>::value && + !__is_forward_iterator<_InpIter>::value>::type*) +{ + for (; __f != __l; ++__f) + push_back(*__f); +} + +template +template +void +deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l, + typename enable_if<__is_forward_iterator<_ForIter>::value>::type*) +{ + size_type __n = _VSTD::distance(__f, __l); + allocator_type& __a = __base::__alloc(); + size_type __back_capacity = __back_spare(); + if (__n > __back_capacity) + __add_back_capacity(__n - __back_capacity); + // __n <= __back_capacity + for (iterator __i = __base::end(); __f != __l; ++__i, (void) ++__f, ++__base::size()) + __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__f); +} + +template +void +deque<_Tp, _Allocator>::__append(size_type __n) +{ + allocator_type& __a = __base::__alloc(); + size_type __back_capacity = __back_spare(); + if (__n > __back_capacity) + __add_back_capacity(__n - __back_capacity); + // __n <= __back_capacity + for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size()) + __alloc_traits::construct(__a, _VSTD::addressof(*__i)); +} + +template +void +deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v) +{ + allocator_type& __a = __base::__alloc(); + size_type __back_capacity = __back_spare(); + if (__n > __back_capacity) + __add_back_capacity(__n - __back_capacity); + // __n <= __back_capacity + for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size()) + __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v); +} + +// Create front capacity for one block of elements. +// Strong guarantee. Either do it or don't touch anything. +template +void +deque<_Tp, _Allocator>::__add_front_capacity() +{ + allocator_type& __a = __base::__alloc(); + if (__back_spare() >= __base::__block_size) + { + __base::__start_ += __base::__block_size; + pointer __pt = __base::__map_.back(); + __base::__map_.pop_back(); + __base::__map_.push_front(__pt); + } + // Else if __base::__map_.size() < __base::__map_.capacity() then we need to allocate 1 buffer + else if (__base::__map_.size() < __base::__map_.capacity()) + { // we can put the new buffer into the map, but don't shift things around + // until all buffers are allocated. If we throw, we don't need to fix + // anything up (any added buffers are undetectible) + if (__base::__map_.__front_spare() > 0) + __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size)); + else + { + __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size)); + // Done allocating, reorder capacity + pointer __pt = __base::__map_.back(); + __base::__map_.pop_back(); + __base::__map_.push_front(__pt); + } + __base::__start_ = __base::__map_.size() == 1 ? + __base::__block_size / 2 : + __base::__start_ + __base::__block_size; + } + // Else need to allocate 1 buffer, *and* we need to reallocate __map_. + else + { + __split_buffer + __buf(max(2 * __base::__map_.capacity(), 1), + 0, __base::__map_.__alloc()); + + typedef __allocator_destructor<_Allocator> _Dp; + unique_ptr __hold( + __alloc_traits::allocate(__a, __base::__block_size), + _Dp(__a, __base::__block_size)); + __buf.push_back(__hold.get()); + __hold.release(); + + for (typename __base::__map_pointer __i = __base::__map_.begin(); + __i != __base::__map_.end(); ++__i) + __buf.push_back(*__i); + _VSTD::swap(__base::__map_.__first_, __buf.__first_); + _VSTD::swap(__base::__map_.__begin_, __buf.__begin_); + _VSTD::swap(__base::__map_.__end_, __buf.__end_); + _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap()); + __base::__start_ = __base::__map_.size() == 1 ? + __base::__block_size / 2 : + __base::__start_ + __base::__block_size; + } +} + +// Create front capacity for __n elements. +// Strong guarantee. Either do it or don't touch anything. +template +void +deque<_Tp, _Allocator>::__add_front_capacity(size_type __n) +{ + allocator_type& __a = __base::__alloc(); + size_type __nb = __recommend_blocks(__n + __base::__map_.empty()); + // Number of unused blocks at back: + size_type __back_capacity = __back_spare() / __base::__block_size; + __back_capacity = _VSTD::min(__back_capacity, __nb); // don't take more than you need + __nb -= __back_capacity; // number of blocks need to allocate + // If __nb == 0, then we have sufficient capacity. + if (__nb == 0) + { + __base::__start_ += __base::__block_size * __back_capacity; + for (; __back_capacity > 0; --__back_capacity) + { + pointer __pt = __base::__map_.back(); + __base::__map_.pop_back(); + __base::__map_.push_front(__pt); + } + } + // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers + else if (__nb <= __base::__map_.capacity() - __base::__map_.size()) + { // we can put the new buffers into the map, but don't shift things around + // until all buffers are allocated. If we throw, we don't need to fix + // anything up (any added buffers are undetectible) + for (; __nb > 0; --__nb, __base::__start_ += __base::__block_size - (__base::__map_.size() == 1)) + { + if (__base::__map_.__front_spare() == 0) + break; + __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size)); + } + for (; __nb > 0; --__nb, ++__back_capacity) + __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size)); + // Done allocating, reorder capacity + __base::__start_ += __back_capacity * __base::__block_size; + for (; __back_capacity > 0; --__back_capacity) + { + pointer __pt = __base::__map_.back(); + __base::__map_.pop_back(); + __base::__map_.push_front(__pt); + } + } + // Else need to allocate __nb buffers, *and* we need to reallocate __map_. + else + { + size_type __ds = (__nb + __back_capacity) * __base::__block_size - __base::__map_.empty(); + __split_buffer + __buf(max(2* __base::__map_.capacity(), + __nb + __base::__map_.size()), + 0, __base::__map_.__alloc()); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (; __nb > 0; --__nb) + __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size)); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + for (typename __base::__map_pointer __i = __buf.begin(); + __i != __buf.end(); ++__i) + __alloc_traits::deallocate(__a, *__i, __base::__block_size); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + for (; __back_capacity > 0; --__back_capacity) + { + __buf.push_back(__base::__map_.back()); + __base::__map_.pop_back(); + } + for (typename __base::__map_pointer __i = __base::__map_.begin(); + __i != __base::__map_.end(); ++__i) + __buf.push_back(*__i); + _VSTD::swap(__base::__map_.__first_, __buf.__first_); + _VSTD::swap(__base::__map_.__begin_, __buf.__begin_); + _VSTD::swap(__base::__map_.__end_, __buf.__end_); + _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap()); + __base::__start_ += __ds; + } +} + +// Create back capacity for one block of elements. +// Strong guarantee. Either do it or don't touch anything. +template +void +deque<_Tp, _Allocator>::__add_back_capacity() +{ + allocator_type& __a = __base::__alloc(); + if (__front_spare() >= __base::__block_size) + { + __base::__start_ -= __base::__block_size; + pointer __pt = __base::__map_.front(); + __base::__map_.pop_front(); + __base::__map_.push_back(__pt); + } + // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers + else if (__base::__map_.size() < __base::__map_.capacity()) + { // we can put the new buffer into the map, but don't shift things around + // until it is allocated. If we throw, we don't need to fix + // anything up (any added buffers are undetectible) + if (__base::__map_.__back_spare() != 0) + __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size)); + else + { + __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size)); + // Done allocating, reorder capacity + pointer __pt = __base::__map_.front(); + __base::__map_.pop_front(); + __base::__map_.push_back(__pt); + } + } + // Else need to allocate 1 buffer, *and* we need to reallocate __map_. + else + { + __split_buffer + __buf(max(2* __base::__map_.capacity(), 1), + __base::__map_.size(), + __base::__map_.__alloc()); + + typedef __allocator_destructor<_Allocator> _Dp; + unique_ptr __hold( + __alloc_traits::allocate(__a, __base::__block_size), + _Dp(__a, __base::__block_size)); + __buf.push_back(__hold.get()); + __hold.release(); + + for (typename __base::__map_pointer __i = __base::__map_.end(); + __i != __base::__map_.begin();) + __buf.push_front(*--__i); + _VSTD::swap(__base::__map_.__first_, __buf.__first_); + _VSTD::swap(__base::__map_.__begin_, __buf.__begin_); + _VSTD::swap(__base::__map_.__end_, __buf.__end_); + _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap()); + } +} + +// Create back capacity for __n elements. +// Strong guarantee. Either do it or don't touch anything. +template +void +deque<_Tp, _Allocator>::__add_back_capacity(size_type __n) +{ + allocator_type& __a = __base::__alloc(); + size_type __nb = __recommend_blocks(__n + __base::__map_.empty()); + // Number of unused blocks at front: + size_type __front_capacity = __front_spare() / __base::__block_size; + __front_capacity = _VSTD::min(__front_capacity, __nb); // don't take more than you need + __nb -= __front_capacity; // number of blocks need to allocate + // If __nb == 0, then we have sufficient capacity. + if (__nb == 0) + { + __base::__start_ -= __base::__block_size * __front_capacity; + for (; __front_capacity > 0; --__front_capacity) + { + pointer __pt = __base::__map_.front(); + __base::__map_.pop_front(); + __base::__map_.push_back(__pt); + } + } + // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers + else if (__nb <= __base::__map_.capacity() - __base::__map_.size()) + { // we can put the new buffers into the map, but don't shift things around + // until all buffers are allocated. If we throw, we don't need to fix + // anything up (any added buffers are undetectible) + for (; __nb > 0; --__nb) + { + if (__base::__map_.__back_spare() == 0) + break; + __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size)); + } + for (; __nb > 0; --__nb, ++__front_capacity, __base::__start_ += + __base::__block_size - (__base::__map_.size() == 1)) + __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size)); + // Done allocating, reorder capacity + __base::__start_ -= __base::__block_size * __front_capacity; + for (; __front_capacity > 0; --__front_capacity) + { + pointer __pt = __base::__map_.front(); + __base::__map_.pop_front(); + __base::__map_.push_back(__pt); + } + } + // Else need to allocate __nb buffers, *and* we need to reallocate __map_. + else + { + size_type __ds = __front_capacity * __base::__block_size; + __split_buffer + __buf(max(2* __base::__map_.capacity(), + __nb + __base::__map_.size()), + __base::__map_.size() - __front_capacity, + __base::__map_.__alloc()); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (; __nb > 0; --__nb) + __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size)); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + for (typename __base::__map_pointer __i = __buf.begin(); + __i != __buf.end(); ++__i) + __alloc_traits::deallocate(__a, *__i, __base::__block_size); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + for (; __front_capacity > 0; --__front_capacity) + { + __buf.push_back(__base::__map_.front()); + __base::__map_.pop_front(); + } + for (typename __base::__map_pointer __i = __base::__map_.end(); + __i != __base::__map_.begin();) + __buf.push_front(*--__i); + _VSTD::swap(__base::__map_.__first_, __buf.__first_); + _VSTD::swap(__base::__map_.__begin_, __buf.__begin_); + _VSTD::swap(__base::__map_.__end_, __buf.__end_); + _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap()); + __base::__start_ -= __ds; + } +} + +template +void +deque<_Tp, _Allocator>::pop_front() +{ + allocator_type& __a = __base::__alloc(); + __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() + + __base::__start_ / __base::__block_size) + + __base::__start_ % __base::__block_size)); + --__base::size(); + if (++__base::__start_ >= 2 * __base::__block_size) + { + __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size); + __base::__map_.pop_front(); + __base::__start_ -= __base::__block_size; + } +} + +template +void +deque<_Tp, _Allocator>::pop_back() +{ + allocator_type& __a = __base::__alloc(); + size_type __p = __base::size() + __base::__start_ - 1; + __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() + + __p / __base::__block_size) + + __p % __base::__block_size)); + --__base::size(); + if (__back_spare() >= 2 * __base::__block_size) + { + __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size); + __base::__map_.pop_back(); + } +} + +// move assign [__f, __l) to [__r, __r + (__l-__f)). +// If __vt points into [__f, __l), then subtract (__f - __r) from __vt. +template +typename deque<_Tp, _Allocator>::iterator +deque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r, + const_pointer& __vt) +{ + // as if + // for (; __f != __l; ++__f, ++__r) + // *__r = _VSTD::move(*__f); + difference_type __n = __l - __f; + while (__n > 0) + { + pointer __fb = __f.__ptr_; + pointer __fe = *__f.__m_iter_ + __base::__block_size; + difference_type __bs = __fe - __fb; + if (__bs > __n) + { + __bs = __n; + __fe = __fb + __bs; + } + if (__fb <= __vt && __vt < __fe) + __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_; + __r = _VSTD::move(__fb, __fe, __r); + __n -= __bs; + __f += __bs; + } + return __r; +} + +// move assign [__f, __l) to [__r - (__l-__f), __r) backwards. +// If __vt points into [__f, __l), then add (__r - __l) to __vt. +template +typename deque<_Tp, _Allocator>::iterator +deque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r, + const_pointer& __vt) +{ + // as if + // while (__f != __l) + // *--__r = _VSTD::move(*--__l); + difference_type __n = __l - __f; + while (__n > 0) + { + --__l; + pointer __lb = *__l.__m_iter_; + pointer __le = __l.__ptr_ + 1; + difference_type __bs = __le - __lb; + if (__bs > __n) + { + __bs = __n; + __lb = __le - __bs; + } + if (__lb <= __vt && __vt < __le) + __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_; + __r = _VSTD::move_backward(__lb, __le, __r); + __n -= __bs; + __l -= __bs - 1; + } + return __r; +} + +// move construct [__f, __l) to [__r, __r + (__l-__f)). +// If __vt points into [__f, __l), then add (__r - __f) to __vt. +template +void +deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l, + iterator __r, const_pointer& __vt) +{ + allocator_type& __a = __base::__alloc(); + // as if + // for (; __f != __l; ++__r, ++__f, ++__base::size()) + // __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__f)); + difference_type __n = __l - __f; + while (__n > 0) + { + pointer __fb = __f.__ptr_; + pointer __fe = *__f.__m_iter_ + __base::__block_size; + difference_type __bs = __fe - __fb; + if (__bs > __n) + { + __bs = __n; + __fe = __fb + __bs; + } + if (__fb <= __vt && __vt < __fe) + __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_; + for (; __fb != __fe; ++__fb, ++__r, ++__base::size()) + __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__fb)); + __n -= __bs; + __f += __bs; + } +} + +// move construct [__f, __l) to [__r - (__l-__f), __r) backwards. +// If __vt points into [__f, __l), then subtract (__l - __r) from __vt. +template +void +deque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l, + iterator __r, const_pointer& __vt) +{ + allocator_type& __a = __base::__alloc(); + // as if + // for (iterator __j = __l; __j != __f;) + // { + // __alloc_traitsconstruct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__j)); + // --__base::__start_; + // ++__base::size(); + // } + difference_type __n = __l - __f; + while (__n > 0) + { + --__l; + pointer __lb = *__l.__m_iter_; + pointer __le = __l.__ptr_ + 1; + difference_type __bs = __le - __lb; + if (__bs > __n) + { + __bs = __n; + __lb = __le - __bs; + } + if (__lb <= __vt && __vt < __le) + __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_; + while (__le != __lb) + { + __alloc_traits::construct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__le)); + --__base::__start_; + ++__base::size(); + } + __n -= __bs; + __l -= __bs - 1; + } +} + +template +typename deque<_Tp, _Allocator>::iterator +deque<_Tp, _Allocator>::erase(const_iterator __f) +{ + iterator __b = __base::begin(); + difference_type __pos = __f - __b; + iterator __p = __b + __pos; + allocator_type& __a = __base::__alloc(); + if (__pos <= (__base::size() - 1) / 2) + { // erase from front + _VSTD::move_backward(__b, __p, _VSTD::next(__p)); + __alloc_traits::destroy(__a, _VSTD::addressof(*__b)); + --__base::size(); + ++__base::__start_; + if (__front_spare() >= 2 * __base::__block_size) + { + __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size); + __base::__map_.pop_front(); + __base::__start_ -= __base::__block_size; + } + } + else + { // erase from back + iterator __i = _VSTD::move(_VSTD::next(__p), __base::end(), __p); + __alloc_traits::destroy(__a, _VSTD::addressof(*__i)); + --__base::size(); + if (__back_spare() >= 2 * __base::__block_size) + { + __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size); + __base::__map_.pop_back(); + } + } + return __base::begin() + __pos; +} + +template +typename deque<_Tp, _Allocator>::iterator +deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) +{ + difference_type __n = __l - __f; + iterator __b = __base::begin(); + difference_type __pos = __f - __b; + iterator __p = __b + __pos; + if (__n > 0) + { + allocator_type& __a = __base::__alloc(); + if (__pos <= (__base::size() - __n) / 2) + { // erase from front + iterator __i = _VSTD::move_backward(__b, __p, __p + __n); + for (; __b != __i; ++__b) + __alloc_traits::destroy(__a, _VSTD::addressof(*__b)); + __base::size() -= __n; + __base::__start_ += __n; + while (__front_spare() >= 2 * __base::__block_size) + { + __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size); + __base::__map_.pop_front(); + __base::__start_ -= __base::__block_size; + } + } + else + { // erase from back + iterator __i = _VSTD::move(__p + __n, __base::end(), __p); + for (iterator __e = __base::end(); __i != __e; ++__i) + __alloc_traits::destroy(__a, _VSTD::addressof(*__i)); + __base::size() -= __n; + while (__back_spare() >= 2 * __base::__block_size) + { + __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size); + __base::__map_.pop_back(); + } + } + } + return __base::begin() + __pos; +} + +template +void +deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f) +{ + iterator __e = __base::end(); + difference_type __n = __e - __f; + if (__n > 0) + { + allocator_type& __a = __base::__alloc(); + iterator __b = __base::begin(); + difference_type __pos = __f - __b; + for (iterator __p = __b + __pos; __p != __e; ++__p) + __alloc_traits::destroy(__a, _VSTD::addressof(*__p)); + __base::size() -= __n; + while (__back_spare() >= 2 * __base::__block_size) + { + __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size); + __base::__map_.pop_back(); + } + } +} + +template +inline +void +deque<_Tp, _Allocator>::swap(deque& __c) +#if _LIBCPP_STD_VER >= 14 + _NOEXCEPT +#else + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + __is_nothrow_swappable::value) +#endif +{ + __base::swap(__c); +} + +template +inline +void +deque<_Tp, _Allocator>::clear() _NOEXCEPT +{ + __base::clear(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) +{ + const typename deque<_Tp, _Allocator>::size_type __sz = __x.size(); + return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) +{ + return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_DEQUE diff --git a/headers/libs/libc++/errno.h b/headers/libs/libc++/errno.h new file mode 100644 index 0000000000..ee6429110c --- /dev/null +++ b/headers/libs/libc++/errno.h @@ -0,0 +1,398 @@ +// -*- C++ -*- +//===-------------------------- errno.h -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_ERRNO_H +#define _LIBCPP_ERRNO_H + +/* + errno.h synopsis + +Macros: + + EDOM + EILSEQ // C99 + ERANGE + errno + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#include_next + +#ifdef __cplusplus + +#if !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE) + +#ifdef ELAST + +static const int __elast1 = ELAST+1; +static const int __elast2 = ELAST+2; + +#else + +static const int __elast1 = 104; +static const int __elast2 = 105; + +#endif + +#ifdef ENOTRECOVERABLE + +#define EOWNERDEAD __elast1 + +#ifdef ELAST +#undef ELAST +#define ELAST EOWNERDEAD +#endif + +#elif defined(EOWNERDEAD) + +#define ENOTRECOVERABLE __elast1 +#ifdef ELAST +#undef ELAST +#define ELAST ENOTRECOVERABLE +#endif + +#else // defined(EOWNERDEAD) + +#define EOWNERDEAD __elast1 +#define ENOTRECOVERABLE __elast2 +#ifdef ELAST +#undef ELAST +#define ELAST ENOTRECOVERABLE +#endif + +#endif // defined(EOWNERDEAD) + +#endif // !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE) + +// supply errno values likely to be missing, particularly on Windows + +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT 9901 +#endif + +#ifndef EADDRINUSE +#define EADDRINUSE 9902 +#endif + +#ifndef EADDRNOTAVAIL +#define EADDRNOTAVAIL 9903 +#endif + +#ifndef EISCONN +#define EISCONN 9904 +#endif + +#ifndef EBADMSG +#define EBADMSG 9905 +#endif + +#ifndef ECONNABORTED +#define ECONNABORTED 9906 +#endif + +#ifndef EALREADY +#define EALREADY 9907 +#endif + +#ifndef ECONNREFUSED +#define ECONNREFUSED 9908 +#endif + +#ifndef ECONNRESET +#define ECONNRESET 9909 +#endif + +#ifndef EDESTADDRREQ +#define EDESTADDRREQ 9910 +#endif + +#ifndef EHOSTUNREACH +#define EHOSTUNREACH 9911 +#endif + +#ifndef EIDRM +#define EIDRM 9912 +#endif + +#ifndef EMSGSIZE +#define EMSGSIZE 9913 +#endif + +#ifndef ENETDOWN +#define ENETDOWN 9914 +#endif + +#ifndef ENETRESET +#define ENETRESET 9915 +#endif + +#ifndef ENETUNREACH +#define ENETUNREACH 9916 +#endif + +#ifndef ENOBUFS +#define ENOBUFS 9917 +#endif + +#ifndef ENOLINK +#define ENOLINK 9918 +#endif + +#ifndef ENODATA +#define ENODATA 9919 +#endif + +#ifndef ENOMSG +#define ENOMSG 9920 +#endif + +#ifndef ENOPROTOOPT +#define ENOPROTOOPT 9921 +#endif + +#ifndef ENOSR +#define ENOSR 9922 +#endif + +#ifndef ENOTSOCK +#define ENOTSOCK 9923 +#endif + +#ifndef ENOSTR +#define ENOSTR 9924 +#endif + +#ifndef ENOTCONN +#define ENOTCONN 9925 +#endif + +#ifndef ENOTSUP +#define ENOTSUP 9926 +#endif + +#ifndef ECANCELED +#define ECANCELED 9927 +#endif + +#ifndef EINPROGRESS +#define EINPROGRESS 9928 +#endif + +#ifndef EOPNOTSUPP +#define EOPNOTSUPP 9929 +#endif + +#ifndef EWOULDBLOCK +#define EWOULDBLOCK 9930 +#endif + +#ifndef EOWNERDEAD +#define EOWNERDEAD 9931 +#endif + +#ifndef EPROTO +#define EPROTO 9932 +#endif + +#ifndef EPROTONOSUPPORT +#define EPROTONOSUPPORT 9933 +#endif + +#ifndef ENOTRECOVERABLE +#define ENOTRECOVERABLE 9934 +#endif + +#ifndef ETIME +#define ETIME 9935 +#endif + +#ifndef ETXTBSY +#define ETXTBSY 9936 +#endif + +#ifndef ETIMEDOUT +#define ETIMEDOUT 9938 +#endif + +#ifndef ELOOP +#define ELOOP 9939 +#endif + +#ifndef EOVERFLOW +#define EOVERFLOW 9940 +#endif + +#ifndef EPROTOTYPE +#define EPROTOTYPE 9941 +#endif + +#ifndef ENOSYS +#define ENOSYS 9942 +#endif + +#ifndef EINVAL +#define EINVAL 9943 +#endif + +#ifndef ERANGE +#define ERANGE 9944 +#endif + +#ifndef EILSEQ +#define EILSEQ 9945 +#endif + +// Windows Mobile doesn't appear to define these: + +#ifndef E2BIG +#define E2BIG 9946 +#endif + +#ifndef EDOM +#define EDOM 9947 +#endif + +#ifndef EFAULT +#define EFAULT 9948 +#endif + +#ifndef EBADF +#define EBADF 9949 +#endif + +#ifndef EPIPE +#define EPIPE 9950 +#endif + +#ifndef EXDEV +#define EXDEV 9951 +#endif + +#ifndef EBUSY +#define EBUSY 9952 +#endif + +#ifndef ENOTEMPTY +#define ENOTEMPTY 9953 +#endif + +#ifndef ENOEXEC +#define ENOEXEC 9954 +#endif + +#ifndef EEXIST +#define EEXIST 9955 +#endif + +#ifndef EFBIG +#define EFBIG 9956 +#endif + +#ifndef ENAMETOOLONG +#define ENAMETOOLONG 9957 +#endif + +#ifndef ENOTTY +#define ENOTTY 9958 +#endif + +#ifndef EINTR +#define EINTR 9959 +#endif + +#ifndef ESPIPE +#define ESPIPE 9960 +#endif + +#ifndef EIO +#define EIO 9961 +#endif + +#ifndef EISDIR +#define EISDIR 9962 +#endif + +#ifndef ECHILD +#define ECHILD 9963 +#endif + +#ifndef ENOLCK +#define ENOLCK 9964 +#endif + +#ifndef ENOSPC +#define ENOSPC 9965 +#endif + +#ifndef ENXIO +#define ENXIO 9966 +#endif + +#ifndef ENODEV +#define ENODEV 9967 +#endif + +#ifndef ENOENT +#define ENOENT 9968 +#endif + +#ifndef ESRCH +#define ESRCH 9969 +#endif + +#ifndef ENOTDIR +#define ENOTDIR 9970 +#endif + +#ifndef ENOMEM +#define ENOMEM 9971 +#endif + +#ifndef EPERM +#define EPERM 9972 +#endif + +#ifndef EACCES +#define EACCES 9973 +#endif + +#ifndef EROFS +#define EROFS 9974 +#endif + +#ifndef EDEADLK +#define EDEADLK 9975 +#endif + +#ifndef EAGAIN +#define EAGAIN 9976 +#endif + +#ifndef ENFILE +#define ENFILE 9977 +#endif + +#ifndef EMFILE +#define EMFILE 9978 +#endif + +#ifndef EMLINK +#define EMLINK 9979 +#endif + +#endif // __cplusplus + +#endif // _LIBCPP_ERRNO_H diff --git a/headers/libs/libc++/exception b/headers/libs/libc++/exception new file mode 100644 index 0000000000..5a905e7e58 --- /dev/null +++ b/headers/libs/libc++/exception @@ -0,0 +1,254 @@ +// -*- C++ -*- +//===-------------------------- exception ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXCEPTION +#define _LIBCPP_EXCEPTION + +/* + exception synopsis + +namespace std +{ + +class exception +{ +public: + exception() noexcept; + exception(const exception&) noexcept; + exception& operator=(const exception&) noexcept; + virtual ~exception() noexcept; + virtual const char* what() const noexcept; +}; + +class bad_exception + : public exception +{ +public: + bad_exception() noexcept; + bad_exception(const bad_exception&) noexcept; + bad_exception& operator=(const bad_exception&) noexcept; + virtual ~bad_exception() noexcept; + virtual const char* what() const noexcept; +}; + +typedef void (*unexpected_handler)(); +unexpected_handler set_unexpected(unexpected_handler f ) noexcept; +unexpected_handler get_unexpected() noexcept; +[[noreturn]] void unexpected(); + +typedef void (*terminate_handler)(); +terminate_handler set_terminate(terminate_handler f ) noexcept; +terminate_handler get_terminate() noexcept; +[[noreturn]] void terminate() noexcept; + +bool uncaught_exception() noexcept; +int uncaught_exceptions() noexcept; // C++17 + +typedef unspecified exception_ptr; + +exception_ptr current_exception() noexcept; +void rethrow_exception [[noreturn]] (exception_ptr p); +template exception_ptr make_exception_ptr(E e) noexcept; + +class nested_exception +{ +public: + nested_exception() noexcept; + nested_exception(const nested_exception&) noexcept = default; + nested_exception& operator=(const nested_exception&) noexcept = default; + virtual ~nested_exception() = default; + + // access functions + [[noreturn]] void rethrow_nested() const; + exception_ptr nested_ptr() const noexcept; +}; + +template [[noreturn]] void throw_with_nested(T&& t); +template void rethrow_if_nested(const E& e); + +} // std + +*/ + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +namespace std // purposefully not using versioning namespace +{ + +class _LIBCPP_EXCEPTION_ABI exception +{ +public: + _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {} + virtual ~exception() _NOEXCEPT; + virtual const char* what() const _NOEXCEPT; +}; + +class _LIBCPP_EXCEPTION_ABI bad_exception + : public exception +{ +public: + _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {} + virtual ~bad_exception() _NOEXCEPT; + virtual const char* what() const _NOEXCEPT; +}; + +typedef void (*unexpected_handler)(); +_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT; +_LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT; +_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected(); + +typedef void (*terminate_handler)(); +_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT; +_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT; +_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT; + +_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT; +_LIBCPP_FUNC_VIS int uncaught_exceptions() _NOEXCEPT; + +class _LIBCPP_TYPE_VIS exception_ptr; + +_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; +_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); + +class _LIBCPP_TYPE_VIS exception_ptr +{ + void* __ptr_; +public: + _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {} + _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} + exception_ptr(const exception_ptr&) _NOEXCEPT; + exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; + ~exception_ptr() _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_EXPLICIT + operator bool() const _NOEXCEPT {return __ptr_ != nullptr;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT + {return __x.__ptr_ == __y.__ptr_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT + {return !(__x == __y);} + + friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; + friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); +}; + +template +exception_ptr +make_exception_ptr(_Ep __e) _NOEXCEPT +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { + throw __e; + } + catch (...) + { + return current_exception(); + } +#endif // _LIBCPP_NO_EXCEPTIONS +} + +// nested_exception + +class _LIBCPP_EXCEPTION_ABI nested_exception +{ + exception_ptr __ptr_; +public: + nested_exception() _NOEXCEPT; +// nested_exception(const nested_exception&) noexcept = default; +// nested_exception& operator=(const nested_exception&) noexcept = default; + virtual ~nested_exception() _NOEXCEPT; + + // access functions + _LIBCPP_NORETURN void rethrow_nested() const; + _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;} +}; + +template +struct __nested + : public _Tp, + public nested_exception +{ + _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {} +}; + +template +_LIBCPP_NORETURN +void +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +throw_with_nested(_Tp&& __t, typename enable_if< + is_class::type>::value && + !is_base_of::type>::value + && !__libcpp_is_final::type>::value + >::type* = 0) +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +throw_with_nested (_Tp& __t, typename enable_if< + is_class<_Tp>::value && !is_base_of::value + >::type* = 0) +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw __nested::type>(_VSTD::forward<_Tp>(__t)); +#endif +} + +template +_LIBCPP_NORETURN +void +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +throw_with_nested(_Tp&& __t, typename enable_if< + !is_class::type>::value || + is_base_of::type>::value + || __libcpp_is_final::type>::value + >::type* = 0) +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +throw_with_nested (_Tp& __t, typename enable_if< + !is_class<_Tp>::value || is_base_of::value + >::type* = 0) +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw _VSTD::forward<_Tp>(__t); +#endif +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +rethrow_if_nested(const _Ep& __e, typename enable_if< + is_polymorphic<_Ep>::value + >::type* = 0) +{ + const nested_exception* __nep = dynamic_cast(&__e); + if (__nep) + __nep->rethrow_nested(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +rethrow_if_nested(const _Ep&, typename enable_if< + !is_polymorphic<_Ep>::value + >::type* = 0) +{ +} + +} // std + +#endif // _LIBCPP_EXCEPTION diff --git a/headers/libs/libc++/experimental/__config b/headers/libs/libc++/experimental/__config new file mode 100644 index 0000000000..f64a3a90cd --- /dev/null +++ b/headers/libs/libc++/experimental/__config @@ -0,0 +1,32 @@ +// -*- C++ -*- +//===--------------------------- __config ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_CONFIG +#define _LIBCPP_EXPERIMENTAL_CONFIG + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL namespace std { namespace experimental { +#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL } } +#define _VSTD_EXPERIMENTAL std::experimental + +#define _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace fundamentals_v1 { +#define _LIBCPP_END_NAMESPACE_LFTS } } } +#define _VSTD_LFTS _VSTD_EXPERIMENTAL::fundamentals_v1 + +#define _LIBCPP_BEGIN_NAMESPACE_CHRONO_LFTS _LIBCPP_BEGIN_NAMESPACE_STD \ + namespace chrono { namespace experimental { inline namespace fundamentals_v1 { +#define _LIBCPP_END_NAMESPACE_CHRONO_LFTS _LIBCPP_END_NAMESPACE_STD } } } + +#endif diff --git a/headers/libs/libc++/experimental/algorithm b/headers/libs/libc++/experimental/algorithm new file mode 100644 index 0000000000..ffaa793b6d --- /dev/null +++ b/headers/libs/libc++/experimental/algorithm @@ -0,0 +1,120 @@ +// -*- C++ -*- +//===-------------------------- algorithm ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_ALGORITHM +#define _LIBCPP_EXPERIMENTAL_ALGORITHM + +/* + experimental/algorithm synopsis + +#include + +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { + +template +ForwardIterator search(ForwardIterator first, ForwardIterator last, + const Searcher &searcher); +template +SampleIterator sample(PopulationIterator first, PopulationIterator last, + SampleIterator out, Distance n, + UniformRandomNumberGenerator &&g); + +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + +*/ + +#include +#include +#include + +#include <__undef_min_max> + +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS + + +template +_LIBCPP_INLINE_VISIBILITY +_ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s) +{ return __s(__f, __l); } + + +template +_LIBCPP_INLINE_VISIBILITY +_SampleIterator __sample(_PopulationIterator __first, + _PopulationIterator __last, _SampleIterator __out, + _Distance __n, + _UniformRandomNumberGenerator &&__g, + input_iterator_tag) { + + _Distance __k = 0; + for (; __first != __last && __k < __n; ++__first, (void)++__k) + __out[__k] = *__first; + _Distance __sz = __k; + for (; __first != __last; ++__first, (void)++__k) { + _Distance __r = _VSTD::uniform_int_distribution<_Distance>(0, __k)(__g); + if (__r < __sz) + __out[__r] = *__first; + } + return __out + _VSTD::min(__n, __k); +} + +template +_LIBCPP_INLINE_VISIBILITY +_SampleIterator __sample(_PopulationIterator __first, + _PopulationIterator __last, _SampleIterator __out, + _Distance __n, + _UniformRandomNumberGenerator &&__g, + forward_iterator_tag) { + _Distance __unsampled_sz = _VSTD::distance(__first, __last); + for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) { + _Distance __r = + _VSTD::uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); + if (__r < __n) { + *__out++ = *__first; + --__n; + } + } + return __out; +} + +template +_LIBCPP_INLINE_VISIBILITY +_SampleIterator sample(_PopulationIterator __first, + _PopulationIterator __last, _SampleIterator __out, + _Distance __n, _UniformRandomNumberGenerator &&__g) { + typedef typename iterator_traits<_PopulationIterator>::iterator_category + _PopCategory; + typedef typename iterator_traits<_PopulationIterator>::difference_type + _Difference; + typedef typename common_type<_Distance, _Difference>::type _CommonType; + _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); + return _VSTD_LFTS::__sample( + __first, __last, __out, _CommonType(__n), + _VSTD::forward<_UniformRandomNumberGenerator>(__g), + _PopCategory()); +} + +_LIBCPP_END_NAMESPACE_LFTS + +#endif /* _LIBCPP_EXPERIMENTAL_ALGORITHM */ diff --git a/headers/libs/libc++/experimental/any b/headers/libs/libc++/experimental/any new file mode 100644 index 0000000000..603788484d --- /dev/null +++ b/headers/libs/libc++/experimental/any @@ -0,0 +1,590 @@ +// -*- C++ -*- +//===------------------------------ any -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_ANY +#define _LIBCPP_EXPERIMENTAL_ANY + +/* + experimental/any synopsis + +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { + + class bad_any_cast : public bad_cast + { + public: + virtual const char* what() const noexcept; + }; + + class any + { + public: + + // 6.3.1 any construct/destruct + any() noexcept; + + any(const any& other); + any(any&& other) noexcept; + + template + any(ValueType&& value); + + ~any(); + + // 6.3.2 any assignments + any& operator=(const any& rhs); + any& operator=(any&& rhs) noexcept; + + template + any& operator=(ValueType&& rhs); + + // 6.3.3 any modifiers + void clear() noexcept; + void swap(any& rhs) noexcept; + + // 6.3.4 any observers + bool empty() const noexcept; + const type_info& type() const noexcept; + }; + + // 6.4 Non-member functions + void swap(any& x, any& y) noexcept; + + template + ValueType any_cast(const any& operand); + template + ValueType any_cast(any& operand); + template + ValueType any_cast(any&& operand); + + template + const ValueType* any_cast(const any* operand) noexcept; + template + ValueType* any_cast(any* operand) noexcept; + +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + +*/ + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS + +class _LIBCPP_EXCEPTION_ABI bad_any_cast : public bad_cast +{ +public: + virtual const char* what() const _NOEXCEPT; +}; + +#if _LIBCPP_STD_VER > 11 // C++ > 11 + +_LIBCPP_NORETURN _LIBCPP_INLINE_VISIBILITY +inline void __throw_bad_any_cast() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_any_cast(); +#else + assert(!"bad_any_cast"); +#endif +} + +// Forward declarations +class any; + +template +typename add_pointer::type>::type +any_cast(any const *) _NOEXCEPT; + +template +typename add_pointer<_ValueType>::type +any_cast(any *) _NOEXCEPT; + +namespace __any_imp +{ + typedef typename aligned_storage<3*sizeof(void*), alignment_of::value>::type + _Buffer; + + template + struct _IsSmallObject + : public integral_constant::value + % alignment_of<_Tp>::value == 0 + && is_nothrow_move_constructible<_Tp>::value + > + {}; + + enum class _Action + { + _Destroy, + _Copy, + _Move, + _Get, + _TypeInfo + }; + + template + struct _SmallHandler; + + template + struct _LargeHandler; + + template + using _Handler = typename conditional<_IsSmallObject<_Tp>::value + , _SmallHandler<_Tp> + , _LargeHandler<_Tp> + >::type; + template + using _EnableIfNotAny = typename + enable_if< + !is_same::type, any>::value + >::type; + +} // namespace __any_imp + +class any +{ +public: + // 6.3.1 any construct/destruct + _LIBCPP_INLINE_VISIBILITY + any() _NOEXCEPT : __h(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + any(any const & __other) : __h(nullptr) + { + if (__other.__h) __other.__call(_Action::_Copy, this); + } + + _LIBCPP_INLINE_VISIBILITY + any(any && __other) _NOEXCEPT : __h(nullptr) + { + if (__other.__h) __other.__call(_Action::_Move, this); + } + + template < + class _ValueType + , class = __any_imp::_EnableIfNotAny<_ValueType> + > + any(_ValueType && __value); + + _LIBCPP_INLINE_VISIBILITY + ~any() + { + this->clear(); + } + + // 6.3.2 any assignments + _LIBCPP_INLINE_VISIBILITY + any & operator=(any const & __rhs) + { + any(__rhs).swap(*this); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + any & operator=(any && __rhs) _NOEXCEPT + { + any(_VSTD::move(__rhs)).swap(*this); + return *this; + } + + template < + class _ValueType + , class = __any_imp::_EnableIfNotAny<_ValueType> + > + any & operator=(_ValueType && __rhs); + + // 6.3.3 any modifiers + _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT + { + if (__h) this->__call(_Action::_Destroy); + } + + void swap(any & __rhs) _NOEXCEPT; + + // 6.3.4 any observers + _LIBCPP_INLINE_VISIBILITY + bool empty() const _NOEXCEPT + { + return __h == nullptr; + } + +#if !defined(_LIBCPP_NO_RTTI) + _LIBCPP_INLINE_VISIBILITY + const type_info & type() const _NOEXCEPT + { + if (__h) { + return *static_cast(this->__call(_Action::_TypeInfo)); + } else { + return typeid(void); + } + } +#endif + +private: + typedef __any_imp::_Action _Action; + + typedef void* (*_HandleFuncPtr)(_Action, any const *, any *, const type_info *); + + union _Storage + { + void * __ptr; + __any_imp::_Buffer __buf; + }; + + _LIBCPP_ALWAYS_INLINE + void * __call(_Action __a, any * __other = nullptr, + type_info const * __info = nullptr) const + { + return __h(__a, this, __other, __info); + } + + _LIBCPP_ALWAYS_INLINE + void * __call(_Action __a, any * __other = nullptr, + type_info const * __info = nullptr) + { + return __h(__a, this, __other, __info); + } + + template + friend struct __any_imp::_SmallHandler; + template + friend struct __any_imp::_LargeHandler; + + template + friend typename add_pointer::type>::type + any_cast(any const *) _NOEXCEPT; + + template + friend typename add_pointer<_ValueType>::type + any_cast(any *) _NOEXCEPT; + + _HandleFuncPtr __h; + _Storage __s; +}; + +namespace __any_imp +{ + + template + struct _LIBCPP_TYPE_VIS_ONLY _SmallHandler + { + _LIBCPP_INLINE_VISIBILITY + static void* __handle(_Action __act, any const * __this, any * __other, + type_info const * __info) + { + switch (__act) + { + case _Action::_Destroy: + __destroy(const_cast(*__this)); + return nullptr; + case _Action::_Copy: + __copy(*__this, *__other); + return nullptr; + case _Action::_Move: + __move(const_cast(*__this), *__other); + return nullptr; + case _Action::_Get: + return __get(const_cast(*__this), __info); + case _Action::_TypeInfo: + return __type_info(); + } + } + + template + _LIBCPP_INLINE_VISIBILITY + static void __create(any & __dest, _Up && __v) + { + ::new (static_cast(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Up>(__v)); + __dest.__h = &_SmallHandler::__handle; + } + + private: + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void __destroy(any & __this) + { + _Tp & __value = *static_cast<_Tp *>(static_cast(&__this.__s.__buf)); + __value.~_Tp(); + __this.__h = nullptr; + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void __copy(any const & __this, any & __dest) + { + _SmallHandler::__create(__dest, *static_cast<_Tp const *>( + static_cast(&__this.__s.__buf))); + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void __move(any & __this, any & __dest) + { + _SmallHandler::__create(__dest, _VSTD::move( + *static_cast<_Tp*>(static_cast(&__this.__s.__buf)))); + __destroy(__this); + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void* __get(any & __this, type_info const * __info) + { +#if !defined(_LIBCPP_NO_RTTI) + if (typeid(_Tp) == *__info) { + return static_cast(&__this.__s.__buf); + } + return nullptr; +#else + return static_cast(&__this.__s.__buf); +#endif + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void* __type_info() + { +#if !defined(_LIBCPP_NO_RTTI) + return const_cast(static_cast(&typeid(_Tp))); +#else + return nullptr; +#endif + } + }; + + template + struct _LIBCPP_TYPE_VIS_ONLY _LargeHandler + { + _LIBCPP_INLINE_VISIBILITY + static void* __handle(_Action __act, any const * __this, any * __other, + type_info const * __info) + { + switch (__act) + { + case _Action::_Destroy: + __destroy(const_cast(*__this)); + return nullptr; + case _Action::_Copy: + __copy(*__this, *__other); + return nullptr; + case _Action::_Move: + __move(const_cast(*__this), *__other); + return nullptr; + case _Action::_Get: + return __get(const_cast(*__this), __info); + case _Action::_TypeInfo: + return __type_info(); + } + } + + template + _LIBCPP_INLINE_VISIBILITY + static void __create(any & __dest, _Up && __v) + { + typedef allocator<_Tp> _Alloc; + typedef __allocator_destructor<_Alloc> _Dp; + _Alloc __a; + unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Up>(__v)); + __dest.__s.__ptr = __hold.release(); + __dest.__h = &_LargeHandler::__handle; + } + + private: + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void __destroy(any & __this) + { + delete static_cast<_Tp*>(__this.__s.__ptr); + __this.__h = nullptr; + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void __copy(any const & __this, any & __dest) + { + _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr)); + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void __move(any & __this, any & __dest) + { + __dest.__s.__ptr = __this.__s.__ptr; + __dest.__h = &_LargeHandler::__handle; + __this.__h = nullptr; + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void* __get(any & __this, type_info const * __info) + { +#if !defined(_LIBCPP_NO_RTTI) + if (typeid(_Tp) == *__info) { + return static_cast(__this.__s.__ptr); + } + return nullptr; +#else + return static_cast(__this.__s.__ptr); +#endif + } + + _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY + static void* __type_info() + { +#if !defined(_LIBCPP_NO_RTTI) + return const_cast(static_cast(&typeid(_Tp))); +#else + return nullptr; +#endif + } + }; + +} // namespace __any_imp + + +template +_LIBCPP_INLINE_VISIBILITY +any::any(_ValueType && __v) : __h(nullptr) +{ + typedef typename decay<_ValueType>::type _Tp; + static_assert(is_copy_constructible<_Tp>::value, + "_ValueType must be CopyConstructible."); + typedef __any_imp::_Handler<_Tp> _HandlerType; + _HandlerType::__create(*this, _VSTD::forward<_ValueType>(__v)); +} + +template +_LIBCPP_INLINE_VISIBILITY +any & any::operator=(_ValueType && __v) +{ + typedef typename decay<_ValueType>::type _Tp; + static_assert(is_copy_constructible<_Tp>::value, + "_ValueType must be CopyConstructible."); + any(_VSTD::forward<_ValueType>(__v)).swap(*this); + return *this; +} + +inline _LIBCPP_INLINE_VISIBILITY +void any::swap(any & __rhs) _NOEXCEPT +{ + if (__h && __rhs.__h) { + any __tmp; + __rhs.__call(_Action::_Move, &__tmp); + this->__call(_Action::_Move, &__rhs); + __tmp.__call(_Action::_Move, this); + } + else if (__h) { + this->__call(_Action::_Move, &__rhs); + } + else if (__rhs.__h) { + __rhs.__call(_Action::_Move, this); + } +} + +// 6.4 Non-member functions + +inline _LIBCPP_INLINE_VISIBILITY +void swap(any & __lhs, any & __rhs) _NOEXCEPT +{ + __lhs.swap(__rhs); +} + +template +_LIBCPP_INLINE_VISIBILITY +_ValueType any_cast(any const & __v) +{ + static_assert( + is_reference<_ValueType>::value + || is_copy_constructible<_ValueType>::value, + "_ValueType is required to be a reference or a CopyConstructible type."); + typedef typename add_const::type>::type + _Tp; + _Tp * __tmp = any_cast<_Tp>(&__v); + if (__tmp == nullptr) + __throw_bad_any_cast(); + return *__tmp; +} + +template +_LIBCPP_INLINE_VISIBILITY +_ValueType any_cast(any & __v) +{ + static_assert( + is_reference<_ValueType>::value + || is_copy_constructible<_ValueType>::value, + "_ValueType is required to be a reference or a CopyConstructible type."); + typedef typename remove_reference<_ValueType>::type _Tp; + _Tp * __tmp = any_cast<_Tp>(&__v); + if (__tmp == nullptr) + __throw_bad_any_cast(); + return *__tmp; +} + +template +_LIBCPP_INLINE_VISIBILITY +_ValueType any_cast(any && __v) +{ + static_assert( + is_reference<_ValueType>::value + || is_copy_constructible<_ValueType>::value, + "_ValueType is required to be a reference or a CopyConstructible type."); + typedef typename remove_reference<_ValueType>::type _Tp; + _Tp * __tmp = any_cast<_Tp>(&__v); + if (__tmp == nullptr) + __throw_bad_any_cast(); + return *__tmp; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename add_pointer::type>::type +any_cast(any const * __any) _NOEXCEPT +{ + static_assert(!is_reference<_ValueType>::value, + "_ValueType may not be a reference."); + return any_cast<_ValueType>(const_cast(__any)); +} + +template +_LIBCPP_INLINE_VISIBILITY +typename add_pointer<_ValueType>::type +any_cast(any * __any) _NOEXCEPT +{ + using __any_imp::_Action; + static_assert(!is_reference<_ValueType>::value, + "_ValueType may not be a reference."); + typedef typename add_pointer<_ValueType>::type _ReturnType; + if (__any && __any->__h) { + + return static_cast<_ReturnType>( + __any->__call(_Action::_Get, nullptr, +#if !defined(_LIBCPP_NO_RTTI) + &typeid(_ValueType) +#else + nullptr +#endif + )); + + } + return nullptr; +} + +#endif // _LIBCPP_STD_VER > 11 + +_LIBCPP_END_NAMESPACE_LFTS + +#endif // _LIBCPP_EXPERIMENTAL_ANY diff --git a/headers/libs/libc++/experimental/chrono b/headers/libs/libc++/experimental/chrono new file mode 100644 index 0000000000..ca9e5f852e --- /dev/null +++ b/headers/libs/libc++/experimental/chrono @@ -0,0 +1,59 @@ +// -*- C++ -*- +//===------------------------------ chrono ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_CHRONO +#define _LIBCPP_EXPERIMENTAL_CHRONO + +/** + experimental/chrono synopsis + +// C++1y + +#include + +namespace std { +namespace chrono { +namespace experimental { +inline namespace fundamentals_v1 { + + // See C++14 20.12.4, customization traits + template constexpr bool treat_as_floating_point_v + = treat_as_floating_point::value; + +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace chrono +} // namespace std + + */ + +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 11 + +_LIBCPP_BEGIN_NAMESPACE_CHRONO_LFTS + +#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES + +template _LIBCPP_CONSTEXPR bool treat_as_floating_point_v + = treat_as_floating_point<_Rep>::value; + +#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */ + +_LIBCPP_END_NAMESPACE_CHRONO_LFTS + +#endif /* _LIBCPP_STD_VER > 11 */ + +#endif /* _LIBCPP_EXPERIMENTAL_CHRONO */ diff --git a/headers/libs/libc++/experimental/dynarray b/headers/libs/libc++/experimental/dynarray new file mode 100644 index 0000000000..f40a6ca188 --- /dev/null +++ b/headers/libs/libc++/experimental/dynarray @@ -0,0 +1,316 @@ +// -*- C++ -*- +//===-------------------------- dynarray ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_DYNARRAY +#define _LIBCPP_DYNARRAY + +#include <__config> +#if _LIBCPP_STD_VER > 11 + +/* + dynarray synopsis + +namespace std { namespace experimental { + +template< typename T > +class dynarray +{ + // types: + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T* pointer; + typedef const T* const_pointer; + typedef implementation-defined iterator; + typedef implementation-defined const_iterator; + typedef reverse_iterator reverse_iterator; + typedef reverse_iterator const_reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + +public: + // construct/copy/destroy: + explicit dynarray(size_type c); + dynarray(size_type c, const T& v); + dynarray(const dynarray& d); + dynarray(initializer_list); + + template + dynarray(allocator_arg_t, const Alloc& a, size_type c, const Alloc& alloc); + template + dynarray(allocator_arg_t, const Alloc& a, size_type c, const T& v, const Alloc& alloc); + template + dynarray(allocator_arg_t, const Alloc& a, const dynarray& d, const Alloc& alloc); + template + dynarray(allocator_arg_t, const Alloc& a, initializer_list, const Alloc& alloc); + dynarray& operator=(const dynarray&) = delete; + ~dynarray(); + + // iterators: + iterator begin() noexcept; + const_iterator begin() const noexcept; + const_iterator cbegin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + const_iterator cend() const noexcept; + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + const_reverse_iterator crbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + const_reverse_iterator crend() const noexcept; + + // capacity: + size_type size() const noexcept; + size_type max_size() const noexcept; + bool empty() const noexcept; + + // element access: + reference operator[](size_type n); + const_reference operator[](size_type n) const; + + reference front(); + const_reference front() const; + reference back(); + const_reference back() const; + + const_reference at(size_type n) const; + reference at(size_type n); + + // data access: + T* data() noexcept; + const T* data() const noexcept; + + // mutating member functions: + void fill(const T& v); +}; + +}} // std::experimental + +*/ + +#include <__functional_base> +#include +#include +#include +#include +#include + +#include <__undef___deallocate> + +#if defined(_LIBCPP_NO_EXCEPTIONS) + #include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +namespace std { namespace experimental { inline namespace __array_extensions_v1 { + +template +struct _LIBCPP_TYPE_VIS_ONLY dynarray +{ +public: + // types: + typedef dynarray __self; + typedef _Tp value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* iterator; + typedef const value_type* const_iterator; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + +private: + size_t __size_; + value_type * __base_; + _LIBCPP_ALWAYS_INLINE dynarray () noexcept : __size_(0), __base_(nullptr) {} + + static inline _LIBCPP_INLINE_VISIBILITY value_type* __allocate ( size_t count ) + { + if ( numeric_limits::max() / sizeof (value_type) <= count ) + { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_array_length(); +#else + assert(!"dynarray::allocation"); +#endif + } + return static_cast (_VSTD::__allocate (sizeof(value_type) * count)); + } + + static inline _LIBCPP_INLINE_VISIBILITY void __deallocate ( value_type* __ptr ) noexcept + { + _VSTD::__deallocate (static_cast (__ptr)); + } + +public: + + explicit dynarray(size_type __c); + dynarray(size_type __c, const value_type& __v); + dynarray(const dynarray& __d); + dynarray(initializer_list); + +// We're not implementing these right now. +// Updated with the resolution of LWG issue #2255 +// template +// dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c); +// template +// dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c, const value_type& __v); +// template +// dynarray(allocator_arg_t, const _Alloc& __alloc, const dynarray& __d); +// template +// dynarray(allocator_arg_t, const _Alloc& __alloc, initializer_list); + + dynarray& operator=(const dynarray&) = delete; + ~dynarray(); + + // iterators: + inline _LIBCPP_INLINE_VISIBILITY iterator begin() noexcept { return iterator(data()); } + inline _LIBCPP_INLINE_VISIBILITY const_iterator begin() const noexcept { return const_iterator(data()); } + inline _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const noexcept { return const_iterator(data()); } + inline _LIBCPP_INLINE_VISIBILITY iterator end() noexcept { return iterator(data() + __size_); } + inline _LIBCPP_INLINE_VISIBILITY const_iterator end() const noexcept { return const_iterator(data() + __size_); } + inline _LIBCPP_INLINE_VISIBILITY const_iterator cend() const noexcept { return const_iterator(data() + __size_); } + + inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } + inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } + inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } + inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rend() noexcept { return reverse_iterator(begin()); } + inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } + inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } + + // capacity: + inline _LIBCPP_INLINE_VISIBILITY size_type size() const noexcept { return __size_; } + inline _LIBCPP_INLINE_VISIBILITY size_type max_size() const noexcept { return __size_; } + inline _LIBCPP_INLINE_VISIBILITY bool empty() const noexcept { return __size_ == 0; } + + // element access: + inline _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) { return data()[__n]; } + inline _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const { return data()[__n]; } + + inline _LIBCPP_INLINE_VISIBILITY reference front() { return data()[0]; } + inline _LIBCPP_INLINE_VISIBILITY const_reference front() const { return data()[0]; } + inline _LIBCPP_INLINE_VISIBILITY reference back() { return data()[__size_-1]; } + inline _LIBCPP_INLINE_VISIBILITY const_reference back() const { return data()[__size_-1]; } + + inline _LIBCPP_INLINE_VISIBILITY const_reference at(size_type __n) const; + inline _LIBCPP_INLINE_VISIBILITY reference at(size_type __n); + + // data access: + inline _LIBCPP_INLINE_VISIBILITY _Tp* data() noexcept { return __base_; } + inline _LIBCPP_INLINE_VISIBILITY const _Tp* data() const noexcept { return __base_; } + + // mutating member functions: + inline _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __v) { fill_n(begin(), __size_, __v); } +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +dynarray<_Tp>::dynarray(size_type __c) : dynarray () +{ + __base_ = __allocate (__c); + value_type *__data = data (); + for ( __size_ = 0; __size_ < __c; ++__size_, ++__data ) + ::new (__data) value_type; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +dynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray () +{ + __base_ = __allocate (__c); + value_type *__data = data (); + for ( __size_ = 0; __size_ < __c; ++__size_, ++__data ) + ::new (__data) value_type (__v); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +dynarray<_Tp>::dynarray(initializer_list __il) : dynarray () +{ + size_t sz = __il.size(); + __base_ = __allocate (sz); + value_type *__data = data (); + auto src = __il.begin(); + for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src ) + ::new (__data) value_type (*src); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +dynarray<_Tp>::dynarray(const dynarray& __d) : dynarray () +{ + size_t sz = __d.size(); + __base_ = __allocate (sz); + value_type *__data = data (); + auto src = __d.begin(); + for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src ) + ::new (__data) value_type (*src); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +dynarray<_Tp>::~dynarray() +{ + value_type *__data = data () + __size_; + for ( size_t i = 0; i < __size_; ++i ) + (--__data)->value_type::~value_type(); + __deallocate ( __base_ ); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename dynarray<_Tp>::reference +dynarray<_Tp>::at(size_type __n) +{ + if (__n >= __size_) + { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw out_of_range("dynarray::at"); +#else + assert(!"dynarray::at out_of_range"); +#endif + } + return data()[__n]; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename dynarray<_Tp>::const_reference +dynarray<_Tp>::at(size_type __n) const +{ + if (__n >= __size_) + { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw out_of_range("dynarray::at"); +#else + assert(!"dynarray::at out_of_range"); +#endif + } + return data()[__n]; +} + +}}} + + +_LIBCPP_BEGIN_NAMESPACE_STD +template +struct _LIBCPP_TYPE_VIS_ONLY uses_allocator, _Alloc> : true_type {}; +_LIBCPP_END_NAMESPACE_STD + +#endif // if _LIBCPP_STD_VER > 11 +#endif // _LIBCPP_DYNARRAY diff --git a/headers/libs/libc++/experimental/functional b/headers/libs/libc++/experimental/functional new file mode 100644 index 0000000000..c7a78695b8 --- /dev/null +++ b/headers/libs/libc++/experimental/functional @@ -0,0 +1,454 @@ +// -*- C++ -*- +//===-------------------------- functional --------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_FUNCTIONAL +#define _LIBCPP_EXPERIMENTAL_FUNCTIONAL + +/* + experimental/functional synopsis + +#include + +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { + + // See C++14 20.9.9, Function object binders + template constexpr bool is_bind_expression_v + = is_bind_expression::value; + template constexpr int is_placeholder_v + = is_placeholder::value; + + // 4.2, Class template function + template class function; // undefined + template class function; + + template + void swap(function&, function&); + + template + bool operator==(const function&, nullptr_t) noexcept; + template + bool operator==(nullptr_t, const function&) noexcept; + template + bool operator!=(const function&, nullptr_t) noexcept; + template + bool operator!=(nullptr_t, const function&) noexcept; + + // 4.3, Searchers + template> + class default_searcher; + + template::value_type>, + class BinaryPredicate = equal_to<>> + class boyer_moore_searcher; + + template::value_type>, + class BinaryPredicate = equal_to<>> + class boyer_moore_horspool_searcher; + + template> + default_searcher + make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last, + BinaryPredicate pred = BinaryPredicate()); + + template::value_type>, + class BinaryPredicate = equal_to<>> + boyer_moore_searcher + make_boyer_moore_searcher( + RandomAccessIterator pat_first, RandomAccessIterator pat_last, + Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); + + template::value_type>, + class BinaryPredicate = equal_to<>> + boyer_moore_horspool_searcher + make_boyer_moore_horspool_searcher( + RandomAccessIterator pat_first, RandomAccessIterator pat_last, + Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); + + } // namespace fundamentals_v1 + } // namespace experimental + + template + struct uses_allocator, Alloc>; + +} // namespace std + +*/ + +#include +#include + +#include +#include +#include +#include +#include + +#include <__undef_min_max> + +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS + +#if _LIBCPP_STD_VER > 11 +// default searcher +template> +_LIBCPP_TYPE_VIS +class default_searcher { +public: + _LIBCPP_INLINE_VISIBILITY + default_searcher(_ForwardIterator __f, _ForwardIterator __l, + _BinaryPredicate __p = _BinaryPredicate()) + : __first_(__f), __last_(__l), __pred_(__p) {} + + template + _LIBCPP_INLINE_VISIBILITY + _ForwardIterator2 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const + { + return _VSTD::search(__f, __l, __first_, __last_, __pred_); + } + +private: + _ForwardIterator __first_; + _ForwardIterator __last_; + _BinaryPredicate __pred_; + }; + +template> +_LIBCPP_INLINE_VISIBILITY +default_searcher<_ForwardIterator, _BinaryPredicate> +make_default_searcher( _ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate ()) +{ + return default_searcher<_ForwardIterator, _BinaryPredicate>(__f, __l, __p); +} + +template class _BMSkipTable; + +// General case for BM data searching; use a map +template +class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> { +public: // TODO private: + typedef _Value value_type; + typedef _Key key_type; + + const _Value __default_value_; + std::unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table; + +public: + _LIBCPP_INLINE_VISIBILITY + _BMSkipTable(std::size_t __sz, _Value __default, _Hash __hf, _BinaryPredicate __pred) + : __default_value_(__default), __table(__sz, __hf, __pred) {} + + _LIBCPP_INLINE_VISIBILITY + void insert(const key_type &__key, value_type __val) + { + __table [__key] = __val; // Would skip_.insert (val) be better here? + } + + _LIBCPP_INLINE_VISIBILITY + value_type operator [](const key_type & __key) const + { + auto __it = __table.find (__key); + return __it == __table.end() ? __default_value_ : __it->second; + } +}; + + +// Special case small numeric values; use an array +template +class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> { +private: + typedef _Value value_type; + typedef _Key key_type; + + typedef typename std::make_unsigned::type unsigned_key_type; + typedef std::array::max()> skip_map; + skip_map __table; + +public: + _LIBCPP_INLINE_VISIBILITY + _BMSkipTable(std::size_t /*__sz*/, _Value __default, _Hash /*__hf*/, _BinaryPredicate /*__pred*/) + { + std::fill_n(__table.begin(), __table.size(), __default); + } + + _LIBCPP_INLINE_VISIBILITY + void insert(key_type __key, value_type __val) + { + __table[static_cast(__key)] = __val; + } + + _LIBCPP_INLINE_VISIBILITY + value_type operator [](key_type __key) const + { + return __table[static_cast(__key)]; + } +}; + + +template ::value_type>, + class _BinaryPredicate = equal_to<>> +_LIBCPP_TYPE_VIS +class boyer_moore_searcher { +private: + typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type; + typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type; + typedef _BMSkipTable::value && // what about enums? + sizeof(value_type) == 1 && + is_same<_Hash, hash>::value && + is_same<_BinaryPredicate, equal_to<>>::value + > skip_table_type; + +public: + boyer_moore_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, + _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) + : __first_(__f), __last_(__l), __pred_(__pred), + __pattern_length_(_VSTD::distance(__first_, __last_)), + __skip_{make_shared(__pattern_length_, -1, __hf, __pred_)}, + __suffix_{make_shared>(__pattern_length_ + 1)} + { + // build the skip table + for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i ) + __skip_->insert(*__f, __i); + + this->__build_suffix_table ( __first_, __last_, __pred_ ); + } + + template + _RandomAccessIterator2 + operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const + { + static_assert ( std::is_same< + typename std::decay::value_type>::type, + typename std::decay::value_type>::type + >::value, + "Corpus and Pattern iterators must point to the same type" ); + + if (__f == __l ) return __l; // empty corpus + if (__first_ == __last_) return __f; // empty pattern + + // If the pattern is larger than the corpus, we can't find it! + if ( __pattern_length_ > _VSTD::distance (__f, __l)) + return __l; + + // Do the search + return this->__search(__f, __l); + } + +public: // TODO private: + _RandomAccessIterator1 __first_; + _RandomAccessIterator1 __last_; + _BinaryPredicate __pred_; + difference_type __pattern_length_; + shared_ptr __skip_; + shared_ptr> __suffix_; + + template + _RandomAccessIterator2 __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const + { + _RandomAccessIterator2 __cur = __f; + const _RandomAccessIterator2 __last = __l - __pattern_length_; + const skip_table_type & __skip = *__skip_.get(); + const vector & __suffix = *__suffix_.get(); + + while (__cur <= __last) + { + + // Do we match right where we are? + difference_type __j = __pattern_length_; + while (__pred_(__first_ [__j-1], __cur [__j-1])) { + __j--; + // We matched - we're done! + if ( __j == 0 ) + return __cur; + } + + // Since we didn't match, figure out how far to skip forward + difference_type __k = __skip[__cur [ __j - 1 ]]; + difference_type __m = __j - __k - 1; + if (__k < __j && __m > __suffix[ __j ]) + __cur += __m; + else + __cur += __suffix[ __j ]; + } + + return __l; // We didn't find anything + } + + + template + void __compute_bm_prefix ( _Iterator __f, _Iterator __l, _BinaryPredicate __pred, _Container &__prefix ) + { + const std::size_t __count = _VSTD::distance(__f, __l); + + __prefix[0] = 0; + std::size_t __k = 0; + for ( std::size_t __i = 1; __i < __count; ++__i ) + { + while ( __k > 0 && !__pred ( __f[__k], __f[__i] )) + __k = __prefix [ __k - 1 ]; + + if ( __pred ( __f[__k], __f[__i] )) + __k++; + __prefix [ __i ] = __k; + } + } + + void __build_suffix_table(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, + _BinaryPredicate __pred) + { + const std::size_t __count = _VSTD::distance(__f, __l); + vector & __suffix = *__suffix_.get(); + if (__count > 0) + { + _VSTD::vector __scratch(__count); + + __compute_bm_prefix(__f, __l, __pred, __scratch); + for ( std::size_t __i = 0; __i <= __count; __i++ ) + __suffix[__i] = __count - __scratch[__count-1]; + + typedef _VSTD::reverse_iterator<_RandomAccessIterator1> _RevIter; + __compute_bm_prefix(_RevIter(__l), _RevIter(__f), __pred, __scratch); + + for ( std::size_t __i = 0; __i < __count; __i++ ) + { + const std::size_t __j = __count - __scratch[__i]; + const difference_type __k = __i - __scratch[__i] + 1; + + if (__suffix[__j] > __k) + __suffix[__j] = __k; + } + } + } + +}; + +template::value_type>, + class _BinaryPredicate = equal_to<>> +_LIBCPP_INLINE_VISIBILITY +boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate> +make_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l, + _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ()) +{ + return boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p); +} + +// boyer-moore-horspool +template ::value_type>, + class _BinaryPredicate = equal_to<>> +_LIBCPP_TYPE_VIS +class boyer_moore_horspool_searcher { +private: + typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type; + typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type; + typedef _BMSkipTable::value && // what about enums? + sizeof(value_type) == 1 && + is_same<_Hash, hash>::value && + is_same<_BinaryPredicate, equal_to<>>::value + > skip_table_type; + +public: + boyer_moore_horspool_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, + _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) + : __first_(__f), __last_(__l), __pred_(__pred), + __pattern_length_(_VSTD::distance(__first_, __last_)), + __skip_{_VSTD::make_shared(__pattern_length_, __pattern_length_, __hf, __pred_)} + { + // build the skip table + if ( __f != __l ) + { + __l = __l - 1; + for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i ) + __skip_->insert(*__f, __pattern_length_ - 1 - __i); + } + } + + template + _RandomAccessIterator2 + operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const + { + static_assert ( std::is_same< + typename std::decay::value_type>::type, + typename std::decay::value_type>::type + >::value, + "Corpus and Pattern iterators must point to the same type" ); + + if (__f == __l ) return __l; // empty corpus + if (__first_ == __last_) return __f; // empty pattern + + // If the pattern is larger than the corpus, we can't find it! + if ( __pattern_length_ > _VSTD::distance (__f, __l)) + return __l; + + // Do the search + return this->__search(__f, __l); + } + +private: + _RandomAccessIterator1 __first_; + _RandomAccessIterator1 __last_; + _BinaryPredicate __pred_; + difference_type __pattern_length_; + shared_ptr __skip_; + + template + _RandomAccessIterator2 __search ( _RandomAccessIterator2 __f, _RandomAccessIterator2 __l ) const { + _RandomAccessIterator2 __cur = __f; + const _RandomAccessIterator2 __last = __l - __pattern_length_; + const skip_table_type & __skip = *__skip_.get(); + + while (__cur <= __last) + { + // Do we match right where we are? + difference_type __j = __pattern_length_; + while (__pred_(__first_[__j-1], __cur[__j-1])) + { + __j--; + // We matched - we're done! + if ( __j == 0 ) + return __cur; + } + __cur += __skip[__cur[__pattern_length_-1]]; + } + + return __l; + } +}; + +template::value_type>, + class _BinaryPredicate = equal_to<>> +_LIBCPP_INLINE_VISIBILITY +boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate> +make_boyer_moore_horspool_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l, + _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ()) +{ + return boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p); +} + +#endif // _LIBCPP_STD_VER > 11 + +_LIBCPP_END_NAMESPACE_LFTS + +#endif /* _LIBCPP_EXPERIMENTAL_FUNCTIONAL */ diff --git a/headers/libs/libc++/experimental/optional b/headers/libs/libc++/experimental/optional new file mode 100644 index 0000000000..a384882a1e --- /dev/null +++ b/headers/libs/libc++/experimental/optional @@ -0,0 +1,894 @@ +// -*- C++ -*- +//===-------------------------- optional ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_OPTIONAL +#define _LIBCPP_OPTIONAL + +/* + optional synopsis + +// C++1y + +namespace std { namespace experimental { inline namespace fundamentals_v1 { + + // 5.3, optional for object types + template class optional; + + // 5.4, In-place construction + struct in_place_t{}; + constexpr in_place_t in_place{}; + + // 5.5, No-value state indicator + struct nullopt_t{see below}; + constexpr nullopt_t nullopt(unspecified); + + // 5.6, Class bad_optional_access + class bad_optional_access; + + // 5.7, Relational operators + template + constexpr bool operator==(const optional&, const optional&); + template + constexpr bool operator!=(const optional&, const optional&); + template + constexpr bool operator<(const optional&, const optional&); + template + constexpr bool operator>(const optional&, const optional&); + template + constexpr bool operator<=(const optional&, const optional&); + template + constexpr bool operator>=(const optional&, const optional&); + + // 5.8, Comparison with nullopt + template constexpr bool operator==(const optional&, nullopt_t) noexcept; + template constexpr bool operator==(nullopt_t, const optional&) noexcept; + template constexpr bool operator!=(const optional&, nullopt_t) noexcept; + template constexpr bool operator!=(nullopt_t, const optional&) noexcept; + template constexpr bool operator<(const optional&, nullopt_t) noexcept; + template constexpr bool operator<(nullopt_t, const optional&) noexcept; + template constexpr bool operator<=(const optional&, nullopt_t) noexcept; + template constexpr bool operator<=(nullopt_t, const optional&) noexcept; + template constexpr bool operator>(const optional&, nullopt_t) noexcept; + template constexpr bool operator>(nullopt_t, const optional&) noexcept; + template constexpr bool operator>=(const optional&, nullopt_t) noexcept; + template constexpr bool operator>=(nullopt_t, const optional&) noexcept; + + // 5.9, Comparison with T + template constexpr bool operator==(const optional&, const T&); + template constexpr bool operator==(const T&, const optional&); + template constexpr bool operator!=(const optional&, const T&); + template constexpr bool operator!=(const T&, const optional&); + template constexpr bool operator<(const optional&, const T&); + template constexpr bool operator<(const T&, const optional&); + template constexpr bool operator<=(const optional&, const T&); + template constexpr bool operator<=(const T&, const optional&); + template constexpr bool operator>(const optional&, const T&); + template constexpr bool operator>(const T&, const optional&); + template constexpr bool operator>=(const optional&, const T&); + template constexpr bool operator>=(const T&, const optional&); + + // 5.10, Specialized algorithms + template void swap(optional&, optional&) noexcept(see below); + template constexpr optional make_optional(T&&); + + template + class optional + { + public: + typedef T value_type; + + // 5.3.1, Constructors + constexpr optional() noexcept; + constexpr optional(nullopt_t) noexcept; + optional(const optional&); + optional(optional&&) noexcept(see below); + constexpr optional(const T&); + constexpr optional(T&&); + template constexpr explicit optional(in_place_t, Args&&...); + template + constexpr explicit optional(in_place_t, initializer_list, Args&&...); + + // 5.3.2, Destructor + ~optional(); + + // 5.3.3, Assignment + optional& operator=(nullopt_t) noexcept; + optional& operator=(const optional&); + optional& operator=(optional&&) noexcept(see below); + template optional& operator=(U&&); + template void emplace(Args&&...); + template + void emplace(initializer_list, Args&&...); + + // 5.3.4, Swap + void swap(optional&) noexcept(see below); + + // 5.3.5, Observers + constexpr T const* operator ->() const; + constexpr T* operator ->(); + constexpr T const& operator *() const &; + constexpr T& operator *() &; + constexpr T&& operator *() &&; + constexpr const T&& operator *() const &&; + constexpr explicit operator bool() const noexcept; + constexpr T const& value() const &; + constexpr T& value() &; + constexpr T&& value() &&; + constexpr const T&& value() const &&; + template constexpr T value_or(U&&) const &; + template constexpr T value_or(U&&) &&; + + private: + T* val; // exposition only + }; + + } // namespace fundamentals_v1 + } // namespace experimental + + // 5.11, Hash support + template struct hash; + template struct hash>; + +} // namespace std + +*/ + +#include +#include +#include + +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL +class _LIBCPP_EXCEPTION_ABI bad_optional_access + : public std::logic_error +{ +public: + bad_optional_access() : std::logic_error("Bad optional Access") {} + +// Get the key function ~bad_optional_access() into the dylib + virtual ~bad_optional_access() _NOEXCEPT; +}; + +_LIBCPP_END_NAMESPACE_EXPERIMENTAL + + +#if _LIBCPP_STD_VER > 11 + +#include +#include +#include +#include <__functional_base> +#include <__undef_min_max> +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS + +struct in_place_t {}; +constexpr in_place_t in_place{}; + +struct nullopt_t +{ + explicit constexpr nullopt_t(int) noexcept {} +}; + +constexpr nullopt_t nullopt{0}; + +template ::value> +class __optional_storage +{ +protected: + typedef _Tp value_type; + union + { + char __null_state_; + value_type __val_; + }; + bool __engaged_ = false; + + _LIBCPP_INLINE_VISIBILITY + ~__optional_storage() + { + if (__engaged_) + __val_.~value_type(); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_storage() noexcept + : __null_state_('\0') {} + + _LIBCPP_INLINE_VISIBILITY + __optional_storage(const __optional_storage& __x) + : __engaged_(__x.__engaged_) + { + if (__engaged_) + ::new(_VSTD::addressof(__val_)) value_type(__x.__val_); + } + + _LIBCPP_INLINE_VISIBILITY + __optional_storage(__optional_storage&& __x) + noexcept(is_nothrow_move_constructible::value) + : __engaged_(__x.__engaged_) + { + if (__engaged_) + ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_storage(const value_type& __v) + : __val_(__v), + __engaged_(true) {} + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_storage(value_type&& __v) + : __val_(_VSTD::move(__v)), + __engaged_(true) {} + + template + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit __optional_storage(in_place_t, _Args&&... __args) + : __val_(_VSTD::forward<_Args>(__args)...), + __engaged_(true) {} +}; + +template +class __optional_storage<_Tp, true> +{ +protected: + typedef _Tp value_type; + union + { + char __null_state_; + value_type __val_; + }; + bool __engaged_ = false; + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_storage() noexcept + : __null_state_('\0') {} + + _LIBCPP_INLINE_VISIBILITY + __optional_storage(const __optional_storage& __x) + : __engaged_(__x.__engaged_) + { + if (__engaged_) + ::new(_VSTD::addressof(__val_)) value_type(__x.__val_); + } + + _LIBCPP_INLINE_VISIBILITY + __optional_storage(__optional_storage&& __x) + noexcept(is_nothrow_move_constructible::value) + : __engaged_(__x.__engaged_) + { + if (__engaged_) + ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_storage(const value_type& __v) + : __val_(__v), + __engaged_(true) {} + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_storage(value_type&& __v) + : __val_(_VSTD::move(__v)), + __engaged_(true) {} + + template + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit __optional_storage(in_place_t, _Args&&... __args) + : __val_(_VSTD::forward<_Args>(__args)...), + __engaged_(true) {} +}; + +template +class optional + : private __optional_storage<_Tp> +{ + typedef __optional_storage<_Tp> __base; +public: + typedef _Tp value_type; + + static_assert(!is_reference::value, + "Instantiation of optional with a reference type is ill-formed."); + static_assert(!is_same::type, in_place_t>::value, + "Instantiation of optional with a in_place_t type is ill-formed."); + static_assert(!is_same::type, nullopt_t>::value, + "Instantiation of optional with a nullopt_t type is ill-formed."); + static_assert(is_object::value, + "Instantiation of optional with a non-object type is undefined behavior."); + static_assert(is_nothrow_destructible::value, + "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior."); + + _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {} + _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default; + _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default; + _LIBCPP_INLINE_VISIBILITY ~optional() = default; + _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {} + _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v) + : __base(__v) {} + _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v) + : __base(_VSTD::move(__v)) {} + + template ::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit optional(in_place_t, _Args&&... __args) + : __base(in_place, _VSTD::forward<_Args>(__args)...) {} + + template &, _Args...>::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + constexpr + explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) + : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {} + + _LIBCPP_INLINE_VISIBILITY + optional& operator=(nullopt_t) noexcept + { + if (this->__engaged_) + { + this->__val_.~value_type(); + this->__engaged_ = false; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + optional& + operator=(const optional& __opt) + { + if (this->__engaged_ == __opt.__engaged_) + { + if (this->__engaged_) + this->__val_ = __opt.__val_; + } + else + { + if (this->__engaged_) + this->__val_.~value_type(); + else + ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_); + this->__engaged_ = __opt.__engaged_; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + optional& + operator=(optional&& __opt) + noexcept(is_nothrow_move_assignable::value && + is_nothrow_move_constructible::value) + { + if (this->__engaged_ == __opt.__engaged_) + { + if (this->__engaged_) + this->__val_ = _VSTD::move(__opt.__val_); + } + else + { + if (this->__engaged_) + this->__val_.~value_type(); + else + ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_)); + this->__engaged_ = __opt.__engaged_; + } + return *this; + } + + template ::type, value_type>::value && + is_constructible::value && + is_assignable::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + optional& + operator=(_Up&& __v) + { + if (this->__engaged_) + this->__val_ = _VSTD::forward<_Up>(__v); + else + { + ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v)); + this->__engaged_ = true; + } + return *this; + } + + template ::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + void + emplace(_Args&&... __args) + { + *this = nullopt; + ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...); + this->__engaged_ = true; + } + + template &, _Args...>::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + void + emplace(initializer_list<_Up> __il, _Args&&... __args) + { + *this = nullopt; + ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...); + this->__engaged_ = true; + } + + _LIBCPP_INLINE_VISIBILITY + void + swap(optional& __opt) + noexcept(is_nothrow_move_constructible::value && + __is_nothrow_swappable::value) + { + using _VSTD::swap; + if (this->__engaged_ == __opt.__engaged_) + { + if (this->__engaged_) + swap(this->__val_, __opt.__val_); + } + else + { + if (this->__engaged_) + { + ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_)); + this->__val_.~value_type(); + } + else + { + ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_)); + __opt.__val_.~value_type(); + } + swap(this->__engaged_, __opt.__engaged_); + } + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + value_type const* + operator->() const + { + _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); + return __operator_arrow(__has_operator_addressof{}); + } + + _LIBCPP_INLINE_VISIBILITY + value_type* + operator->() + { + _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); + return _VSTD::addressof(this->__val_); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + const value_type& + operator*() const + { + _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); + return this->__val_; + } + + _LIBCPP_INLINE_VISIBILITY + value_type& + operator*() + { + _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); + return this->__val_; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr explicit operator bool() const noexcept {return this->__engaged_;} + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type const& value() const + { + if (!this->__engaged_) + throw bad_optional_access(); + return this->__val_; + } + + _LIBCPP_INLINE_VISIBILITY + value_type& value() + { + if (!this->__engaged_) + throw bad_optional_access(); + return this->__val_; + } + + template + _LIBCPP_INLINE_VISIBILITY + constexpr value_type value_or(_Up&& __v) const& + { + static_assert(is_copy_constructible::value, + "optional::value_or: T must be copy constructible"); + static_assert(is_convertible<_Up, value_type>::value, + "optional::value_or: U must be convertible to T"); + return this->__engaged_ ? this->__val_ : + static_cast(_VSTD::forward<_Up>(__v)); + } + + template + _LIBCPP_INLINE_VISIBILITY + value_type value_or(_Up&& __v) && + { + static_assert(is_move_constructible::value, + "optional::value_or: T must be move constructible"); + static_assert(is_convertible<_Up, value_type>::value, + "optional::value_or: U must be convertible to T"); + return this->__engaged_ ? _VSTD::move(this->__val_) : + static_cast(_VSTD::forward<_Up>(__v)); + } + +private: + _LIBCPP_INLINE_VISIBILITY + value_type const* + __operator_arrow(true_type) const + { + return _VSTD::addressof(this->__val_); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + value_type const* + __operator_arrow(false_type) const + { + return &this->__val_; + } +}; + +// Comparisons between optionals +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (static_cast(__x) != static_cast(__y)) + return false; + if (!static_cast(__x)) + return true; + return *__x == *__y; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast(__y)) + return false; + if (!static_cast(__x)) + return true; + return *__x < *__y; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + return !(__x < __y); +} + + +// Comparisons with nullopt +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return !static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return !static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator!=(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator!=(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(const optional<_Tp>&, nullopt_t) noexcept +{ + return false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<=(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return !static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<=(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return static_cast(__x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>=(const optional<_Tp>&, nullopt_t) noexcept +{ + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>=(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return !static_cast(__x); +} + +// Comparisons with T +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? *__x == __v : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator==(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? *__x == __v : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator!=(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? !(*__x == __v) : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator!=(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? !(*__x == __v) : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? less<_Tp>{}(*__x, __v) : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? less<_Tp>{}(__v, *__x) : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<=(const optional<_Tp>& __x, const _Tp& __v) +{ + return !(__x > __v); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator<=(const _Tp& __v, const optional<_Tp>& __x) +{ + return !(__v > __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast(__x) ? __v < __x : false; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast(__x) ? __x < __v : true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>=(const optional<_Tp>& __x, const _Tp& __v) +{ + return !(__x < __v); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +bool +operator>=(const _Tp& __v, const optional<_Tp>& __x) +{ + return !(__v < __x); +} + + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) +{ + __x.swap(__y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +constexpr +optional::type> +make_optional(_Tp&& __v) +{ + return optional::type>(_VSTD::forward<_Tp>(__v)); +} + +_LIBCPP_END_NAMESPACE_LFTS + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TYPE_VIS_ONLY hash > +{ + typedef std::experimental::optional<_Tp> argument_type; + typedef size_t result_type; + + _LIBCPP_INLINE_VISIBILITY + result_type operator()(const argument_type& __opt) const _NOEXCEPT + { + return static_cast(__opt) ? hash<_Tp>()(*__opt) : 0; + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 11 + +#endif // _LIBCPP_OPTIONAL diff --git a/headers/libs/libc++/experimental/ratio b/headers/libs/libc++/experimental/ratio new file mode 100644 index 0000000000..757f24e086 --- /dev/null +++ b/headers/libs/libc++/experimental/ratio @@ -0,0 +1,77 @@ +// -*- C++ -*- +//===------------------------------ ratio ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_RATIO +#define _LIBCPP_EXPERIMENTAL_RATIO + +/** + experimental/ratio synopsis + C++1y +#include + +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { + + // See C++14 20.11.5, ratio comparison + template constexpr bool ratio_equal_v + = ratio_equal::value; + template constexpr bool ratio_not_equal_v + = ratio_not_equal::value; + template constexpr bool ratio_less_v + = ratio_less::value; + template constexpr bool ratio_less_equal_v + = ratio_less_equal::value; + template constexpr bool ratio_greater_v + = ratio_greater::value; + template constexpr bool ratio_greater_equal_v + = ratio_greater_equal::value; + +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + +*/ + +#include + +#if _LIBCPP_STD_VER > 11 + +#include + +_LIBCPP_BEGIN_NAMESPACE_LFTS + +#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES + +template _LIBCPP_CONSTEXPR bool ratio_equal_v + = ratio_equal<_R1, _R2>::value; + +template _LIBCPP_CONSTEXPR bool ratio_not_equal_v + = ratio_not_equal<_R1, _R2>::value; + +template _LIBCPP_CONSTEXPR bool ratio_less_v + = ratio_less<_R1, _R2>::value; + +template _LIBCPP_CONSTEXPR bool ratio_less_equal_v + = ratio_less_equal<_R1, _R2>::value; + +template _LIBCPP_CONSTEXPR bool ratio_greater_v + = ratio_greater<_R1, _R2>::value; + +template _LIBCPP_CONSTEXPR bool ratio_greater_equal_v + = ratio_greater_equal<_R1, _R2>::value; + +#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */ + +_LIBCPP_END_NAMESPACE_LFTS + +#endif /* _LIBCPP_STD_VER > 11 */ + +#endif // _LIBCPP_EXPERIMENTAL_RATIO diff --git a/headers/libs/libc++/experimental/string_view b/headers/libs/libc++/experimental/string_view new file mode 100644 index 0000000000..2a20d7caa6 --- /dev/null +++ b/headers/libs/libc++/experimental/string_view @@ -0,0 +1,812 @@ +// -*- C++ -*- +//===------------------------ string_view ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_LFTS_STRING_VIEW +#define _LIBCPP_LFTS_STRING_VIEW + +/* +string_view synopsis + +namespace std { + namespace experimental { + inline namespace library_fundamentals_v1 { + + // 7.2, Class template basic_string_view + template> + class basic_string_view; + + // 7.9, basic_string_view non-member comparison functions + template + constexpr bool operator==(basic_string_view x, + basic_string_view y) noexcept; + template + constexpr bool operator!=(basic_string_view x, + basic_string_view y) noexcept; + template + constexpr bool operator< (basic_string_view x, + basic_string_view y) noexcept; + template + constexpr bool operator> (basic_string_view x, + basic_string_view y) noexcept; + template + constexpr bool operator<=(basic_string_view x, + basic_string_view y) noexcept; + template + constexpr bool operator>=(basic_string_view x, + basic_string_view y) noexcept; + // see below, sufficient additional overloads of comparison functions + + // 7.10, Inserters and extractors + template + basic_ostream& + operator<<(basic_ostream& os, + basic_string_view str); + + // basic_string_view typedef names + typedef basic_string_view string_view; + typedef basic_string_view u16string_view; + typedef basic_string_view u32string_view; + typedef basic_string_view wstring_view; + + template> + class basic_string_view { + public: + // types + typedef traits traits_type; + typedef charT value_type; + typedef charT* pointer; + typedef const charT* const_pointer; + typedef charT& reference; + typedef const charT& const_reference; + typedef implementation-defined const_iterator; + typedef const_iterator iterator; + typedef reverse_iterator const_reverse_iterator; + typedef const_reverse_iterator reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + static constexpr size_type npos = size_type(-1); + + // 7.3, basic_string_view constructors and assignment operators + constexpr basic_string_view() noexcept; + constexpr basic_string_view(const basic_string_view&) noexcept = default; + basic_string_view& operator=(const basic_string_view&) noexcept = default; + template + basic_string_view(const basic_string& str) noexcept; + constexpr basic_string_view(const charT* str); + constexpr basic_string_view(const charT* str, size_type len); + + // 7.4, basic_string_view iterator support + constexpr const_iterator begin() const noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + const_reverse_iterator rbegin() const noexcept; + const_reverse_iterator rend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + // 7.5, basic_string_view capacity + constexpr size_type size() const noexcept; + constexpr size_type length() const noexcept; + constexpr size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + + // 7.6, basic_string_view element access + constexpr const_reference operator[](size_type pos) const; + constexpr const_reference at(size_type pos) const; + constexpr const_reference front() const; + constexpr const_reference back() const; + constexpr const_pointer data() const noexcept; + + // 7.7, basic_string_view modifiers + constexpr void clear() noexcept; + constexpr void remove_prefix(size_type n); + constexpr void remove_suffix(size_type n); + constexpr void swap(basic_string_view& s) noexcept; + + // 7.8, basic_string_view string operations + template + explicit operator basic_string() const; + template> + basic_string to_string( + const Allocator& a = Allocator()) const; + + size_type copy(charT* s, size_type n, size_type pos = 0) const; + + constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const; + constexpr int compare(basic_string_view s) const noexcept; + constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const; + constexpr int compare(size_type pos1, size_type n1, + basic_string_view s, size_type pos2, size_type n2) const; + constexpr int compare(const charT* s) const; + constexpr int compare(size_type pos1, size_type n1, const charT* s) const; + constexpr int compare(size_type pos1, size_type n1, + const charT* s, size_type n2) const; + constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept; + constexpr size_type find(charT c, size_type pos = 0) const noexcept; + constexpr size_type find(const charT* s, size_type pos, size_type n) const; + constexpr size_type find(const charT* s, size_type pos = 0) const; + constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept; + constexpr size_type rfind(charT c, size_type pos = npos) const noexcept; + constexpr size_type rfind(const charT* s, size_type pos, size_type n) const; + constexpr size_type rfind(const charT* s, size_type pos = npos) const; + constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept; + constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept; + constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const; + constexpr size_type find_first_of(const charT* s, size_type pos = 0) const; + constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept; + constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept; + constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const; + constexpr size_type find_last_of(const charT* s, size_type pos = npos) const; + constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept; + constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept; + constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const; + constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const; + constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept; + constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept; + constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const; + constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const; + + private: + const_pointer data_; // exposition only + size_type size_; // exposition only + }; + + } // namespace fundamentals_v1 + } // namespace experimental + + // 7.11, Hash support + template struct hash; + template <> struct hash; + template <> struct hash; + template <> struct hash; + template <> struct hash; + +} // namespace std + + +*/ + +#include + +#include +#include +#include +#include +#include + +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS + + template > + class _LIBCPP_TYPE_VIS_ONLY basic_string_view { + public: + // types + typedef _Traits traits_type; + typedef _CharT value_type; + typedef const _CharT* pointer; + typedef const _CharT* const_pointer; + typedef const _CharT& reference; + typedef const _CharT& const_reference; + typedef const_pointer const_iterator; // See [string.view.iterators] + typedef const_iterator iterator; + typedef _VSTD::reverse_iterator const_reverse_iterator; + typedef const_reverse_iterator reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1); + + // [string.view.cons], construct/copy + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {} + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + basic_string_view(const basic_string_view&) _NOEXCEPT = default; + + _LIBCPP_INLINE_VISIBILITY + basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default; + + template + _LIBCPP_INLINE_VISIBILITY + basic_string_view(const basic_string<_CharT, _Traits, _Allocator>& __str) _NOEXCEPT + : __data (__str.data()), __size(__str.size()) {} + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + basic_string_view(const _CharT* __s, size_type __len) + : __data(__s), __size(__len) + { +// _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): recieved nullptr"); + } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + basic_string_view(const _CharT* __s) + : __data(__s), __size(_Traits::length(__s)) {} + + // [string.view.iterators], iterators + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT { return cbegin(); } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT { return cend(); } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_iterator cbegin() const _NOEXCEPT { return __data; } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_iterator cend() const _NOEXCEPT { return __data + __size; } + + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } + + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } + + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } + + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } + + // [string.view.capacity], capacity + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT { return __size; } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + size_type length() const _NOEXCEPT { return __size; } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT { return _VSTD::numeric_limits::max(); } + + _LIBCPP_CONSTEXPR bool _LIBCPP_INLINE_VISIBILITY + empty() const _NOEXCEPT { return __size == 0; } + + // [string.view.access], element access + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_reference operator[](size_type __pos) const { return __data[__pos]; } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_reference at(size_type __pos) const + { + return __pos >= size() + ? (throw out_of_range("string_view::at"), __data[0]) + : __data[__pos]; + } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_reference front() const + { + return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0]; + } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_reference back() const + { + return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1]; + } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_pointer data() const _NOEXCEPT { return __data; } + + // [string.view.modifiers], modifiers: + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT + { + __data = nullptr; + __size = 0; + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + void remove_prefix(size_type __n) _NOEXCEPT + { + _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()"); + __data += __n; + __size -= __n; + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + void remove_suffix(size_type __n) _NOEXCEPT + { + _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()"); + __size -= __n; + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + void swap(basic_string_view& __other) _NOEXCEPT + { + const value_type *__p = __data; + __data = __other.__data; + __other.__data = __p; + + size_type __sz = __size; + __size = __other.__size; + __other.__size = __sz; +// _VSTD::swap( __data, __other.__data ); +// _VSTD::swap( __size, __other.__size ); + } + + // [string.view.ops], string operations: + template + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_EXPLICIT operator basic_string<_CharT, _Traits, _Allocator>() const + { return basic_string<_CharT, _Traits, _Allocator>( begin(), end()); } + + template > + _LIBCPP_INLINE_VISIBILITY + basic_string<_CharT, _Traits, _Allocator> + to_string( const _Allocator& __a = _Allocator()) const + { return basic_string<_CharT, _Traits, _Allocator> ( begin(), end(), __a ); } + + size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const + { + if ( __pos > size()) + throw out_of_range("string_view::copy"); + size_type __rlen = _VSTD::min( __n, size() - __pos ); + _VSTD::copy_n(begin() + __pos, __rlen, __s ); + return __rlen; + } + + _LIBCPP_CONSTEXPR + basic_string_view substr(size_type __pos = 0, size_type __n = npos) const + { +// if (__pos > size()) +// throw out_of_range("string_view::substr"); +// size_type __rlen = _VSTD::min( __n, size() - __pos ); +// return basic_string_view(data() + __pos, __rlen); + return __pos > size() + ? throw out_of_range("string_view::substr") + : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos)); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT + { + size_type __rlen = _VSTD::min( size(), __sv.size()); + int __retval = _Traits::compare(data(), __sv.data(), __rlen); + if ( __retval == 0 ) // first __rlen chars matched + __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 ); + return __retval; + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const + { + return substr(__pos1, __n1).compare(__sv); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + int compare( size_type __pos1, size_type __n1, + basic_string_view _sv, size_type __pos2, size_type __n2) const + { + return substr(__pos1, __n1).compare(_sv.substr(__pos2, __n2)); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + int compare(const _CharT* __s) const + { + return compare(basic_string_view(__s)); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + int compare(size_type __pos1, size_type __n1, const _CharT* __s) const + { + return substr(__pos1, __n1).compare(basic_string_view(__s)); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const + { + return substr(__pos1, __n1).compare(basic_string_view(__s, __n2)); + } + + // find + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT + { + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): recieved nullptr"); + return _VSTD::__str_find + (data(), size(), __s.data(), __pos, __s.size()); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT + { + return _VSTD::__str_find + (data(), size(), __c, __pos); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find(const _CharT* __s, size_type __pos, size_type __n) const + { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): recieved nullptr"); + return _VSTD::__str_find + (data(), size(), __s, __pos, __n); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find(const _CharT* __s, size_type __pos = 0) const + { + _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): recieved nullptr"); + return _VSTD::__str_find + (data(), size(), __s, __pos, traits_type::length(__s)); + } + + // rfind + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT + { + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): recieved nullptr"); + return _VSTD::__str_rfind + (data(), size(), __s.data(), __pos, __s.size()); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT + { + return _VSTD::__str_rfind + (data(), size(), __c, __pos); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const + { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): recieved nullptr"); + return _VSTD::__str_rfind + (data(), size(), __s, __pos, __n); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type rfind(const _CharT* __s, size_type __pos=npos) const + { + _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): recieved nullptr"); + return _VSTD::__str_rfind + (data(), size(), __s, __pos, traits_type::length(__s)); + } + + // find_first_of + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT + { + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): recieved nullptr"); + return _VSTD::__str_find_first_of + (data(), size(), __s.data(), __pos, __s.size()); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT + { return find(__c, __pos); } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const + { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): recieved nullptr"); + return _VSTD::__str_find_first_of + (data(), size(), __s, __pos, __n); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_of(const _CharT* __s, size_type __pos=0) const + { + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): recieved nullptr"); + return _VSTD::__str_find_first_of + (data(), size(), __s, __pos, traits_type::length(__s)); + } + + // find_last_of + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT + { + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): recieved nullptr"); + return _VSTD::__str_find_last_of + (data(), size(), __s.data(), __pos, __s.size()); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT + { return rfind(__c, __pos); } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const + { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): recieved nullptr"); + return _VSTD::__str_find_last_of + (data(), size(), __s, __pos, __n); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_of(const _CharT* __s, size_type __pos=npos) const + { + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): recieved nullptr"); + return _VSTD::__str_find_last_of + (data(), size(), __s, __pos, traits_type::length(__s)); + } + + // find_first_not_of + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT + { + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): recieved nullptr"); + return _VSTD::__str_find_first_not_of + (data(), size(), __s.data(), __pos, __s.size()); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT + { + return _VSTD::__str_find_first_not_of + (data(), size(), __c, __pos); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): recieved nullptr"); + return _VSTD::__str_find_first_not_of + (data(), size(), __s, __pos, __n); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const + { + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): recieved nullptr"); + return _VSTD::__str_find_first_not_of + (data(), size(), __s, __pos, traits_type::length(__s)); + } + + // find_last_not_of + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT + { + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): recieved nullptr"); + return _VSTD::__str_find_last_not_of + (data(), size(), __s.data(), __pos, __s.size()); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT + { + return _VSTD::__str_find_last_not_of + (data(), size(), __c, __pos); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): recieved nullptr"); + return _VSTD::__str_find_last_not_of + (data(), size(), __s, __pos, __n); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const + { + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): recieved nullptr"); + return _VSTD::__str_find_last_not_of + (data(), size(), __s, __pos, traits_type::length(__s)); + } + + private: + const value_type* __data; + size_type __size; + }; + + + // [string.view.comparison] + // operator == + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator==(basic_string_view<_CharT, _Traits> __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT + { + if ( __lhs.size() != __rhs.size()) return false; + return __lhs.compare(__rhs) == 0; + } + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator==(basic_string_view<_CharT, _Traits> __lhs, + typename _VSTD::common_type >::type __rhs) _NOEXCEPT + { + if ( __lhs.size() != __rhs.size()) return false; + return __lhs.compare(__rhs) == 0; + } + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator==(typename _VSTD::common_type >::type __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT + { + if ( __lhs.size() != __rhs.size()) return false; + return __lhs.compare(__rhs) == 0; + } + + + // operator != + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT + { + if ( __lhs.size() != __rhs.size()) + return true; + return __lhs.compare(__rhs) != 0; + } + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator!=(basic_string_view<_CharT, _Traits> __lhs, + typename _VSTD::common_type >::type __rhs) _NOEXCEPT + { + if ( __lhs.size() != __rhs.size()) + return true; + return __lhs.compare(__rhs) != 0; + } + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator!=(typename _VSTD::common_type >::type __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT + { + if ( __lhs.size() != __rhs.size()) + return true; + return __lhs.compare(__rhs) != 0; + } + + + // operator < + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT + { + return __lhs.compare(__rhs) < 0; + } + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator<(basic_string_view<_CharT, _Traits> __lhs, + typename _VSTD::common_type >::type __rhs) _NOEXCEPT + { + return __lhs.compare(__rhs) < 0; + } + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator<(typename _VSTD::common_type >::type __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT + { + return __lhs.compare(__rhs) < 0; + } + + + // operator > + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT + { + return __lhs.compare(__rhs) > 0; + } + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator>(basic_string_view<_CharT, _Traits> __lhs, + typename _VSTD::common_type >::type __rhs) _NOEXCEPT + { + return __lhs.compare(__rhs) > 0; + } + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator>(typename _VSTD::common_type >::type __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT + { + return __lhs.compare(__rhs) > 0; + } + + + // operator <= + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT + { + return __lhs.compare(__rhs) <= 0; + } + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator<=(basic_string_view<_CharT, _Traits> __lhs, + typename _VSTD::common_type >::type __rhs) _NOEXCEPT + { + return __lhs.compare(__rhs) <= 0; + } + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator<=(typename _VSTD::common_type >::type __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT + { + return __lhs.compare(__rhs) <= 0; + } + + + // operator >= + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT + { + return __lhs.compare(__rhs) >= 0; + } + + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator>=(basic_string_view<_CharT, _Traits> __lhs, + typename _VSTD::common_type >::type __rhs) _NOEXCEPT + { + return __lhs.compare(__rhs) >= 0; + } + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator>=(typename _VSTD::common_type >::type __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT + { + return __lhs.compare(__rhs) >= 0; + } + + + // [string.view.io] + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __sv) + { + return _VSTD::__put_character_sequence(__os, __sv.data(), __sv.size()); + } + + typedef basic_string_view string_view; + typedef basic_string_view u16string_view; + typedef basic_string_view u32string_view; + typedef basic_string_view wstring_view; + +_LIBCPP_END_NAMESPACE_LFTS +_LIBCPP_BEGIN_NAMESPACE_STD + +// [string.view.hash] +// Shamelessly stolen from +template +struct _LIBCPP_TYPE_VIS_ONLY hash > + : public unary_function, size_t> +{ + size_t operator()(const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT; +}; + +template +size_t +hash >::operator()( + const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT +{ + return __do_string_hash(__val.data(), __val.data() + __val.size()); +} + +#if _LIBCPP_STD_VER > 11 +template +__quoted_output_proxy<_CharT, const _CharT *, _Traits> +quoted ( std::experimental::basic_string_view <_CharT, _Traits> __sv, + _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +{ + return __quoted_output_proxy<_CharT, const _CharT *, _Traits> + ( __sv.data(), __sv.data() + __sv.size(), __delim, __escape ); +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_LFTS_STRING_VIEW diff --git a/headers/libs/libc++/experimental/system_error b/headers/libs/libc++/experimental/system_error new file mode 100644 index 0000000000..2ec2385446 --- /dev/null +++ b/headers/libs/libc++/experimental/system_error @@ -0,0 +1,63 @@ +// -*- C++ -*- +//===-------------------------- system_error ------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR +#define _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR + +/** + experimental/system_error synopsis + +// C++1y + +#include + +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { + + // See C++14 19.5, System error support + template constexpr bool is_error_code_enum_v + = is_error_code_enum::value; + template constexpr bool is_error_condition_enum_v + = is_error_condition_enum::value; + +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + +*/ + +#include + +#if _LIBCPP_STD_VER > 11 + +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS + +#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES + +template _LIBCPP_CONSTEXPR bool is_error_code_enum_v + = is_error_code_enum<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_error_condition_enum_v + = is_error_condition_enum<_Tp>::value; + +#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */ + +_LIBCPP_END_NAMESPACE_LFTS + +#endif /* _LIBCPP_STD_VER > 11 */ + +#endif /* _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR */ diff --git a/headers/libs/libc++/experimental/tuple b/headers/libs/libc++/experimental/tuple new file mode 100644 index 0000000000..50d1e0555b --- /dev/null +++ b/headers/libs/libc++/experimental/tuple @@ -0,0 +1,81 @@ +// -*- C++ -*- +//===----------------------------- tuple ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_TUPLE +#define _LIBCPP_EXPERIMENTAL_TUPLE + +/* + experimental/tuple synopsis + +// C++1y + +#include + +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { + + // See C++14 20.4.2.5, tuple helper classes + template constexpr size_t tuple_size_v + = tuple_size::value; + + // 3.2.2, Calling a function with a tuple of arguments + template + constexpr decltype(auto) apply(F&& f, Tuple&& t); + +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +# include + +#if _LIBCPP_STD_VER > 11 + +# include +# include +# include <__functional_base> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS + +#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES +template +_LIBCPP_CONSTEXPR size_t tuple_size_v = tuple_size<_Tp>::value; +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t, + integer_sequence) { + return _VSTD::__invoke( + _VSTD::forward<_Fn>(__f), + _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))... + ); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +decltype(auto) apply(_Fn && __f, _Tuple && __t) { + return _VSTD_LFTS::__apply_tuple_impl( + _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t), + make_index_sequence::type>::value>() + ); +} + +_LIBCPP_END_NAMESPACE_LFTS + +#endif /* _LIBCPP_STD_VER > 11 */ + +#endif /* _LIBCPP_EXPERIMENTAL_TUPLE */ diff --git a/headers/libs/libc++/experimental/type_traits b/headers/libs/libc++/experimental/type_traits new file mode 100644 index 0000000000..ae49fc176c --- /dev/null +++ b/headers/libs/libc++/experimental/type_traits @@ -0,0 +1,427 @@ +// -*- C++ -*- +//===-------------------------- type_traits -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_TYPE_TRAITS +#define _LIBCPP_EXPERIMENTAL_TYPE_TRAITS + +/** + experimental/type_traits synopsis + +// C++1y +#include + +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { + + // See C++14 20.10.4.1, primary type categories + template constexpr bool is_void_v + = is_void::value; + template constexpr bool is_null_pointer_v + = is_null_pointer::value; + template constexpr bool is_integral_v + = is_integral::value; + template constexpr bool is_floating_point_v + = is_floating_point::value; + template constexpr bool is_array_v + = is_array::value; + template constexpr bool is_pointer_v + = is_pointer::value; + template constexpr bool is_lvalue_reference_v + = is_lvalue_reference::value; + template constexpr bool is_rvalue_reference_v + = is_rvalue_reference::value; + template constexpr bool is_member_object_pointer_v + = is_member_object_pointer::value; + template constexpr bool is_member_function_pointer_v + = is_member_function_pointer::value; + template constexpr bool is_enum_v + = is_enum::value; + template constexpr bool is_union_v + = is_union::value; + template constexpr bool is_class_v + = is_class::value; + template constexpr bool is_function_v + = is_function::value; + + // See C++14 20.10.4.2, composite type categories + template constexpr bool is_reference_v + = is_reference::value; + template constexpr bool is_arithmetic_v + = is_arithmetic::value; + template constexpr bool is_fundamental_v + = is_fundamental::value; + template constexpr bool is_object_v + = is_object::value; + template constexpr bool is_scalar_v + = is_scalar::value; + template constexpr bool is_compound_v + = is_compound::value; + template constexpr bool is_member_pointer_v + = is_member_pointer::value; + + // See C++14 20.10.4.3, type properties + template constexpr bool is_const_v + = is_const::value; + template constexpr bool is_volatile_v + = is_volatile::value; + template constexpr bool is_trivial_v + = is_trivial::value; + template constexpr bool is_trivially_copyable_v + = is_trivially_copyable::value; + template constexpr bool is_standard_layout_v + = is_standard_layout::value; + template constexpr bool is_pod_v + = is_pod::value; + template constexpr bool is_literal_type_v + = is_literal_type::value; + template constexpr bool is_empty_v + = is_empty::value; + template constexpr bool is_polymorphic_v + = is_polymorphic::value; + template constexpr bool is_abstract_v + = is_abstract::value; + template constexpr bool is_final_v + = is_final::value; + template constexpr bool is_signed_v + = is_signed::value; + template constexpr bool is_unsigned_v + = is_unsigned::value; + template constexpr bool is_constructible_v + = is_constructible::value; + template constexpr bool is_default_constructible_v + = is_default_constructible::value; + template constexpr bool is_copy_constructible_v + = is_copy_constructible::value; + template constexpr bool is_move_constructible_v + = is_move_constructible::value; + template constexpr bool is_assignable_v + = is_assignable::value; + template constexpr bool is_copy_assignable_v + = is_copy_assignable::value; + template constexpr bool is_move_assignable_v + = is_move_assignable::value; + template constexpr bool is_destructible_v + = is_destructible::value; + template constexpr bool is_trivially_constructible_v + = is_trivially_constructible::value; + template constexpr bool is_trivially_default_constructible_v + = is_trivially_default_constructible::value; + template constexpr bool is_trivially_copy_constructible_v + = is_trivially_copy_constructible::value; + template constexpr bool is_trivially_move_constructible_v + = is_trivially_move_constructible::value; + template constexpr bool is_trivially_assignable_v + = is_trivially_assignable::value; + template constexpr bool is_trivially_copy_assignable_v + = is_trivially_copy_assignable::value; + template constexpr bool is_trivially_move_assignable_v + = is_trivially_move_assignable::value; + template constexpr bool is_trivially_destructible_v + = is_trivially_destructible::value; + template constexpr bool is_nothrow_constructible_v + = is_nothrow_constructible::value; + template constexpr bool is_nothrow_default_constructible_v + = is_nothrow_default_constructible::value; + template constexpr bool is_nothrow_copy_constructible_v + = is_nothrow_copy_constructible::value; + template constexpr bool is_nothrow_move_constructible_v + = is_nothrow_move_constructible::value; + template constexpr bool is_nothrow_assignable_v + = is_nothrow_assignable::value; + template constexpr bool is_nothrow_copy_assignable_v + = is_nothrow_copy_assignable::value; + template constexpr bool is_nothrow_move_assignable_v + = is_nothrow_move_assignable::value; + template constexpr bool is_nothrow_destructible_v + = is_nothrow_destructible::value; + template constexpr bool has_virtual_destructor_v + = has_virtual_destructor::value; + + // See C++14 20.10.5, type property queries + template constexpr size_t alignment_of_v + = alignment_of::value; + template constexpr size_t rank_v + = rank::value; + template constexpr size_t extent_v + = extent::value; + + // See C++14 20.10.6, type relations + template constexpr bool is_same_v + = is_same::value; + template constexpr bool is_base_of_v + = is_base_of::value; + template constexpr bool is_convertible_v + = is_convertible::value; + + // 3.3.2, Other type transformations + template class invocation_type; // not defined + template class invocation_type; + template class raw_invocation_type; // not defined + template class raw_invocation_type; + + template + using invocation_type_t = typename invocation_type::type; + template + using raw_invocation_type_t = typename raw_invocation_type::type; + +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include + +#if _LIBCPP_STD_VER > 11 + +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS + +#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES + +// C++14 20.10.4.1, primary type categories + +template _LIBCPP_CONSTEXPR bool is_void_v + = is_void<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_null_pointer_v + = is_null_pointer<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_integral_v + = is_integral<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_floating_point_v + = is_floating_point<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_array_v + = is_array<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_pointer_v + = is_pointer<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_lvalue_reference_v + = is_lvalue_reference<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_rvalue_reference_v + = is_rvalue_reference<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_member_object_pointer_v + = is_member_object_pointer<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_member_function_pointer_v + = is_member_function_pointer<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_enum_v + = is_enum<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_union_v + = is_union<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_class_v + = is_class<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_function_v + = is_function<_Tp>::value; + +// C++14 20.10.4.2, composite type categories + +template _LIBCPP_CONSTEXPR bool is_reference_v + = is_reference<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_arithmetic_v + = is_arithmetic<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_fundamental_v + = is_fundamental<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_object_v + = is_object<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_scalar_v + = is_scalar<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_compound_v + = is_compound<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_member_pointer_v + = is_member_pointer<_Tp>::value; + +// C++14 20.10.4.3, type properties + +template _LIBCPP_CONSTEXPR bool is_const_v + = is_const<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_volatile_v + = is_volatile<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_trivial_v + = is_trivial<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_trivially_copyable_v + = is_trivially_copyable<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_standard_layout_v + = is_standard_layout<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_pod_v + = is_pod<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_literal_type_v + = is_literal_type<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_empty_v + = is_empty<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_polymorphic_v + = is_polymorphic<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_abstract_v + = is_abstract<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_final_v + = is_final<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_signed_v + = is_signed<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_unsigned_v + = is_unsigned<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_constructible_v + = is_constructible<_Tp, _Ts...>::value; + +template _LIBCPP_CONSTEXPR bool is_default_constructible_v + = is_default_constructible<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_copy_constructible_v + = is_copy_constructible<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_move_constructible_v + = is_move_constructible<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_assignable_v + = is_assignable<_Tp, _Up>::value; + +template _LIBCPP_CONSTEXPR bool is_copy_assignable_v + = is_copy_assignable<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_move_assignable_v + = is_move_assignable<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_destructible_v + = is_destructible<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_trivially_constructible_v + = is_trivially_constructible<_Tp, _Ts...>::value; + +template _LIBCPP_CONSTEXPR bool is_trivially_default_constructible_v + = is_trivially_default_constructible<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_trivially_copy_constructible_v + = is_trivially_copy_constructible<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_trivially_move_constructible_v + = is_trivially_move_constructible<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_trivially_assignable_v + = is_trivially_assignable<_Tp, _Up>::value; + +template _LIBCPP_CONSTEXPR bool is_trivially_copy_assignable_v + = is_trivially_copy_assignable<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_trivially_move_assignable_v + = is_trivially_move_assignable<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_trivially_destructible_v + = is_trivially_destructible<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_nothrow_constructible_v + = is_nothrow_constructible<_Tp, _Ts...>::value; + +template _LIBCPP_CONSTEXPR bool is_nothrow_default_constructible_v + = is_nothrow_default_constructible<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_nothrow_copy_constructible_v + = is_nothrow_copy_constructible<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_nothrow_move_constructible_v + = is_nothrow_move_constructible<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_nothrow_assignable_v + = is_nothrow_assignable<_Tp, _Up>::value; + +template _LIBCPP_CONSTEXPR bool is_nothrow_copy_assignable_v + = is_nothrow_copy_assignable<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_nothrow_move_assignable_v + = is_nothrow_move_assignable<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool is_nothrow_destructible_v + = is_nothrow_destructible<_Tp>::value; + +template _LIBCPP_CONSTEXPR bool has_virtual_destructor_v + = has_virtual_destructor<_Tp>::value; + +// C++14 20.10.5, type properties queries + +template _LIBCPP_CONSTEXPR size_t alignment_of_v + = alignment_of<_Tp>::value; + +template _LIBCPP_CONSTEXPR size_t rank_v + = rank<_Tp>::value; + +template _LIBCPP_CONSTEXPR size_t extent_v + = extent<_Tp, _Id>::value; + +// C++14 20.10.6, type relations + +template _LIBCPP_CONSTEXPR bool is_same_v + = is_same<_Tp, _Up>::value; + +template _LIBCPP_CONSTEXPR bool is_base_of_v + = is_base_of<_Tp, _Up>::value; + +template _LIBCPP_CONSTEXPR bool is_convertible_v + = is_convertible<_Tp, _Up>::value; + +#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */ + +// 3.3.2, Other type transformations +/* +template +class _LIBCPP_TYPE_VIS_ONLY raw_invocation_type; + +template +class _LIBCPP_TYPE_VIS_ONLY raw_invocation_type<_Fn(_Args...)>; + +template +class _LIBCPP_TYPE_VIS_ONLY invokation_type; + +template +class _LIBCPP_TYPE_VIS_ONLY invokation_type<_Fn(_Args...)>; + +template +using invokation_type_t = typename invokation_type<_Tp>::type; + +template +using raw_invocation_type_t = typename raw_invocation_type<_Tp>::type; +*/ + +_LIBCPP_END_NAMESPACE_LFTS + +#endif /* _LIBCPP_STD_VER > 11 */ + +#endif /* _LIBCPP_EXPERIMENTAL_TYPE_TRAITS */ diff --git a/headers/libs/libc++/experimental/utility b/headers/libs/libc++/experimental/utility new file mode 100644 index 0000000000..b5fca6c775 --- /dev/null +++ b/headers/libs/libc++/experimental/utility @@ -0,0 +1,47 @@ +// -*- C++ -*- +//===-------------------------- utility ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_UTILITY +#define _LIBCPP_EXPERIMENTAL_UTILITY + +/* + experimental/utility synopsis + +// C++1y + +#include + +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { + + 3.1.2, erased-type placeholder + struct erased_type { }; + +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS + + struct _LIBCPP_TYPE_VIS_ONLY erased_type { }; + +_LIBCPP_END_NAMESPACE_LFTS + +#endif /* _LIBCPP_EXPERIMENTAL_UTILITY */ diff --git a/headers/libs/libc++/ext/__hash b/headers/libs/libc++/ext/__hash new file mode 100644 index 0000000000..5675d54055 --- /dev/null +++ b/headers/libs/libc++/ext/__hash @@ -0,0 +1,135 @@ +// -*- C++ -*- +//===------------------------- hash_set ------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXT_HASH +#define _LIBCPP_EXT_HASH + +#pragma GCC system_header + +#include +#include + +namespace __gnu_cxx { +using namespace std; + +template struct _LIBCPP_TYPE_VIS_ONLY hash { }; + +template <> struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(const char *__c) const _NOEXCEPT + { + return __do_string_hash(__c, __c + strlen(__c)); + } +}; + +template <> struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(char *__c) const _NOEXCEPT + { + return __do_string_hash(__c, __c + strlen(__c)); + } +}; + +template <> struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(char __c) const _NOEXCEPT + { + return __c; + } +}; + +template <> struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(signed char __c) const _NOEXCEPT + { + return __c; + } +}; + +template <> struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(unsigned char __c) const _NOEXCEPT + { + return __c; + } +}; + +template <> struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(short __c) const _NOEXCEPT + { + return __c; + } +}; + +template <> struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(unsigned short __c) const _NOEXCEPT + { + return __c; + } +}; + +template <> struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(int __c) const _NOEXCEPT + { + return __c; + } +}; + +template <> struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(unsigned int __c) const _NOEXCEPT + { + return __c; + } +}; + +template <> struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(long __c) const _NOEXCEPT + { + return __c; + } +}; + +template <> struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(unsigned long __c) const _NOEXCEPT + { + return __c; + } +}; +} + +#endif // _LIBCPP_EXT_HASH diff --git a/headers/libs/libc++/ext/hash_map b/headers/libs/libc++/ext/hash_map new file mode 100644 index 0000000000..0e4ab6910e --- /dev/null +++ b/headers/libs/libc++/ext/hash_map @@ -0,0 +1,994 @@ +// -*- C++ -*- +//===-------------------------- hash_map ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_HASH_MAP +#define _LIBCPP_HASH_MAP + +/* + + hash_map synopsis + +namespace __gnu_cxx +{ + +template , class Pred = equal_to, + class Alloc = allocator>> +class hash_map +{ +public: + // types + typedef Key key_type; + typedef T mapped_type; + typedef Hash hasher; + typedef Pred key_equal; + typedef Alloc allocator_type; + typedef pair value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename allocator_traits::pointer pointer; + typedef typename allocator_traits::const_pointer const_pointer; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::difference_type difference_type; + + typedef /unspecified/ iterator; + typedef /unspecified/ const_iterator; + + explicit hash_map(size_type n = 193, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + hash_map(InputIterator f, InputIterator l, + size_type n = 193, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + hash_map(const hash_map&); + ~hash_map(); + hash_map& operator=(const hash_map&); + + allocator_type get_allocator() const; + + bool empty() const; + size_type size() const; + size_type max_size() const; + + iterator begin(); + iterator end(); + const_iterator begin() const; + const_iterator end() const; + + pair insert(const value_type& obj); + template + void insert(InputIterator first, InputIterator last); + + void erase(const_iterator position); + size_type erase(const key_type& k); + void erase(const_iterator first, const_iterator last); + void clear(); + + void swap(hash_map&); + + hasher hash_funct() const; + key_equal key_eq() const; + + iterator find(const key_type& k); + const_iterator find(const key_type& k) const; + size_type count(const key_type& k) const; + pair equal_range(const key_type& k); + pair equal_range(const key_type& k) const; + + mapped_type& operator[](const key_type& k); + + size_type bucket_count() const; + size_type max_bucket_count() const; + + size_type elems_in_bucket(size_type n) const; + + void resize(size_type n); +}; + +template + void swap(hash_map& x, + hash_map& y); + +template + bool + operator==(const hash_map& x, + const hash_map& y); + +template + bool + operator!=(const hash_map& x, + const hash_map& y); + +template , class Pred = equal_to, + class Alloc = allocator>> +class hash_multimap +{ +public: + // types + typedef Key key_type; + typedef T mapped_type; + typedef Hash hasher; + typedef Pred key_equal; + typedef Alloc allocator_type; + typedef pair value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename allocator_traits::pointer pointer; + typedef typename allocator_traits::const_pointer const_pointer; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::difference_type difference_type; + + typedef /unspecified/ iterator; + typedef /unspecified/ const_iterator; + + explicit hash_multimap(size_type n = 193, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + hash_multimap(InputIterator f, InputIterator l, + size_type n = 193, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + explicit hash_multimap(const allocator_type&); + hash_multimap(const hash_multimap&); + ~hash_multimap(); + hash_multimap& operator=(const hash_multimap&); + + allocator_type get_allocator() const; + + bool empty() const; + size_type size() const; + size_type max_size() const; + + iterator begin(); + iterator end(); + const_iterator begin() const; + const_iterator end() const; + + iterator insert(const value_type& obj); + template + void insert(InputIterator first, InputIterator last); + + void erase(const_iterator position); + size_type erase(const key_type& k); + void erase(const_iterator first, const_iterator last); + void clear(); + + void swap(hash_multimap&); + + hasher hash_funct() const; + key_equal key_eq() const; + + iterator find(const key_type& k); + const_iterator find(const key_type& k) const; + size_type count(const key_type& k) const; + pair equal_range(const key_type& k); + pair equal_range(const key_type& k) const; + + size_type bucket_count() const; + size_type max_bucket_count() const; + + size_type elems_in_bucket(size_type n) const; + + void resize(size_type n); +}; + +template + void swap(hash_multimap& x, + hash_multimap& y); + +template + bool + operator==(const hash_multimap& x, + const hash_multimap& y); + +template + bool + operator!=(const hash_multimap& x, + const hash_multimap& y); + +} // __gnu_cxx + +*/ + +#include <__config> +#include <__hash_table> +#include +#include +#include +#include + +#if __DEPRECATED +#if defined(_MSC_VER) && ! defined(__clang__) + _LIBCPP_WARNING("Use of the header is deprecated. Migrate to ") +#else +# warning Use of the header is deprecated. Migrate to +#endif +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +namespace __gnu_cxx { + +using namespace std; + +template ::value && !__libcpp_is_final<_Hash>::value + > +class __hash_map_hasher + : private _Hash +{ +public: + _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : _Hash() {} + _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : _Hash(__h) {} + _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return *this;} + _LIBCPP_INLINE_VISIBILITY + size_t operator()(const _Tp& __x) const + {return static_cast(*this)(__x.first);} + _LIBCPP_INLINE_VISIBILITY + size_t operator()(const typename _Tp::first_type& __x) const + {return static_cast(*this)(__x);} +}; + +template +class __hash_map_hasher<_Tp, _Hash, false> +{ + _Hash __hash_; +public: + _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : __hash_() {} + _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : __hash_(__h) {} + _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return __hash_;} + _LIBCPP_INLINE_VISIBILITY + size_t operator()(const _Tp& __x) const + {return __hash_(__x.first);} + _LIBCPP_INLINE_VISIBILITY + size_t operator()(const typename _Tp::first_type& __x) const + {return __hash_(__x);} +}; + +template ::value && !__libcpp_is_final<_Pred>::value + > +class __hash_map_equal + : private _Pred +{ +public: + _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : _Pred() {} + _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : _Pred(__p) {} + _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return *this;} + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return static_cast(*this)(__x.first, __y.first);} + _LIBCPP_INLINE_VISIBILITY + bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const + {return static_cast(*this)(__x, __y.first);} + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const + {return static_cast(*this)(__x.first, __y);} + _LIBCPP_INLINE_VISIBILITY + bool operator()(const typename _Tp::first_type& __x, + const typename _Tp::first_type& __y) const + {return static_cast(*this)(__x, __y);} +}; + +template +class __hash_map_equal<_Tp, _Pred, false> +{ + _Pred __pred_; +public: + _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : __pred_() {} + _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : __pred_(__p) {} + _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return __pred_;} + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __pred_(__x.first, __y.first);} + _LIBCPP_INLINE_VISIBILITY + bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const + {return __pred_(__x, __y.first);} + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const + {return __pred_(__x.first, __y);} + _LIBCPP_INLINE_VISIBILITY + bool operator()(const typename _Tp::first_type& __x, + const typename _Tp::first_type& __y) const + {return __pred_(__x, __y);} +}; + +template +class __hash_map_node_destructor +{ + typedef _Alloc allocator_type; + typedef allocator_traits __alloc_traits; + typedef typename __alloc_traits::value_type::value_type value_type; +public: + typedef typename __alloc_traits::pointer pointer; +private: + typedef typename value_type::first_type first_type; + typedef typename value_type::second_type second_type; + + allocator_type& __na_; + + __hash_map_node_destructor& operator=(const __hash_map_node_destructor&); + +public: + bool __first_constructed; + bool __second_constructed; + + _LIBCPP_INLINE_VISIBILITY + explicit __hash_map_node_destructor(allocator_type& __na) + : __na_(__na), + __first_constructed(false), + __second_constructed(false) + {} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + __hash_map_node_destructor(__hash_node_destructor&& __x) + : __na_(__x.__na_), + __first_constructed(__x.__value_constructed), + __second_constructed(__x.__value_constructed) + { + __x.__value_constructed = false; + } +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + __hash_map_node_destructor(const __hash_node_destructor& __x) + : __na_(__x.__na_), + __first_constructed(__x.__value_constructed), + __second_constructed(__x.__value_constructed) + { + const_cast(__x.__value_constructed) = false; + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + _LIBCPP_INLINE_VISIBILITY + void operator()(pointer __p) + { + if (__second_constructed) + __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.second)); + if (__first_constructed) + __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.first)); + if (__p) + __alloc_traits::deallocate(__na_, __p, 1); + } +}; + +template +class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator +{ + _HashIterator __i_; + + typedef pointer_traits __pointer_traits; + typedef const typename _HashIterator::value_type::first_type key_type; + typedef typename _HashIterator::value_type::second_type mapped_type; +public: + typedef forward_iterator_tag iterator_category; + typedef pair value_type; + typedef typename _HashIterator::difference_type difference_type; + typedef value_type& reference; + typedef typename __pointer_traits::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + pointer; + + _LIBCPP_INLINE_VISIBILITY __hash_map_iterator() {} + + _LIBCPP_INLINE_VISIBILITY __hash_map_iterator(_HashIterator __i) : __i_(__i) {} + + _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *operator->();} + _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return (pointer)__i_.operator->();} + + _LIBCPP_INLINE_VISIBILITY __hash_map_iterator& operator++() {++__i_; return *this;} + _LIBCPP_INLINE_VISIBILITY + __hash_map_iterator operator++(int) + { + __hash_map_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y) + {return __x.__i_ == __y.__i_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y) + {return __x.__i_ != __y.__i_;} + + template friend class _LIBCPP_TYPE_VIS_ONLY hash_map; + template friend class _LIBCPP_TYPE_VIS_ONLY hash_multimap; + template friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator; + template friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator; + template friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator; +}; + +template +class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator +{ + _HashIterator __i_; + + typedef pointer_traits __pointer_traits; + typedef const typename _HashIterator::value_type::first_type key_type; + typedef typename _HashIterator::value_type::second_type mapped_type; +public: + typedef forward_iterator_tag iterator_category; + typedef pair value_type; + typedef typename _HashIterator::difference_type difference_type; + typedef const value_type& reference; + typedef typename __pointer_traits::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + pointer; + + _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator() {} + + _LIBCPP_INLINE_VISIBILITY + __hash_map_const_iterator(_HashIterator __i) : __i_(__i) {} + _LIBCPP_INLINE_VISIBILITY + __hash_map_const_iterator( + __hash_map_iterator __i) + : __i_(__i.__i_) {} + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const {return *operator->();} + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const {return (pointer)__i_.operator->();} + + _LIBCPP_INLINE_VISIBILITY + __hash_map_const_iterator& operator++() {++__i_; return *this;} + _LIBCPP_INLINE_VISIBILITY + __hash_map_const_iterator operator++(int) + { + __hash_map_const_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) + {return __x.__i_ == __y.__i_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) + {return __x.__i_ != __y.__i_;} + + template friend class _LIBCPP_TYPE_VIS_ONLY hash_map; + template friend class _LIBCPP_TYPE_VIS_ONLY hash_multimap; + template friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator; + template friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator; +}; + +template , class _Pred = equal_to<_Key>, + class _Alloc = allocator > > +class _LIBCPP_TYPE_VIS_ONLY hash_map +{ +public: + // types + typedef _Key key_type; + typedef _Tp mapped_type; + typedef _Tp data_type; + typedef _Hash hasher; + typedef _Pred key_equal; + typedef _Alloc allocator_type; + typedef pair value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + +private: + typedef pair __value_type; + typedef __hash_map_hasher<__value_type, hasher> __hasher; + typedef __hash_map_equal<__value_type, key_equal> __key_equal; + typedef typename __rebind_alloc_helper, __value_type>::type __allocator_type; + + typedef __hash_table<__value_type, __hasher, + __key_equal, __allocator_type> __table; + + __table __table_; + + typedef typename __table::__node_pointer __node_pointer; + typedef typename __table::__node_const_pointer __node_const_pointer; + typedef typename __table::__node_traits __node_traits; + typedef typename __table::__node_allocator __node_allocator; + typedef typename __table::__node __node; + typedef __hash_map_node_destructor<__node_allocator> _Dp; + typedef unique_ptr<__node, _Dp> __node_holder; + typedef allocator_traits __alloc_traits; +public: + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; + typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::difference_type difference_type; + + typedef __hash_map_iterator iterator; + typedef __hash_map_const_iterator const_iterator; + + _LIBCPP_INLINE_VISIBILITY hash_map() {__table_.rehash(193);} + explicit hash_map(size_type __n, const hasher& __hf = hasher(), + const key_equal& __eql = key_equal()); + hash_map(size_type __n, const hasher& __hf, + const key_equal& __eql, + const allocator_type& __a); + template + hash_map(_InputIterator __first, _InputIterator __last); + template + hash_map(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf = hasher(), + const key_equal& __eql = key_equal()); + template + hash_map(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf, + const key_equal& __eql, + const allocator_type& __a); + hash_map(const hash_map& __u); + + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const + {return allocator_type(__table_.__node_alloc());} + + _LIBCPP_INLINE_VISIBILITY + bool empty() const {return __table_.size() == 0;} + _LIBCPP_INLINE_VISIBILITY + size_type size() const {return __table_.size();} + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const {return __table_.max_size();} + + _LIBCPP_INLINE_VISIBILITY + iterator begin() {return __table_.begin();} + _LIBCPP_INLINE_VISIBILITY + iterator end() {return __table_.end();} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const {return __table_.begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const {return __table_.end();} + + _LIBCPP_INLINE_VISIBILITY + pair insert(const value_type& __x) + {return __table_.__insert_unique(__x);} + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;} + template + void insert(_InputIterator __first, _InputIterator __last); + + _LIBCPP_INLINE_VISIBILITY + void erase(const_iterator __p) {__table_.erase(__p.__i_);} + _LIBCPP_INLINE_VISIBILITY + size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);} + _LIBCPP_INLINE_VISIBILITY + void erase(const_iterator __first, const_iterator __last) + {__table_.erase(__first.__i_, __last.__i_);} + _LIBCPP_INLINE_VISIBILITY + void clear() {__table_.clear();} + + _LIBCPP_INLINE_VISIBILITY + void swap(hash_map& __u) {__table_.swap(__u.__table_);} + + _LIBCPP_INLINE_VISIBILITY + hasher hash_funct() const + {return __table_.hash_function().hash_function();} + _LIBCPP_INLINE_VISIBILITY + key_equal key_eq() const + {return __table_.key_eq().key_eq();} + + _LIBCPP_INLINE_VISIBILITY + iterator find(const key_type& __k) {return __table_.find(__k);} + _LIBCPP_INLINE_VISIBILITY + const_iterator find(const key_type& __k) const {return __table_.find(__k);} + _LIBCPP_INLINE_VISIBILITY + size_type count(const key_type& __k) const {return __table_.__count_unique(__k);} + _LIBCPP_INLINE_VISIBILITY + pair equal_range(const key_type& __k) + {return __table_.__equal_range_unique(__k);} + _LIBCPP_INLINE_VISIBILITY + pair equal_range(const key_type& __k) const + {return __table_.__equal_range_unique(__k);} + + mapped_type& operator[](const key_type& __k); + + _LIBCPP_INLINE_VISIBILITY + size_type bucket_count() const {return __table_.bucket_count();} + _LIBCPP_INLINE_VISIBILITY + size_type max_bucket_count() const {return __table_.max_bucket_count();} + + _LIBCPP_INLINE_VISIBILITY + size_type elems_in_bucket(size_type __n) const + {return __table_.bucket_size(__n);} + + _LIBCPP_INLINE_VISIBILITY + void resize(size_type __n) {__table_.rehash(__n);} + +private: + __node_holder __construct_node(const key_type& __k); +}; + +template +hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( + size_type __n, const hasher& __hf, const key_equal& __eql) + : __table_(__hf, __eql) +{ + __table_.rehash(__n); +} + +template +hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( + size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a) + : __table_(__hf, __eql, __a) +{ + __table_.rehash(__n); +} + +template +template +hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( + _InputIterator __first, _InputIterator __last) +{ + __table_.rehash(193); + insert(__first, __last); +} + +template +template +hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( + _InputIterator __first, _InputIterator __last, size_type __n, + const hasher& __hf, const key_equal& __eql) + : __table_(__hf, __eql) +{ + __table_.rehash(__n); + insert(__first, __last); +} + +template +template +hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( + _InputIterator __first, _InputIterator __last, size_type __n, + const hasher& __hf, const key_equal& __eql, const allocator_type& __a) + : __table_(__hf, __eql, __a) +{ + __table_.rehash(__n); + insert(__first, __last); +} + +template +hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( + const hash_map& __u) + : __table_(__u.__table_) +{ + __table_.rehash(__u.bucket_count()); + insert(__u.begin(), __u.end()); +} + +template +typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder +hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k) +{ + __node_allocator& __na = __table_.__node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), __k); + __h.get_deleter().__first_constructed = true; + __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second)); + __h.get_deleter().__second_constructed = true; + return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 +} + +template +template +inline _LIBCPP_INLINE_VISIBILITY +void +hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, + _InputIterator __last) +{ + for (; __first != __last; ++__first) + __table_.__insert_unique(*__first); +} + +template +_Tp& +hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) +{ + iterator __i = find(__k); + if (__i != end()) + return __i->second; + __node_holder __h = __construct_node(__k); + pair __r = __table_.__node_insert_unique(__h.get()); + __h.release(); + return __r.first->second; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, + hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) +{ + __x.swap(__y); +} + +template +bool +operator==(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, + const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) +{ + if (__x.size() != __y.size()) + return false; + typedef typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator + const_iterator; + for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end(); + __i != __ex; ++__i) + { + const_iterator __j = __y.find(__i->first); + if (__j == __ey || !(*__i == *__j)) + return false; + } + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, + const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) +{ + return !(__x == __y); +} + +template , class _Pred = equal_to<_Key>, + class _Alloc = allocator > > +class _LIBCPP_TYPE_VIS_ONLY hash_multimap +{ +public: + // types + typedef _Key key_type; + typedef _Tp mapped_type; + typedef _Tp data_type; + typedef _Hash hasher; + typedef _Pred key_equal; + typedef _Alloc allocator_type; + typedef pair value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + +private: + typedef pair __value_type; + typedef __hash_map_hasher<__value_type, hasher> __hasher; + typedef __hash_map_equal<__value_type, key_equal> __key_equal; + typedef typename __rebind_alloc_helper, __value_type>::type __allocator_type; + + typedef __hash_table<__value_type, __hasher, + __key_equal, __allocator_type> __table; + + __table __table_; + + typedef typename __table::__node_traits __node_traits; + typedef typename __table::__node_allocator __node_allocator; + typedef typename __table::__node __node; + typedef __hash_map_node_destructor<__node_allocator> _Dp; + typedef unique_ptr<__node, _Dp> __node_holder; + typedef allocator_traits __alloc_traits; +public: + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; + typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::difference_type difference_type; + + typedef __hash_map_iterator iterator; + typedef __hash_map_const_iterator const_iterator; + + _LIBCPP_INLINE_VISIBILITY + hash_multimap() {__table_.rehash(193);} + explicit hash_multimap(size_type __n, const hasher& __hf = hasher(), + const key_equal& __eql = key_equal()); + hash_multimap(size_type __n, const hasher& __hf, + const key_equal& __eql, + const allocator_type& __a); + template + hash_multimap(_InputIterator __first, _InputIterator __last); + template + hash_multimap(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf = hasher(), + const key_equal& __eql = key_equal()); + template + hash_multimap(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf, + const key_equal& __eql, + const allocator_type& __a); + hash_multimap(const hash_multimap& __u); + + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const + {return allocator_type(__table_.__node_alloc());} + + _LIBCPP_INLINE_VISIBILITY + bool empty() const {return __table_.size() == 0;} + _LIBCPP_INLINE_VISIBILITY + size_type size() const {return __table_.size();} + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const {return __table_.max_size();} + + _LIBCPP_INLINE_VISIBILITY + iterator begin() {return __table_.begin();} + _LIBCPP_INLINE_VISIBILITY + iterator end() {return __table_.end();} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const {return __table_.begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const {return __table_.end();} + + _LIBCPP_INLINE_VISIBILITY + iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);} + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator, const value_type& __x) {return insert(__x);} + template + void insert(_InputIterator __first, _InputIterator __last); + + _LIBCPP_INLINE_VISIBILITY + void erase(const_iterator __p) {__table_.erase(__p.__i_);} + _LIBCPP_INLINE_VISIBILITY + size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);} + _LIBCPP_INLINE_VISIBILITY + void erase(const_iterator __first, const_iterator __last) + {__table_.erase(__first.__i_, __last.__i_);} + _LIBCPP_INLINE_VISIBILITY + void clear() {__table_.clear();} + + _LIBCPP_INLINE_VISIBILITY + void swap(hash_multimap& __u) {__table_.swap(__u.__table_);} + + _LIBCPP_INLINE_VISIBILITY + hasher hash_funct() const + {return __table_.hash_function().hash_function();} + _LIBCPP_INLINE_VISIBILITY + key_equal key_eq() const + {return __table_.key_eq().key_eq();} + + _LIBCPP_INLINE_VISIBILITY + iterator find(const key_type& __k) {return __table_.find(__k);} + _LIBCPP_INLINE_VISIBILITY + const_iterator find(const key_type& __k) const {return __table_.find(__k);} + _LIBCPP_INLINE_VISIBILITY + size_type count(const key_type& __k) const {return __table_.__count_multi(__k);} + _LIBCPP_INLINE_VISIBILITY + pair equal_range(const key_type& __k) + {return __table_.__equal_range_multi(__k);} + _LIBCPP_INLINE_VISIBILITY + pair equal_range(const key_type& __k) const + {return __table_.__equal_range_multi(__k);} + + _LIBCPP_INLINE_VISIBILITY + size_type bucket_count() const {return __table_.bucket_count();} + _LIBCPP_INLINE_VISIBILITY + size_type max_bucket_count() const {return __table_.max_bucket_count();} + + _LIBCPP_INLINE_VISIBILITY + size_type elems_in_bucket(size_type __n) const + {return __table_.bucket_size(__n);} + + _LIBCPP_INLINE_VISIBILITY + void resize(size_type __n) {__table_.rehash(__n);} +}; + +template +hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( + size_type __n, const hasher& __hf, const key_equal& __eql) + : __table_(__hf, __eql) +{ + __table_.rehash(__n); +} + +template +hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( + size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a) + : __table_(__hf, __eql, __a) +{ + __table_.rehash(__n); +} + +template +template +hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( + _InputIterator __first, _InputIterator __last) +{ + __table_.rehash(193); + insert(__first, __last); +} + +template +template +hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( + _InputIterator __first, _InputIterator __last, size_type __n, + const hasher& __hf, const key_equal& __eql) + : __table_(__hf, __eql) +{ + __table_.rehash(__n); + insert(__first, __last); +} + +template +template +hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( + _InputIterator __first, _InputIterator __last, size_type __n, + const hasher& __hf, const key_equal& __eql, const allocator_type& __a) + : __table_(__hf, __eql, __a) +{ + __table_.rehash(__n); + insert(__first, __last); +} + +template +hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( + const hash_multimap& __u) + : __table_(__u.__table_) +{ + __table_.rehash(__u.bucket_count()); + insert(__u.begin(), __u.end()); +} + +template +template +inline _LIBCPP_INLINE_VISIBILITY +void +hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, + _InputIterator __last) +{ + for (; __first != __last; ++__first) + __table_.__insert_multi(*__first); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, + hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) +{ + __x.swap(__y); +} + +template +bool +operator==(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, + const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) +{ + if (__x.size() != __y.size()) + return false; + typedef typename hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator + const_iterator; + typedef pair _EqRng; + for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;) + { + _EqRng __xeq = __x.equal_range(__i->first); + _EqRng __yeq = __y.equal_range(__i->first); + if (_VSTD::distance(__xeq.first, __xeq.second) != + _VSTD::distance(__yeq.first, __yeq.second) || + !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first)) + return false; + __i = __xeq.second; + } + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, + const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) +{ + return !(__x == __y); +} + +} // __gnu_cxx + +#endif // _LIBCPP_HASH_MAP diff --git a/headers/libs/libc++/ext/hash_set b/headers/libs/libc++/ext/hash_set new file mode 100644 index 0000000000..c4bb89843d --- /dev/null +++ b/headers/libs/libc++/ext/hash_set @@ -0,0 +1,661 @@ +// -*- C++ -*- +//===------------------------- hash_set ------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_HASH_SET +#define _LIBCPP_HASH_SET + +/* + + hash_set synopsis + +namespace __gnu_cxx +{ + +template , class Pred = equal_to, + class Alloc = allocator> +class hash_set +{ +public: + // types + typedef Value key_type; + typedef key_type value_type; + typedef Hash hasher; + typedef Pred key_equal; + typedef Alloc allocator_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename allocator_traits::pointer pointer; + typedef typename allocator_traits::const_pointer const_pointer; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::difference_type difference_type; + + typedef /unspecified/ iterator; + typedef /unspecified/ const_iterator; + + explicit hash_set(size_type n = 193, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + hash_set(InputIterator f, InputIterator l, + size_type n = 193, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + hash_set(const hash_set&); + ~hash_set(); + hash_set& operator=(const hash_set&); + + allocator_type get_allocator() const; + + bool empty() const; + size_type size() const; + size_type max_size() const; + + iterator begin(); + iterator end(); + const_iterator begin() const; + const_iterator end() const; + + pair insert(const value_type& obj); + template + void insert(InputIterator first, InputIterator last); + + void erase(const_iterator position); + size_type erase(const key_type& k); + void erase(const_iterator first, const_iterator last); + void clear(); + + void swap(hash_set&); + + hasher hash_funct() const; + key_equal key_eq() const; + + iterator find(const key_type& k); + const_iterator find(const key_type& k) const; + size_type count(const key_type& k) const; + pair equal_range(const key_type& k); + pair equal_range(const key_type& k) const; + + size_type bucket_count() const; + size_type max_bucket_count() const; + + size_type elems_in_bucket(size_type n) const; + + void resize(size_type n); +}; + +template + void swap(hash_set& x, + hash_set& y); + +template + bool + operator==(const hash_set& x, + const hash_set& y); + +template + bool + operator!=(const hash_set& x, + const hash_set& y); + +template , class Pred = equal_to, + class Alloc = allocator> +class hash_multiset +{ +public: + // types + typedef Value key_type; + typedef key_type value_type; + typedef Hash hasher; + typedef Pred key_equal; + typedef Alloc allocator_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename allocator_traits::pointer pointer; + typedef typename allocator_traits::const_pointer const_pointer; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::difference_type difference_type; + + typedef /unspecified/ iterator; + typedef /unspecified/ const_iterator; + + explicit hash_multiset(size_type n = 193, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + hash_multiset(InputIterator f, InputIterator l, + size_type n = 193, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + hash_multiset(const hash_multiset&); + ~hash_multiset(); + hash_multiset& operator=(const hash_multiset&); + + allocator_type get_allocator() const; + + bool empty() const; + size_type size() const; + size_type max_size() const; + + iterator begin(); + iterator end(); + const_iterator begin() const; + const_iterator end() const; + + iterator insert(const value_type& obj); + template + void insert(InputIterator first, InputIterator last); + + void erase(const_iterator position); + size_type erase(const key_type& k); + void erase(const_iterator first, const_iterator last); + void clear(); + + void swap(hash_multiset&); + + hasher hash_funct() const; + key_equal key_eq() const; + + iterator find(const key_type& k); + const_iterator find(const key_type& k) const; + size_type count(const key_type& k) const; + pair equal_range(const key_type& k); + pair equal_range(const key_type& k) const; + + size_type bucket_count() const; + size_type max_bucket_count() const; + + size_type elems_in_bucket(size_type n) const; + + void resize(size_type n); +}; + +template + void swap(hash_multiset& x, + hash_multiset& y); + +template + bool + operator==(const hash_multiset& x, + const hash_multiset& y); + +template + bool + operator!=(const hash_multiset& x, + const hash_multiset& y); +} // __gnu_cxx + +*/ + +#include <__config> +#include <__hash_table> +#include +#include + +#if __DEPRECATED +#if defined(_MSC_VER) && ! defined(__clang__) + _LIBCPP_WARNING("Use of the header is deprecated. Migrate to ") +#else +# warning Use of the header is deprecated. Migrate to +#endif +#endif + +namespace __gnu_cxx { + +using namespace std; + +template , class _Pred = equal_to<_Value>, + class _Alloc = allocator<_Value> > +class _LIBCPP_TYPE_VIS_ONLY hash_set +{ +public: + // types + typedef _Value key_type; + typedef key_type value_type; + typedef _Hash hasher; + typedef _Pred key_equal; + typedef _Alloc allocator_type; + typedef value_type& reference; + typedef const value_type& const_reference; + +private: + typedef __hash_table __table; + + __table __table_; + +public: + typedef typename __table::pointer pointer; + typedef typename __table::const_pointer const_pointer; + typedef typename __table::size_type size_type; + typedef typename __table::difference_type difference_type; + + typedef typename __table::const_iterator iterator; + typedef typename __table::const_iterator const_iterator; + + _LIBCPP_INLINE_VISIBILITY + hash_set() {__table_.rehash(193);} + explicit hash_set(size_type __n, const hasher& __hf = hasher(), + const key_equal& __eql = key_equal()); + hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a); + template + hash_set(_InputIterator __first, _InputIterator __last); + template + hash_set(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf = hasher(), + const key_equal& __eql = key_equal()); + template + hash_set(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a); + hash_set(const hash_set& __u); + + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const + {return allocator_type(__table_.__node_alloc());} + + _LIBCPP_INLINE_VISIBILITY + bool empty() const {return __table_.size() == 0;} + _LIBCPP_INLINE_VISIBILITY + size_type size() const {return __table_.size();} + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const {return __table_.max_size();} + + _LIBCPP_INLINE_VISIBILITY + iterator begin() {return __table_.begin();} + _LIBCPP_INLINE_VISIBILITY + iterator end() {return __table_.end();} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const {return __table_.begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const {return __table_.end();} + + _LIBCPP_INLINE_VISIBILITY + pair insert(const value_type& __x) + {return __table_.__insert_unique(__x);} + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;} + template + void insert(_InputIterator __first, _InputIterator __last); + + _LIBCPP_INLINE_VISIBILITY + void erase(const_iterator __p) {__table_.erase(__p);} + _LIBCPP_INLINE_VISIBILITY + size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);} + _LIBCPP_INLINE_VISIBILITY + void erase(const_iterator __first, const_iterator __last) + {__table_.erase(__first, __last);} + _LIBCPP_INLINE_VISIBILITY + void clear() {__table_.clear();} + + _LIBCPP_INLINE_VISIBILITY + void swap(hash_set& __u) {__table_.swap(__u.__table_);} + + _LIBCPP_INLINE_VISIBILITY + hasher hash_funct() const {return __table_.hash_function();} + _LIBCPP_INLINE_VISIBILITY + key_equal key_eq() const {return __table_.key_eq();} + + _LIBCPP_INLINE_VISIBILITY + iterator find(const key_type& __k) {return __table_.find(__k);} + _LIBCPP_INLINE_VISIBILITY + const_iterator find(const key_type& __k) const {return __table_.find(__k);} + _LIBCPP_INLINE_VISIBILITY + size_type count(const key_type& __k) const {return __table_.__count_unique(__k);} + _LIBCPP_INLINE_VISIBILITY + pair equal_range(const key_type& __k) + {return __table_.__equal_range_unique(__k);} + _LIBCPP_INLINE_VISIBILITY + pair equal_range(const key_type& __k) const + {return __table_.__equal_range_unique(__k);} + + _LIBCPP_INLINE_VISIBILITY + size_type bucket_count() const {return __table_.bucket_count();} + _LIBCPP_INLINE_VISIBILITY + size_type max_bucket_count() const {return __table_.max_bucket_count();} + + _LIBCPP_INLINE_VISIBILITY + size_type elems_in_bucket(size_type __n) const {return __table_.bucket_size(__n);} + + _LIBCPP_INLINE_VISIBILITY + void resize(size_type __n) {__table_.rehash(__n);} +}; + +template +hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(size_type __n, + const hasher& __hf, const key_equal& __eql) + : __table_(__hf, __eql) +{ + __table_.rehash(__n); +} + +template +hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(size_type __n, + const hasher& __hf, const key_equal& __eql, const allocator_type& __a) + : __table_(__hf, __eql, __a) +{ + __table_.rehash(__n); +} + +template +template +hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set( + _InputIterator __first, _InputIterator __last) +{ + __table_.rehash(193); + insert(__first, __last); +} + +template +template +hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set( + _InputIterator __first, _InputIterator __last, size_type __n, + const hasher& __hf, const key_equal& __eql) + : __table_(__hf, __eql) +{ + __table_.rehash(__n); + insert(__first, __last); +} + +template +template +hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set( + _InputIterator __first, _InputIterator __last, size_type __n, + const hasher& __hf, const key_equal& __eql, const allocator_type& __a) + : __table_(__hf, __eql, __a) +{ + __table_.rehash(__n); + insert(__first, __last); +} + +template +hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set( + const hash_set& __u) + : __table_(__u.__table_) +{ + __table_.rehash(__u.bucket_count()); + insert(__u.begin(), __u.end()); +} + +template +template +inline _LIBCPP_INLINE_VISIBILITY +void +hash_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, + _InputIterator __last) +{ + for (; __first != __last; ++__first) + __table_.__insert_unique(*__first); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(hash_set<_Value, _Hash, _Pred, _Alloc>& __x, + hash_set<_Value, _Hash, _Pred, _Alloc>& __y) +{ + __x.swap(__y); +} + +template +bool +operator==(const hash_set<_Value, _Hash, _Pred, _Alloc>& __x, + const hash_set<_Value, _Hash, _Pred, _Alloc>& __y) +{ + if (__x.size() != __y.size()) + return false; + typedef typename hash_set<_Value, _Hash, _Pred, _Alloc>::const_iterator + const_iterator; + for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end(); + __i != __ex; ++__i) + { + const_iterator __j = __y.find(*__i); + if (__j == __ey || !(*__i == *__j)) + return false; + } + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const hash_set<_Value, _Hash, _Pred, _Alloc>& __x, + const hash_set<_Value, _Hash, _Pred, _Alloc>& __y) +{ + return !(__x == __y); +} + +template , class _Pred = equal_to<_Value>, + class _Alloc = allocator<_Value> > +class _LIBCPP_TYPE_VIS_ONLY hash_multiset +{ +public: + // types + typedef _Value key_type; + typedef key_type value_type; + typedef _Hash hasher; + typedef _Pred key_equal; + typedef _Alloc allocator_type; + typedef value_type& reference; + typedef const value_type& const_reference; + +private: + typedef __hash_table __table; + + __table __table_; + +public: + typedef typename __table::pointer pointer; + typedef typename __table::const_pointer const_pointer; + typedef typename __table::size_type size_type; + typedef typename __table::difference_type difference_type; + + typedef typename __table::const_iterator iterator; + typedef typename __table::const_iterator const_iterator; + + _LIBCPP_INLINE_VISIBILITY + hash_multiset() {__table_.rehash(193);} + explicit hash_multiset(size_type __n, const hasher& __hf = hasher(), + const key_equal& __eql = key_equal()); + hash_multiset(size_type __n, const hasher& __hf, + const key_equal& __eql, const allocator_type& __a); + template + hash_multiset(_InputIterator __first, _InputIterator __last); + template + hash_multiset(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf = hasher(), + const key_equal& __eql = key_equal()); + template + hash_multiset(_InputIterator __first, _InputIterator __last, + size_type __n , const hasher& __hf, + const key_equal& __eql, const allocator_type& __a); + hash_multiset(const hash_multiset& __u); + + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const + {return allocator_type(__table_.__node_alloc());} + + _LIBCPP_INLINE_VISIBILITY + bool empty() const {return __table_.size() == 0;} + _LIBCPP_INLINE_VISIBILITY + size_type size() const {return __table_.size();} + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const {return __table_.max_size();} + + _LIBCPP_INLINE_VISIBILITY + iterator begin() {return __table_.begin();} + _LIBCPP_INLINE_VISIBILITY + iterator end() {return __table_.end();} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const {return __table_.begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const {return __table_.end();} + + _LIBCPP_INLINE_VISIBILITY + iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);} + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator, const value_type& __x) {return insert(__x);} + template + void insert(_InputIterator __first, _InputIterator __last); + + _LIBCPP_INLINE_VISIBILITY + void erase(const_iterator __p) {__table_.erase(__p);} + _LIBCPP_INLINE_VISIBILITY + size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);} + _LIBCPP_INLINE_VISIBILITY + void erase(const_iterator __first, const_iterator __last) + {__table_.erase(__first, __last);} + _LIBCPP_INLINE_VISIBILITY + void clear() {__table_.clear();} + + _LIBCPP_INLINE_VISIBILITY + void swap(hash_multiset& __u) {__table_.swap(__u.__table_);} + + _LIBCPP_INLINE_VISIBILITY + hasher hash_funct() const {return __table_.hash_function();} + _LIBCPP_INLINE_VISIBILITY + key_equal key_eq() const {return __table_.key_eq();} + + _LIBCPP_INLINE_VISIBILITY + iterator find(const key_type& __k) {return __table_.find(__k);} + _LIBCPP_INLINE_VISIBILITY + const_iterator find(const key_type& __k) const {return __table_.find(__k);} + _LIBCPP_INLINE_VISIBILITY + size_type count(const key_type& __k) const {return __table_.__count_multi(__k);} + _LIBCPP_INLINE_VISIBILITY + pair equal_range(const key_type& __k) + {return __table_.__equal_range_multi(__k);} + _LIBCPP_INLINE_VISIBILITY + pair equal_range(const key_type& __k) const + {return __table_.__equal_range_multi(__k);} + + _LIBCPP_INLINE_VISIBILITY + size_type bucket_count() const {return __table_.bucket_count();} + _LIBCPP_INLINE_VISIBILITY + size_type max_bucket_count() const {return __table_.max_bucket_count();} + + _LIBCPP_INLINE_VISIBILITY + size_type elems_in_bucket(size_type __n) const {return __table_.bucket_size(__n);} + + _LIBCPP_INLINE_VISIBILITY + void resize(size_type __n) {__table_.rehash(__n);} +}; + +template +hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( + size_type __n, const hasher& __hf, const key_equal& __eql) + : __table_(__hf, __eql) +{ + __table_.rehash(__n); +} + +template +hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( + size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a) + : __table_(__hf, __eql, __a) +{ + __table_.rehash(__n); +} + +template +template +hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( + _InputIterator __first, _InputIterator __last) +{ + __table_.rehash(193); + insert(__first, __last); +} + +template +template +hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( + _InputIterator __first, _InputIterator __last, size_type __n, + const hasher& __hf, const key_equal& __eql) + : __table_(__hf, __eql) +{ + __table_.rehash(__n); + insert(__first, __last); +} + +template +template +hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( + _InputIterator __first, _InputIterator __last, size_type __n, + const hasher& __hf, const key_equal& __eql, const allocator_type& __a) + : __table_(__hf, __eql, __a) +{ + __table_.rehash(__n); + insert(__first, __last); +} + +template +hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( + const hash_multiset& __u) + : __table_(__u.__table_) +{ + __table_.rehash(__u.bucket_count()); + insert(__u.begin(), __u.end()); +} + +template +template +inline _LIBCPP_INLINE_VISIBILITY +void +hash_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, + _InputIterator __last) +{ + for (; __first != __last; ++__first) + __table_.__insert_multi(*__first); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x, + hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y) +{ + __x.swap(__y); +} + +template +bool +operator==(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x, + const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y) +{ + if (__x.size() != __y.size()) + return false; + typedef typename hash_multiset<_Value, _Hash, _Pred, _Alloc>::const_iterator + const_iterator; + typedef pair _EqRng; + for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;) + { + _EqRng __xeq = __x.equal_range(*__i); + _EqRng __yeq = __y.equal_range(*__i); + if (_VSTD::distance(__xeq.first, __xeq.second) != + _VSTD::distance(__yeq.first, __yeq.second) || + !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first)) + return false; + __i = __xeq.second; + } + return true; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x, + const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y) +{ + return !(__x == __y); +} + +} // __gnu_cxx + +#endif // _LIBCPP_HASH_SET diff --git a/headers/libs/libc++/float.h b/headers/libs/libc++/float.h new file mode 100644 index 0000000000..1acfdc6188 --- /dev/null +++ b/headers/libs/libc++/float.h @@ -0,0 +1,83 @@ +// -*- C++ -*- +//===--------------------------- float.h ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_FLOAT_H +#define _LIBCPP_FLOAT_H + +/* + float.h synopsis + +Macros: + + FLT_ROUNDS + FLT_EVAL_METHOD // C99 + FLT_RADIX + + FLT_MANT_DIG + DBL_MANT_DIG + LDBL_MANT_DIG + + DECIMAL_DIG // C99 + + FLT_DIG + DBL_DIG + LDBL_DIG + + FLT_MIN_EXP + DBL_MIN_EXP + LDBL_MIN_EXP + + FLT_MIN_10_EXP + DBL_MIN_10_EXP + LDBL_MIN_10_EXP + + FLT_MAX_EXP + DBL_MAX_EXP + LDBL_MAX_EXP + + FLT_MAX_10_EXP + DBL_MAX_10_EXP + LDBL_MAX_10_EXP + + FLT_MAX + DBL_MAX + LDBL_MAX + + FLT_EPSILON + DBL_EPSILON + LDBL_EPSILON + + FLT_MIN + DBL_MIN + LDBL_MIN + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#include_next + +#ifdef __cplusplus + +#ifndef FLT_EVAL_METHOD +#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ +#endif + +#ifndef DECIMAL_DIG +#define DECIMAL_DIG __DECIMAL_DIG__ +#endif + +#endif // __cplusplus + +#endif // _LIBCPP_FLOAT_H diff --git a/headers/libs/libc++/forward_list b/headers/libs/libc++/forward_list new file mode 100644 index 0000000000..8a87fc5e1f --- /dev/null +++ b/headers/libs/libc++/forward_list @@ -0,0 +1,1649 @@ +// -*- C++ -*- +//===----------------------- forward_list ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_FORWARD_LIST +#define _LIBCPP_FORWARD_LIST + +/* + forward_list synopsis + +namespace std +{ + +template > +class forward_list +{ +public: + typedef T value_type; + typedef Allocator allocator_type; + + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename allocator_traits::pointer pointer; + typedef typename allocator_traits::const_pointer const_pointer; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::difference_type difference_type; + + typedef
iterator; + typedef
const_iterator; + + forward_list() + noexcept(is_nothrow_default_constructible::value); + explicit forward_list(const allocator_type& a); + explicit forward_list(size_type n); + explicit forward_list(size_type n, const allocator_type& a); // C++14 + forward_list(size_type n, const value_type& v); + forward_list(size_type n, const value_type& v, const allocator_type& a); + template + forward_list(InputIterator first, InputIterator last); + template + forward_list(InputIterator first, InputIterator last, const allocator_type& a); + forward_list(const forward_list& x); + forward_list(const forward_list& x, const allocator_type& a); + forward_list(forward_list&& x) + noexcept(is_nothrow_move_constructible::value); + forward_list(forward_list&& x, const allocator_type& a); + forward_list(initializer_list il); + forward_list(initializer_list il, const allocator_type& a); + + ~forward_list(); + + forward_list& operator=(const forward_list& x); + forward_list& operator=(forward_list&& x) + noexcept( + allocator_type::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value); + forward_list& operator=(initializer_list il); + + template + void assign(InputIterator first, InputIterator last); + void assign(size_type n, const value_type& v); + void assign(initializer_list il); + + allocator_type get_allocator() const noexcept; + + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + + iterator before_begin() noexcept; + const_iterator before_begin() const noexcept; + const_iterator cbefore_begin() const noexcept; + + bool empty() const noexcept; + size_type max_size() const noexcept; + + reference front(); + const_reference front() const; + + template void emplace_front(Args&&... args); + void push_front(const value_type& v); + void push_front(value_type&& v); + + void pop_front(); + + template + iterator emplace_after(const_iterator p, Args&&... args); + iterator insert_after(const_iterator p, const value_type& v); + iterator insert_after(const_iterator p, value_type&& v); + iterator insert_after(const_iterator p, size_type n, const value_type& v); + template + iterator insert_after(const_iterator p, + InputIterator first, InputIterator last); + iterator insert_after(const_iterator p, initializer_list il); + + iterator erase_after(const_iterator p); + iterator erase_after(const_iterator first, const_iterator last); + + void swap(forward_list& x) + noexcept(allocator_traits::is_always_equal::value); // C++17 + + void resize(size_type n); + void resize(size_type n, const value_type& v); + void clear() noexcept; + + void splice_after(const_iterator p, forward_list& x); + void splice_after(const_iterator p, forward_list&& x); + void splice_after(const_iterator p, forward_list& x, const_iterator i); + void splice_after(const_iterator p, forward_list&& x, const_iterator i); + void splice_after(const_iterator p, forward_list& x, + const_iterator first, const_iterator last); + void splice_after(const_iterator p, forward_list&& x, + const_iterator first, const_iterator last); + void remove(const value_type& v); + template void remove_if(Predicate pred); + void unique(); + template void unique(BinaryPredicate binary_pred); + void merge(forward_list& x); + void merge(forward_list&& x); + template void merge(forward_list& x, Compare comp); + template void merge(forward_list&& x, Compare comp); + void sort(); + template void sort(Compare comp); + void reverse() noexcept; +}; + +template + bool operator==(const forward_list& x, + const forward_list& y); + +template + bool operator< (const forward_list& x, + const forward_list& y); + +template + bool operator!=(const forward_list& x, + const forward_list& y); + +template + bool operator> (const forward_list& x, + const forward_list& y); + +template + bool operator>=(const forward_list& x, + const forward_list& y); + +template + bool operator<=(const forward_list& x, + const forward_list& y); + +template + void swap(forward_list& x, forward_list& y) + noexcept(noexcept(x.swap(y))); + +} // std + +*/ + +#include <__config> + +#include +#include +#include +#include +#include + +#include <__undef_min_max> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template struct __forward_list_node; + +template +struct __forward_begin_node +{ + typedef _NodePtr pointer; + + pointer __next_; + + _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {} +}; + +template +struct _LIBCPP_HIDDEN __begin_node_of +{ + typedef __forward_begin_node + < + typename pointer_traits<_VoidPtr>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind<__forward_list_node<_Tp, _VoidPtr> > +#else + rebind<__forward_list_node<_Tp, _VoidPtr> >::other +#endif + > type; +}; + +template +struct __forward_list_node + : public __begin_node_of<_Tp, _VoidPtr>::type +{ + typedef _Tp value_type; + + value_type __value_; +}; + +template > class _LIBCPP_TYPE_VIS_ONLY forward_list; +template class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator; + +template +class _LIBCPP_TYPE_VIS_ONLY __forward_list_iterator +{ + typedef _NodePtr __node_pointer; + + __node_pointer __ptr_; + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} + + template friend class _LIBCPP_TYPE_VIS_ONLY forward_list; + template friend class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator; + +public: + typedef forward_iterator_tag iterator_category; + typedef typename pointer_traits<__node_pointer>::element_type::value_type + value_type; + typedef value_type& reference; + typedef typename pointer_traits<__node_pointer>::difference_type + difference_type; + typedef typename pointer_traits<__node_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + pointer; + + _LIBCPP_INLINE_VISIBILITY + __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const {return __ptr_->__value_;} + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const {return pointer_traits::pointer_to(__ptr_->__value_);} + + _LIBCPP_INLINE_VISIBILITY + __forward_list_iterator& operator++() + { + __ptr_ = __ptr_->__next_; + return *this; + } + _LIBCPP_INLINE_VISIBILITY + __forward_list_iterator operator++(int) + { + __forward_list_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __forward_list_iterator& __x, + const __forward_list_iterator& __y) + {return __x.__ptr_ == __y.__ptr_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __forward_list_iterator& __x, + const __forward_list_iterator& __y) + {return !(__x == __y);} +}; + +template +class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator +{ + typedef _NodeConstPtr __node_const_pointer; + + __node_const_pointer __ptr_; + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_const_iterator(__node_const_pointer __p) _NOEXCEPT + : __ptr_(__p) {} + + typedef typename remove_const + < + typename pointer_traits<__node_const_pointer>::element_type + >::type __node; + typedef typename pointer_traits<__node_const_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind<__node> +#else + rebind<__node>::other +#endif + __node_pointer; + + template friend class forward_list; + +public: + typedef forward_iterator_tag iterator_category; + typedef typename __node::value_type value_type; + typedef const value_type& reference; + typedef typename pointer_traits<__node_const_pointer>::difference_type + difference_type; + typedef typename pointer_traits<__node_const_pointer>::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + pointer; + + _LIBCPP_INLINE_VISIBILITY + __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {} + _LIBCPP_INLINE_VISIBILITY + __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT + : __ptr_(__p.__ptr_) {} + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const {return __ptr_->__value_;} + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const {return pointer_traits::pointer_to(__ptr_->__value_);} + + _LIBCPP_INLINE_VISIBILITY + __forward_list_const_iterator& operator++() + { + __ptr_ = __ptr_->__next_; + return *this; + } + _LIBCPP_INLINE_VISIBILITY + __forward_list_const_iterator operator++(int) + { + __forward_list_const_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __forward_list_const_iterator& __x, + const __forward_list_const_iterator& __y) + {return __x.__ptr_ == __y.__ptr_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __forward_list_const_iterator& __x, + const __forward_list_const_iterator& __y) + {return !(__x == __y);} +}; + +template +class __forward_list_base +{ +protected: + typedef _Tp value_type; + typedef _Alloc allocator_type; + + typedef typename allocator_traits::void_pointer void_pointer; + typedef __forward_list_node __node; + typedef typename __begin_node_of::type __begin_node; + typedef typename __rebind_alloc_helper, __node>::type __node_allocator; + typedef allocator_traits<__node_allocator> __node_traits; + typedef typename __node_traits::pointer __node_pointer; + typedef typename __node_traits::pointer __node_const_pointer; + + typedef typename __rebind_alloc_helper, __begin_node>::type __begin_node_allocator; + typedef typename allocator_traits<__begin_node_allocator>::pointer __begin_node_pointer; + + __compressed_pair<__begin_node, __node_allocator> __before_begin_; + + _LIBCPP_INLINE_VISIBILITY + __node_pointer __before_begin() _NOEXCEPT + {return static_cast<__node_pointer>(pointer_traits<__begin_node_pointer>:: + pointer_to(__before_begin_.first()));} + _LIBCPP_INLINE_VISIBILITY + __node_const_pointer __before_begin() const _NOEXCEPT + {return static_cast<__node_const_pointer>(pointer_traits<__begin_node_pointer>:: + pointer_to(const_cast<__begin_node&>(__before_begin_.first())));} + + _LIBCPP_INLINE_VISIBILITY + __node_allocator& __alloc() _NOEXCEPT + {return __before_begin_.second();} + _LIBCPP_INLINE_VISIBILITY + const __node_allocator& __alloc() const _NOEXCEPT + {return __before_begin_.second();} + + typedef __forward_list_iterator<__node_pointer> iterator; + typedef __forward_list_const_iterator<__node_pointer> const_iterator; + + _LIBCPP_INLINE_VISIBILITY + __forward_list_base() + _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) + : __before_begin_(__begin_node()) {} + _LIBCPP_INLINE_VISIBILITY + __forward_list_base(const allocator_type& __a) + : __before_begin_(__begin_node(), __node_allocator(__a)) {} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +public: + __forward_list_base(__forward_list_base&& __x) + _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value); + __forward_list_base(__forward_list_base&& __x, const allocator_type& __a); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +private: + __forward_list_base(const __forward_list_base&); + __forward_list_base& operator=(const __forward_list_base&); + +public: + ~__forward_list_base(); + +protected: + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __forward_list_base& __x) + {__copy_assign_alloc(__x, integral_constant());} + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__forward_list_base& __x) + _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value || + is_nothrow_move_assignable<__node_allocator>::value) + {__move_assign_alloc(__x, integral_constant());} + +public: + void swap(__forward_list_base& __x) +#if _LIBCPP_STD_VER >= 14 + _NOEXCEPT; +#else + _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value || + __is_nothrow_swappable<__node_allocator>::value); +#endif +protected: + void clear() _NOEXCEPT; + +private: + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __forward_list_base&, false_type) {} + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __forward_list_base& __x, true_type) + { + if (__alloc() != __x.__alloc()) + clear(); + __alloc() = __x.__alloc(); + } + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__forward_list_base& __x, false_type) _NOEXCEPT + {} + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__forward_list_base& __x, true_type) + _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) + {__alloc() = _VSTD::move(__x.__alloc());} +}; + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x) + _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) + : __before_begin_(_VSTD::move(__x.__before_begin_)) +{ + __x.__before_begin()->__next_ = nullptr; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x, + const allocator_type& __a) + : __before_begin_(__begin_node(), __node_allocator(__a)) +{ + if (__alloc() == __x.__alloc()) + { + __before_begin()->__next_ = __x.__before_begin()->__next_; + __x.__before_begin()->__next_ = nullptr; + } +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +__forward_list_base<_Tp, _Alloc>::~__forward_list_base() +{ + clear(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x) +#if _LIBCPP_STD_VER >= 14 + _NOEXCEPT +#else + _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value || + __is_nothrow_swappable<__node_allocator>::value) +#endif +{ + __swap_allocator(__alloc(), __x.__alloc(), + integral_constant()); + using _VSTD::swap; + swap(__before_begin()->__next_, __x.__before_begin()->__next_); +} + +template +void +__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT +{ + __node_allocator& __a = __alloc(); + for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;) + { + __node_pointer __next = __p->__next_; + __node_traits::destroy(__a, _VSTD::addressof(__p->__value_)); + __node_traits::deallocate(__a, __p, 1); + __p = __next; + } + __before_begin()->__next_ = nullptr; +} + +template */> +class _LIBCPP_TYPE_VIS_ONLY forward_list + : private __forward_list_base<_Tp, _Alloc> +{ + typedef __forward_list_base<_Tp, _Alloc> base; + typedef typename base::__node_allocator __node_allocator; + typedef typename base::__node __node; + typedef typename base::__node_traits __node_traits; + typedef typename base::__node_pointer __node_pointer; + +public: + typedef _Tp value_type; + typedef _Alloc allocator_type; + + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename allocator_traits::pointer pointer; + typedef typename allocator_traits::const_pointer const_pointer; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::difference_type difference_type; + + typedef typename base::iterator iterator; + typedef typename base::const_iterator const_iterator; + + _LIBCPP_INLINE_VISIBILITY + forward_list() + _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) + {} // = default; + explicit forward_list(const allocator_type& __a); + explicit forward_list(size_type __n); +#if _LIBCPP_STD_VER > 11 + explicit forward_list(size_type __n, const allocator_type& __a); +#endif + forward_list(size_type __n, const value_type& __v); + forward_list(size_type __n, const value_type& __v, const allocator_type& __a); + template + forward_list(_InputIterator __f, _InputIterator __l, + typename enable_if< + __is_input_iterator<_InputIterator>::value + >::type* = nullptr); + template + forward_list(_InputIterator __f, _InputIterator __l, + const allocator_type& __a, + typename enable_if< + __is_input_iterator<_InputIterator>::value + >::type* = nullptr); + forward_list(const forward_list& __x); + forward_list(const forward_list& __x, const allocator_type& __a); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + forward_list(forward_list&& __x) + _NOEXCEPT_(is_nothrow_move_constructible::value) + : base(_VSTD::move(__x)) {} + forward_list(forward_list&& __x, const allocator_type& __a); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + forward_list(initializer_list __il); + forward_list(initializer_list __il, const allocator_type& __a); +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + // ~forward_list() = default; + + forward_list& operator=(const forward_list& __x); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + forward_list& operator=(forward_list&& __x) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value); +#endif +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + forward_list& operator=(initializer_list __il); +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + template + typename enable_if + < + __is_input_iterator<_InputIterator>::value, + void + >::type + assign(_InputIterator __f, _InputIterator __l); + void assign(size_type __n, const value_type& __v); +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + void assign(initializer_list __il); +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const _NOEXCEPT + {return allocator_type(base::__alloc());} + + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT + {return iterator(base::__before_begin()->__next_);} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT + {return const_iterator(base::__before_begin()->__next_);} + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT + {return iterator(nullptr);} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT + {return const_iterator(nullptr);} + + _LIBCPP_INLINE_VISIBILITY + const_iterator cbegin() const _NOEXCEPT + {return const_iterator(base::__before_begin()->__next_);} + _LIBCPP_INLINE_VISIBILITY + const_iterator cend() const _NOEXCEPT + {return const_iterator(nullptr);} + + _LIBCPP_INLINE_VISIBILITY + iterator before_begin() _NOEXCEPT + {return iterator(base::__before_begin());} + _LIBCPP_INLINE_VISIBILITY + const_iterator before_begin() const _NOEXCEPT + {return const_iterator(base::__before_begin());} + _LIBCPP_INLINE_VISIBILITY + const_iterator cbefore_begin() const _NOEXCEPT + {return const_iterator(base::__before_begin());} + + _LIBCPP_INLINE_VISIBILITY + bool empty() const _NOEXCEPT + {return base::__before_begin()->__next_ == nullptr;} + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT + {return numeric_limits::max();} + + _LIBCPP_INLINE_VISIBILITY + reference front() {return base::__before_begin()->__next_->__value_;} + _LIBCPP_INLINE_VISIBILITY + const_reference front() const {return base::__before_begin()->__next_->__value_;} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + template void emplace_front(_Args&&... __args); +#endif + void push_front(value_type&& __v); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + void push_front(const value_type& __v); + + void pop_front(); + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + template + iterator emplace_after(const_iterator __p, _Args&&... __args); +#endif // _LIBCPP_HAS_NO_VARIADICS + iterator insert_after(const_iterator __p, value_type&& __v); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + iterator insert_after(const_iterator __p, const value_type& __v); + iterator insert_after(const_iterator __p, size_type __n, const value_type& __v); + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + __is_input_iterator<_InputIterator>::value, + iterator + >::type + insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l); +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + iterator insert_after(const_iterator __p, initializer_list __il) + {return insert_after(__p, __il.begin(), __il.end());} +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + iterator erase_after(const_iterator __p); + iterator erase_after(const_iterator __f, const_iterator __l); + + _LIBCPP_INLINE_VISIBILITY + void swap(forward_list& __x) +#if _LIBCPP_STD_VER >= 14 + _NOEXCEPT +#else + _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || + __is_nothrow_swappable<__node_allocator>::value) +#endif + {base::swap(__x);} + + void resize(size_type __n); + void resize(size_type __n, const value_type& __v); + _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT {base::clear();} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + void splice_after(const_iterator __p, forward_list&& __x); + _LIBCPP_INLINE_VISIBILITY + void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i); + _LIBCPP_INLINE_VISIBILITY + void splice_after(const_iterator __p, forward_list&& __x, + const_iterator __f, const_iterator __l); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + void splice_after(const_iterator __p, forward_list& __x); + void splice_after(const_iterator __p, forward_list& __x, const_iterator __i); + void splice_after(const_iterator __p, forward_list& __x, + const_iterator __f, const_iterator __l); + void remove(const value_type& __v); + template void remove_if(_Predicate __pred); + _LIBCPP_INLINE_VISIBILITY + void unique() {unique(__equal_to());} + template void unique(_BinaryPredicate __binary_pred); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + void merge(forward_list&& __x) {merge(__x, __less());} + template + _LIBCPP_INLINE_VISIBILITY + void merge(forward_list&& __x, _Compare __comp) + {merge(__x, _VSTD::move(__comp));} +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + void merge(forward_list& __x) {merge(__x, __less());} + template void merge(forward_list& __x, _Compare __comp); + _LIBCPP_INLINE_VISIBILITY + void sort() {sort(__less());} + template void sort(_Compare __comp); + void reverse() _NOEXCEPT; + +private: + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + void __move_assign(forward_list& __x, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value); + void __move_assign(forward_list& __x, false_type); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + template + static + __node_pointer + __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp); + + template + static + __node_pointer + __sort(__node_pointer __f, difference_type __sz, _Compare& __comp); +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a) + : base(__a) +{ +} + +template +forward_list<_Tp, _Alloc>::forward_list(size_type __n) +{ + if (__n > 0) + { + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); + for (__node_pointer __p = base::__before_begin(); __n > 0; --__n, + __p = __p->__next_) + { + __h.reset(__node_traits::allocate(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); + __h->__next_ = nullptr; + __p->__next_ = __h.release(); + } + } +} + +#if _LIBCPP_STD_VER > 11 +template +forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __a) + : base ( __a ) +{ + if (__n > 0) + { + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); + for (__node_pointer __p = base::__before_begin(); __n > 0; --__n, + __p = __p->__next_) + { + __h.reset(__node_traits::allocate(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); + __h->__next_ = nullptr; + __p->__next_ = __h.release(); + } + } +} +#endif + +template +forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v) +{ + insert_after(cbefore_begin(), __n, __v); +} + +template +forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v, + const allocator_type& __a) + : base(__a) +{ + insert_after(cbefore_begin(), __n, __v); +} + +template +template +forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, + typename enable_if< + __is_input_iterator<_InputIterator>::value + >::type*) +{ + insert_after(cbefore_begin(), __f, __l); +} + +template +template +forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, + const allocator_type& __a, + typename enable_if< + __is_input_iterator<_InputIterator>::value + >::type*) + : base(__a) +{ + insert_after(cbefore_begin(), __f, __l); +} + +template +forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x) + : base(allocator_type( + __node_traits::select_on_container_copy_construction(__x.__alloc()) + ) + ) +{ + insert_after(cbefore_begin(), __x.begin(), __x.end()); +} + +template +forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x, + const allocator_type& __a) + : base(__a) +{ + insert_after(cbefore_begin(), __x.begin(), __x.end()); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x, + const allocator_type& __a) + : base(_VSTD::move(__x), __a) +{ + if (base::__alloc() != __x.__alloc()) + { + typedef move_iterator _Ip; + insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end())); + } +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +template +forward_list<_Tp, _Alloc>::forward_list(initializer_list __il) +{ + insert_after(cbefore_begin(), __il.begin(), __il.end()); +} + +template +forward_list<_Tp, _Alloc>::forward_list(initializer_list __il, + const allocator_type& __a) + : base(__a) +{ + insert_after(cbefore_begin(), __il.begin(), __il.end()); +} + +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +template +forward_list<_Tp, _Alloc>& +forward_list<_Tp, _Alloc>::operator=(const forward_list& __x) +{ + if (this != &__x) + { + base::__copy_assign_alloc(__x); + assign(__x.begin(), __x.end()); + } + return *this; +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value) +{ + clear(); + base::__move_assign_alloc(__x); + base::__before_begin()->__next_ = __x.__before_begin()->__next_; + __x.__before_begin()->__next_ = nullptr; +} + +template +void +forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type) +{ + if (base::__alloc() == __x.__alloc()) + __move_assign(__x, true_type()); + else + { + typedef move_iterator _Ip; + assign(_Ip(__x.begin()), _Ip(__x.end())); + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +forward_list<_Tp, _Alloc>& +forward_list<_Tp, _Alloc>::operator=(forward_list&& __x) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value) +{ + __move_assign(__x, integral_constant()); + return *this; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +template +inline _LIBCPP_INLINE_VISIBILITY +forward_list<_Tp, _Alloc>& +forward_list<_Tp, _Alloc>::operator=(initializer_list __il) +{ + assign(__il.begin(), __il.end()); + return *this; +} + +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +template +template +typename enable_if +< + __is_input_iterator<_InputIterator>::value, + void +>::type +forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l) +{ + iterator __i = before_begin(); + iterator __j = _VSTD::next(__i); + iterator __e = end(); + for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f) + *__j = *__f; + if (__j == __e) + insert_after(__i, __f, __l); + else + erase_after(__i, __e); +} + +template +void +forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v) +{ + iterator __i = before_begin(); + iterator __j = _VSTD::next(__i); + iterator __e = end(); + for (; __j != __e && __n > 0; --__n, ++__i, ++__j) + *__j = __v; + if (__j == __e) + insert_after(__i, __n, __v); + else + erase_after(__i, __e); +} + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +template +inline _LIBCPP_INLINE_VISIBILITY +void +forward_list<_Tp, _Alloc>::assign(initializer_list __il) +{ + assign(__il.begin(), __il.end()); +} + +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + +template +template +void +forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args) +{ + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), + _VSTD::forward<_Args>(__args)...); + __h->__next_ = base::__before_begin()->__next_; + base::__before_begin()->__next_ = __h.release(); +} + +#endif // _LIBCPP_HAS_NO_VARIADICS + +template +void +forward_list<_Tp, _Alloc>::push_front(value_type&& __v) +{ + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); + __h->__next_ = base::__before_begin()->__next_; + base::__before_begin()->__next_ = __h.release(); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +forward_list<_Tp, _Alloc>::push_front(const value_type& __v) +{ + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); + __h->__next_ = base::__before_begin()->__next_; + base::__before_begin()->__next_ = __h.release(); +} + +template +void +forward_list<_Tp, _Alloc>::pop_front() +{ + __node_allocator& __a = base::__alloc(); + __node_pointer __p = base::__before_begin()->__next_; + base::__before_begin()->__next_ = __p->__next_; + __node_traits::destroy(__a, _VSTD::addressof(__p->__value_)); + __node_traits::deallocate(__a, __p, 1); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + +template +template +typename forward_list<_Tp, _Alloc>::iterator +forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args) +{ + __node_pointer const __r = __p.__ptr_; + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), + _VSTD::forward<_Args>(__args)...); + __h->__next_ = __r->__next_; + __r->__next_ = __h.release(); + return iterator(__r->__next_); +} + +#endif // _LIBCPP_HAS_NO_VARIADICS + +template +typename forward_list<_Tp, _Alloc>::iterator +forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v) +{ + __node_pointer const __r = __p.__ptr_; + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); + __h->__next_ = __r->__next_; + __r->__next_ = __h.release(); + return iterator(__r->__next_); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +typename forward_list<_Tp, _Alloc>::iterator +forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v) +{ + __node_pointer const __r = __p.__ptr_; + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); + __h->__next_ = __r->__next_; + __r->__next_ = __h.release(); + return iterator(__r->__next_); +} + +template +typename forward_list<_Tp, _Alloc>::iterator +forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, + const value_type& __v) +{ + __node_pointer __r = __p.__ptr_; + if (__n > 0) + { + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); + __node_pointer __first = __h.release(); + __node_pointer __last = __first; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (--__n; __n != 0; --__n, __last = __last->__next_) + { + __h.reset(__node_traits::allocate(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); + __last->__next_ = __h.release(); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + while (__first != nullptr) + { + __node_pointer __next = __first->__next_; + __node_traits::destroy(__a, _VSTD::addressof(__first->__value_)); + __node_traits::deallocate(__a, __first, 1); + __first = __next; + } + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __last->__next_ = __r->__next_; + __r->__next_ = __first; + __r = __last; + } + return iterator(__r); +} + +template +template +typename enable_if +< + __is_input_iterator<_InputIterator>::value, + typename forward_list<_Tp, _Alloc>::iterator +>::type +forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, + _InputIterator __f, _InputIterator __l) +{ + __node_pointer __r = __p.__ptr_; + if (__f != __l) + { + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f); + __node_pointer __first = __h.release(); + __node_pointer __last = __first; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_))) + { + __h.reset(__node_traits::allocate(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f); + __last->__next_ = __h.release(); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + while (__first != nullptr) + { + __node_pointer __next = __first->__next_; + __node_traits::destroy(__a, _VSTD::addressof(__first->__value_)); + __node_traits::deallocate(__a, __first, 1); + __first = __next; + } + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __last->__next_ = __r->__next_; + __r->__next_ = __first; + __r = __last; + } + return iterator(__r); +} + +template +typename forward_list<_Tp, _Alloc>::iterator +forward_list<_Tp, _Alloc>::erase_after(const_iterator __f) +{ + __node_pointer __p = __f.__ptr_; + __node_pointer __n = __p->__next_; + __p->__next_ = __n->__next_; + __node_allocator& __a = base::__alloc(); + __node_traits::destroy(__a, _VSTD::addressof(__n->__value_)); + __node_traits::deallocate(__a, __n, 1); + return iterator(__p->__next_); +} + +template +typename forward_list<_Tp, _Alloc>::iterator +forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l) +{ + __node_pointer __e = __l.__ptr_; + if (__f != __l) + { + __node_pointer __p = __f.__ptr_; + __node_pointer __n = __p->__next_; + if (__n != __e) + { + __p->__next_ = __e; + __node_allocator& __a = base::__alloc(); + do + { + __p = __n->__next_; + __node_traits::destroy(__a, _VSTD::addressof(__n->__value_)); + __node_traits::deallocate(__a, __n, 1); + __n = __p; + } while (__n != __e); + } + } + return iterator(__e); +} + +template +void +forward_list<_Tp, _Alloc>::resize(size_type __n) +{ + size_type __sz = 0; + iterator __p = before_begin(); + iterator __i = begin(); + iterator __e = end(); + for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz) + ; + if (__i != __e) + erase_after(__p, __e); + else + { + __n -= __sz; + if (__n > 0) + { + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); + for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n, + __ptr = __ptr->__next_) + { + __h.reset(__node_traits::allocate(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); + __h->__next_ = nullptr; + __ptr->__next_ = __h.release(); + } + } + } +} + +template +void +forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v) +{ + size_type __sz = 0; + iterator __p = before_begin(); + iterator __i = begin(); + iterator __e = end(); + for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz) + ; + if (__i != __e) + erase_after(__p, __e); + else + { + __n -= __sz; + if (__n > 0) + { + __node_allocator& __a = base::__alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); + for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n, + __ptr = __ptr->__next_) + { + __h.reset(__node_traits::allocate(__a, 1)); + __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); + __h->__next_ = nullptr; + __ptr->__next_ = __h.release(); + } + } + } +} + +template +void +forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, + forward_list& __x) +{ + if (!__x.empty()) + { + if (__p.__ptr_->__next_ != nullptr) + { + const_iterator __lm1 = __x.before_begin(); + while (__lm1.__ptr_->__next_ != nullptr) + ++__lm1; + __lm1.__ptr_->__next_ = __p.__ptr_->__next_; + } + __p.__ptr_->__next_ = __x.__before_begin()->__next_; + __x.__before_begin()->__next_ = nullptr; + } +} + +template +void +forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, + forward_list& __x, + const_iterator __i) +{ + const_iterator __lm1 = _VSTD::next(__i); + if (__p != __i && __p != __lm1) + { + __i.__ptr_->__next_ = __lm1.__ptr_->__next_; + __lm1.__ptr_->__next_ = __p.__ptr_->__next_; + __p.__ptr_->__next_ = __lm1.__ptr_; + } +} + +template +void +forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, + forward_list& __x, + const_iterator __f, const_iterator __l) +{ + if (__f != __l && __p != __f) + { + const_iterator __lm1 = __f; + while (__lm1.__ptr_->__next_ != __l.__ptr_) + ++__lm1; + if (__f != __lm1) + { + __lm1.__ptr_->__next_ = __p.__ptr_->__next_; + __p.__ptr_->__next_ = __f.__ptr_->__next_; + __f.__ptr_->__next_ = __l.__ptr_; + } + } +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +void +forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, + forward_list&& __x) +{ + splice_after(__p, __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, + forward_list&& __x, + const_iterator __i) +{ + splice_after(__p, __x, __i); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, + forward_list&& __x, + const_iterator __f, const_iterator __l) +{ + splice_after(__p, __x, __f, __l); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +forward_list<_Tp, _Alloc>::remove(const value_type& __v) +{ + forward_list<_Tp, _Alloc> __deleted_nodes; // collect the nodes we're removing + iterator __e = end(); + for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;) + { + if (__i.__ptr_->__next_->__value_ == __v) + { + iterator __j = _VSTD::next(__i, 2); + for (; __j != __e && *__j == __v; ++__j) + ; + __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j); + if (__j == __e) + break; + __i = __j; + } + else + ++__i; + } +} + +template +template +void +forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred) +{ + iterator __e = end(); + for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;) + { + if (__pred(__i.__ptr_->__next_->__value_)) + { + iterator __j = _VSTD::next(__i, 2); + for (; __j != __e && __pred(*__j); ++__j) + ; + erase_after(__i, __j); + if (__j == __e) + break; + __i = __j; + } + else + ++__i; + } +} + +template +template +void +forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) +{ + for (iterator __i = begin(), __e = end(); __i != __e;) + { + iterator __j = _VSTD::next(__i); + for (; __j != __e && __binary_pred(*__i, *__j); ++__j) + ; + if (__i.__ptr_->__next_ != __j.__ptr_) + erase_after(__i, __j); + __i = __j; + } +} + +template +template +void +forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp) +{ + if (this != &__x) + { + base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_, + __x.__before_begin()->__next_, + __comp); + __x.__before_begin()->__next_ = nullptr; + } +} + +template +template +typename forward_list<_Tp, _Alloc>::__node_pointer +forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2, + _Compare& __comp) +{ + if (__f1 == nullptr) + return __f2; + if (__f2 == nullptr) + return __f1; + __node_pointer __r; + if (__comp(__f2->__value_, __f1->__value_)) + { + __node_pointer __t = __f2; + while (__t->__next_ != nullptr && + __comp(__t->__next_->__value_, __f1->__value_)) + __t = __t->__next_; + __r = __f2; + __f2 = __t->__next_; + __t->__next_ = __f1; + } + else + __r = __f1; + __node_pointer __p = __f1; + __f1 = __f1->__next_; + while (__f1 != nullptr && __f2 != nullptr) + { + if (__comp(__f2->__value_, __f1->__value_)) + { + __node_pointer __t = __f2; + while (__t->__next_ != nullptr && + __comp(__t->__next_->__value_, __f1->__value_)) + __t = __t->__next_; + __p->__next_ = __f2; + __f2 = __t->__next_; + __t->__next_ = __f1; + } + __p = __f1; + __f1 = __f1->__next_; + } + if (__f2 != nullptr) + __p->__next_ = __f2; + return __r; +} + +template +template +inline _LIBCPP_INLINE_VISIBILITY +void +forward_list<_Tp, _Alloc>::sort(_Compare __comp) +{ + base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_, + _VSTD::distance(begin(), end()), __comp); +} + +template +template +typename forward_list<_Tp, _Alloc>::__node_pointer +forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz, + _Compare& __comp) +{ + switch (__sz) + { + case 0: + case 1: + return __f1; + case 2: + if (__comp(__f1->__next_->__value_, __f1->__value_)) + { + __node_pointer __t = __f1->__next_; + __t->__next_ = __f1; + __f1->__next_ = nullptr; + __f1 = __t; + } + return __f1; + } + difference_type __sz1 = __sz / 2; + difference_type __sz2 = __sz - __sz1; + __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__ptr_; + __node_pointer __f2 = __t->__next_; + __t->__next_ = nullptr; + return __merge(__sort(__f1, __sz1, __comp), + __sort(__f2, __sz2, __comp), __comp); +} + +template +void +forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT +{ + __node_pointer __p = base::__before_begin()->__next_; + if (__p != nullptr) + { + __node_pointer __f = __p->__next_; + __p->__next_ = nullptr; + while (__f != nullptr) + { + __node_pointer __t = __f->__next_; + __f->__next_ = __p; + __p = __f; + __f = __t; + } + base::__before_begin()->__next_ = __p; + } +} + +template +bool operator==(const forward_list<_Tp, _Alloc>& __x, + const forward_list<_Tp, _Alloc>& __y) +{ + typedef forward_list<_Tp, _Alloc> _Cp; + typedef typename _Cp::const_iterator _Ip; + _Ip __ix = __x.begin(); + _Ip __ex = __x.end(); + _Ip __iy = __y.begin(); + _Ip __ey = __y.end(); + for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy) + if (!(*__ix == *__iy)) + return false; + return (__ix == __ex) == (__iy == __ey); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(const forward_list<_Tp, _Alloc>& __x, + const forward_list<_Tp, _Alloc>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator< (const forward_list<_Tp, _Alloc>& __x, + const forward_list<_Tp, _Alloc>& __y) +{ + return _VSTD::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator> (const forward_list<_Tp, _Alloc>& __x, + const forward_list<_Tp, _Alloc>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator>=(const forward_list<_Tp, _Alloc>& __x, + const forward_list<_Tp, _Alloc>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator<=(const forward_list<_Tp, _Alloc>& __x, + const forward_list<_Tp, _Alloc>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_FORWARD_LIST diff --git a/headers/libs/libc++/fstream b/headers/libs/libc++/fstream new file mode 100644 index 0000000000..1f289eddc5 --- /dev/null +++ b/headers/libs/libc++/fstream @@ -0,0 +1,1457 @@ +// -*- C++ -*- +//===------------------------- fstream ------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_FSTREAM +#define _LIBCPP_FSTREAM + +/* + fstream synopsis + +template > +class basic_filebuf + : public basic_streambuf +{ +public: + typedef charT char_type; + typedef traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // 27.9.1.2 Constructors/destructor: + basic_filebuf(); + basic_filebuf(basic_filebuf&& rhs); + virtual ~basic_filebuf(); + + // 27.9.1.3 Assign/swap: + basic_filebuf& operator=(basic_filebuf&& rhs); + void swap(basic_filebuf& rhs); + + // 27.9.1.4 Members: + bool is_open() const; + basic_filebuf* open(const char* s, ios_base::openmode mode); + basic_filebuf* open(const string& s, ios_base::openmode mode); + basic_filebuf* close(); + +protected: + // 27.9.1.5 Overridden virtual functions: + virtual streamsize showmanyc(); + virtual int_type underflow(); + virtual int_type uflow(); + virtual int_type pbackfail(int_type c = traits_type::eof()); + virtual int_type overflow (int_type c = traits_type::eof()); + virtual basic_streambuf* setbuf(char_type* s, streamsize n); + virtual pos_type seekoff(off_type off, ios_base::seekdir way, + ios_base::openmode which = ios_base::in | ios_base::out); + virtual pos_type seekpos(pos_type sp, + ios_base::openmode which = ios_base::in | ios_base::out); + virtual int sync(); + virtual void imbue(const locale& loc); +}; + +template + void + swap(basic_filebuf& x, basic_filebuf& y); + +typedef basic_filebuf filebuf; +typedef basic_filebuf wfilebuf; + +template > +class basic_ifstream + : public basic_istream +{ +public: + typedef charT char_type; + typedef traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + basic_ifstream(); + explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in); + explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in); + basic_ifstream(basic_ifstream&& rhs); + + basic_ifstream& operator=(basic_ifstream&& rhs); + void swap(basic_ifstream& rhs); + + basic_filebuf* rdbuf() const; + bool is_open() const; + void open(const char* s, ios_base::openmode mode = ios_base::in); + void open(const string& s, ios_base::openmode mode = ios_base::in); + void close(); +}; + +template + void + swap(basic_ifstream& x, basic_ifstream& y); + +typedef basic_ifstream ifstream; +typedef basic_ifstream wifstream; + +template > +class basic_ofstream + : public basic_ostream +{ +public: + typedef charT char_type; + typedef traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + basic_ofstream(); + explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out); + explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out); + basic_ofstream(basic_ofstream&& rhs); + + basic_ofstream& operator=(basic_ofstream&& rhs); + void swap(basic_ofstream& rhs); + + basic_filebuf* rdbuf() const; + bool is_open() const; + void open(const char* s, ios_base::openmode mode = ios_base::out); + void open(const string& s, ios_base::openmode mode = ios_base::out); + void close(); +}; + +template + void + swap(basic_ofstream& x, basic_ofstream& y); + +typedef basic_ofstream ofstream; +typedef basic_ofstream wofstream; + +template > +class basic_fstream + : public basic_iostream +{ +public: + typedef charT char_type; + typedef traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + basic_fstream(); + explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out); + explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out); + basic_fstream(basic_fstream&& rhs); + + basic_fstream& operator=(basic_fstream&& rhs); + void swap(basic_fstream& rhs); + + basic_filebuf* rdbuf() const; + bool is_open() const; + void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out); + void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out); + void close(); +}; + +template + void swap(basic_fstream& x, basic_fstream& y); + +typedef basic_fstream fstream; +typedef basic_fstream wfstream; + +} // std + +*/ + +#include <__config> +#include +#include +#include <__locale> +#include + +#include <__undef_min_max> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TYPE_VIS_ONLY basic_filebuf + : public basic_streambuf<_CharT, _Traits> +{ +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + typedef typename traits_type::state_type state_type; + + // 27.9.1.2 Constructors/destructor: + basic_filebuf(); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + basic_filebuf(basic_filebuf&& __rhs); +#endif + virtual ~basic_filebuf(); + + // 27.9.1.3 Assign/swap: +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + basic_filebuf& operator=(basic_filebuf&& __rhs); +#endif + void swap(basic_filebuf& __rhs); + + // 27.9.1.4 Members: + bool is_open() const; +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + basic_filebuf* open(const char* __s, ios_base::openmode __mode); + basic_filebuf* open(const string& __s, ios_base::openmode __mode); +#endif + basic_filebuf* close(); + +protected: + // 27.9.1.5 Overridden virtual functions: + virtual int_type underflow(); + virtual int_type pbackfail(int_type __c = traits_type::eof()); + virtual int_type overflow (int_type __c = traits_type::eof()); + virtual basic_streambuf* setbuf(char_type* __s, streamsize __n); + virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __wch = ios_base::in | ios_base::out); + virtual pos_type seekpos(pos_type __sp, + ios_base::openmode __wch = ios_base::in | ios_base::out); + virtual int sync(); + virtual void imbue(const locale& __loc); + +private: + char* __extbuf_; + const char* __extbufnext_; + const char* __extbufend_; + char __extbuf_min_[8]; + size_t __ebs_; + char_type* __intbuf_; + size_t __ibs_; + FILE* __file_; + const codecvt* __cv_; + state_type __st_; + state_type __st_last_; + ios_base::openmode __om_; + ios_base::openmode __cm_; + bool __owns_eb_; + bool __owns_ib_; + bool __always_noconv_; + + bool __read_mode(); + void __write_mode(); +}; + +template +basic_filebuf<_CharT, _Traits>::basic_filebuf() + : __extbuf_(0), + __extbufnext_(0), + __extbufend_(0), + __ebs_(0), + __intbuf_(0), + __ibs_(0), + __file_(0), + __cv_(nullptr), + __st_(), + __st_last_(), + __om_(0), + __cm_(0), + __owns_eb_(false), + __owns_ib_(false), + __always_noconv_(false) +{ + if (has_facet >(this->getloc())) + { + __cv_ = &use_facet >(this->getloc()); + __always_noconv_ = __cv_->always_noconv(); + } + setbuf(0, 4096); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) + : basic_streambuf<_CharT, _Traits>(__rhs) +{ + if (__rhs.__extbuf_ == __rhs.__extbuf_min_) + { + __extbuf_ = __extbuf_min_; + __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_); + __extbufend_ = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_); + } + else + { + __extbuf_ = __rhs.__extbuf_; + __extbufnext_ = __rhs.__extbufnext_; + __extbufend_ = __rhs.__extbufend_; + } + __ebs_ = __rhs.__ebs_; + __intbuf_ = __rhs.__intbuf_; + __ibs_ = __rhs.__ibs_; + __file_ = __rhs.__file_; + __cv_ = __rhs.__cv_; + __st_ = __rhs.__st_; + __st_last_ = __rhs.__st_last_; + __om_ = __rhs.__om_; + __cm_ = __rhs.__cm_; + __owns_eb_ = __rhs.__owns_eb_; + __owns_ib_ = __rhs.__owns_ib_; + __always_noconv_ = __rhs.__always_noconv_; + if (__rhs.pbase()) + { + if (__rhs.pbase() == __rhs.__intbuf_) + this->setp(__intbuf_, __intbuf_ + (__rhs. epptr() - __rhs.pbase())); + else + this->setp((char_type*)__extbuf_, + (char_type*)__extbuf_ + (__rhs. epptr() - __rhs.pbase())); + this->pbump(__rhs. pptr() - __rhs.pbase()); + } + else if (__rhs.eback()) + { + if (__rhs.eback() == __rhs.__intbuf_) + this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()), + __intbuf_ + (__rhs.egptr() - __rhs.eback())); + else + this->setg((char_type*)__extbuf_, + (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()), + (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback())); + } + __rhs.__extbuf_ = 0; + __rhs.__extbufnext_ = 0; + __rhs.__extbufend_ = 0; + __rhs.__ebs_ = 0; + __rhs.__intbuf_ = 0; + __rhs.__ibs_ = 0; + __rhs.__file_ = 0; + __rhs.__st_ = state_type(); + __rhs.__st_last_ = state_type(); + __rhs.__om_ = 0; + __rhs.__cm_ = 0; + __rhs.__owns_eb_ = false; + __rhs.__owns_ib_ = false; + __rhs.setg(0, 0, 0); + __rhs.setp(0, 0); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_filebuf<_CharT, _Traits>& +basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) +{ + close(); + swap(__rhs); + return *this; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +basic_filebuf<_CharT, _Traits>::~basic_filebuf() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + close(); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCPP_NO_EXCEPTIONS + if (__owns_eb_) + delete [] __extbuf_; + if (__owns_ib_) + delete [] __intbuf_; +} + +template +void +basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) +{ + basic_streambuf::swap(__rhs); + if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) + { + _VSTD::swap(__extbuf_, __rhs.__extbuf_); + _VSTD::swap(__extbufnext_, __rhs.__extbufnext_); + _VSTD::swap(__extbufend_, __rhs.__extbufend_); + } + else + { + ptrdiff_t __ln = __extbufnext_ - __extbuf_; + ptrdiff_t __le = __extbufend_ - __extbuf_; + ptrdiff_t __rn = __rhs.__extbufnext_ - __rhs.__extbuf_; + ptrdiff_t __re = __rhs.__extbufend_ - __rhs.__extbuf_; + if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) + { + __extbuf_ = __rhs.__extbuf_; + __rhs.__extbuf_ = __rhs.__extbuf_min_; + } + else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_) + { + __rhs.__extbuf_ = __extbuf_; + __extbuf_ = __extbuf_min_; + } + __extbufnext_ = __extbuf_ + __rn; + __extbufend_ = __extbuf_ + __re; + __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln; + __rhs.__extbufend_ = __rhs.__extbuf_ + __le; + } + _VSTD::swap(__ebs_, __rhs.__ebs_); + _VSTD::swap(__intbuf_, __rhs.__intbuf_); + _VSTD::swap(__ibs_, __rhs.__ibs_); + _VSTD::swap(__file_, __rhs.__file_); + _VSTD::swap(__cv_, __rhs.__cv_); + _VSTD::swap(__st_, __rhs.__st_); + _VSTD::swap(__st_last_, __rhs.__st_last_); + _VSTD::swap(__om_, __rhs.__om_); + _VSTD::swap(__cm_, __rhs.__cm_); + _VSTD::swap(__owns_eb_, __rhs.__owns_eb_); + _VSTD::swap(__owns_ib_, __rhs.__owns_ib_); + _VSTD::swap(__always_noconv_, __rhs.__always_noconv_); + if (this->eback() == (char_type*)__rhs.__extbuf_min_) + { + ptrdiff_t __n = this->gptr() - this->eback(); + ptrdiff_t __e = this->egptr() - this->eback(); + this->setg((char_type*)__extbuf_min_, + (char_type*)__extbuf_min_ + __n, + (char_type*)__extbuf_min_ + __e); + } + else if (this->pbase() == (char_type*)__rhs.__extbuf_min_) + { + ptrdiff_t __n = this->pptr() - this->pbase(); + ptrdiff_t __e = this->epptr() - this->pbase(); + this->setp((char_type*)__extbuf_min_, + (char_type*)__extbuf_min_ + __e); + this->pbump(__n); + } + if (__rhs.eback() == (char_type*)__extbuf_min_) + { + ptrdiff_t __n = __rhs.gptr() - __rhs.eback(); + ptrdiff_t __e = __rhs.egptr() - __rhs.eback(); + __rhs.setg((char_type*)__rhs.__extbuf_min_, + (char_type*)__rhs.__extbuf_min_ + __n, + (char_type*)__rhs.__extbuf_min_ + __e); + } + else if (__rhs.pbase() == (char_type*)__extbuf_min_) + { + ptrdiff_t __n = __rhs.pptr() - __rhs.pbase(); + ptrdiff_t __e = __rhs.epptr() - __rhs.pbase(); + __rhs.setp((char_type*)__rhs.__extbuf_min_, + (char_type*)__rhs.__extbuf_min_ + __e); + __rhs.pbump(__n); + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) +{ + __x.swap(__y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +basic_filebuf<_CharT, _Traits>::is_open() const +{ + return __file_ != 0; +} + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +template +basic_filebuf<_CharT, _Traits>* +basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) +{ + basic_filebuf<_CharT, _Traits>* __rt = 0; + if (__file_ == 0) + { + __rt = this; + const char* __mdstr; + switch (__mode & ~ios_base::ate) + { + case ios_base::out: + case ios_base::out | ios_base::trunc: + __mdstr = "w"; + break; + case ios_base::out | ios_base::app: + case ios_base::app: + __mdstr = "a"; + break; + case ios_base::in: + __mdstr = "r"; + break; + case ios_base::in | ios_base::out: + __mdstr = "r+"; + break; + case ios_base::in | ios_base::out | ios_base::trunc: + __mdstr = "w+"; + break; + case ios_base::in | ios_base::out | ios_base::app: + case ios_base::in | ios_base::app: + __mdstr = "a+"; + break; + case ios_base::out | ios_base::binary: + case ios_base::out | ios_base::trunc | ios_base::binary: + __mdstr = "wb"; + break; + case ios_base::out | ios_base::app | ios_base::binary: + case ios_base::app | ios_base::binary: + __mdstr = "ab"; + break; + case ios_base::in | ios_base::binary: + __mdstr = "rb"; + break; + case ios_base::in | ios_base::out | ios_base::binary: + __mdstr = "r+b"; + break; + case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary: + __mdstr = "w+b"; + break; + case ios_base::in | ios_base::out | ios_base::app | ios_base::binary: + case ios_base::in | ios_base::app | ios_base::binary: + __mdstr = "a+b"; + break; + default: + __rt = 0; + break; + } + if (__rt) + { + __file_ = fopen(__s, __mdstr); + if (__file_) + { + __om_ = __mode; + if (__mode & ios_base::ate) + { + if (fseek(__file_, 0, SEEK_END)) + { + fclose(__file_); + __file_ = 0; + __rt = 0; + } + } + } + else + __rt = 0; + } + } + return __rt; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_filebuf<_CharT, _Traits>* +basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) +{ + return open(__s.c_str(), __mode); +} +#endif + +template +basic_filebuf<_CharT, _Traits>* +basic_filebuf<_CharT, _Traits>::close() +{ + basic_filebuf<_CharT, _Traits>* __rt = 0; + if (__file_) + { + __rt = this; + unique_ptr __h(__file_, fclose); + if (sync()) + __rt = 0; + if (fclose(__h.release()) == 0) + __file_ = 0; + else + __rt = 0; + } + return __rt; +} + +template +typename basic_filebuf<_CharT, _Traits>::int_type +basic_filebuf<_CharT, _Traits>::underflow() +{ + if (__file_ == 0) + return traits_type::eof(); + bool __initial = __read_mode(); + char_type __1buf; + if (this->gptr() == 0) + this->setg(&__1buf, &__1buf+1, &__1buf+1); + const size_t __unget_sz = __initial ? 0 : min((this->egptr() - this->eback()) / 2, 4); + int_type __c = traits_type::eof(); + if (this->gptr() == this->egptr()) + { + memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type)); + if (__always_noconv_) + { + size_t __nmemb = static_cast(this->egptr() - this->eback() - __unget_sz); + __nmemb = fread(this->eback() + __unget_sz, 1, __nmemb, __file_); + if (__nmemb != 0) + { + this->setg(this->eback(), + this->eback() + __unget_sz, + this->eback() + __unget_sz + __nmemb); + __c = traits_type::to_int_type(*this->gptr()); + } + } + else + { + memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); + __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); + __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_); + size_t __nmemb = _VSTD::min(static_cast(__ibs_ - __unget_sz), + static_cast(__extbufend_ - __extbufnext_)); + codecvt_base::result __r; + __st_last_ = __st_; + size_t __nr = fread((void*)__extbufnext_, 1, __nmemb, __file_); + if (__nr != 0) + { +#ifndef _LIBCPP_NO_EXCEPTIONS + if (!__cv_) + throw bad_cast(); +#endif + __extbufend_ = __extbufnext_ + __nr; + char_type* __inext; + __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_, + this->eback() + __unget_sz, + this->eback() + __ibs_, __inext); + if (__r == codecvt_base::noconv) + { + this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_); + __c = traits_type::to_int_type(*this->gptr()); + } + else if (__inext != this->eback() + __unget_sz) + { + this->setg(this->eback(), this->eback() + __unget_sz, __inext); + __c = traits_type::to_int_type(*this->gptr()); + } + } + } + } + else + __c = traits_type::to_int_type(*this->gptr()); + if (this->eback() == &__1buf) + this->setg(0, 0, 0); + return __c; +} + +template +typename basic_filebuf<_CharT, _Traits>::int_type +basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) +{ + if (__file_ && this->eback() < this->gptr()) + { + if (traits_type::eq_int_type(__c, traits_type::eof())) + { + this->gbump(-1); + return traits_type::not_eof(__c); + } + if ((__om_ & ios_base::out) || + traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) + { + this->gbump(-1); + *this->gptr() = traits_type::to_char_type(__c); + return __c; + } + } + return traits_type::eof(); +} + +template +typename basic_filebuf<_CharT, _Traits>::int_type +basic_filebuf<_CharT, _Traits>::overflow(int_type __c) +{ + if (__file_ == 0) + return traits_type::eof(); + __write_mode(); + char_type __1buf; + char_type* __pb_save = this->pbase(); + char_type* __epb_save = this->epptr(); + if (!traits_type::eq_int_type(__c, traits_type::eof())) + { + if (this->pptr() == 0) + this->setp(&__1buf, &__1buf+1); + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } + if (this->pptr() != this->pbase()) + { + if (__always_noconv_) + { + size_t __nmemb = static_cast(this->pptr() - this->pbase()); + if (fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb) + return traits_type::eof(); + } + else + { + char* __extbe = __extbuf_; + codecvt_base::result __r; + do + { +#ifndef _LIBCPP_NO_EXCEPTIONS + if (!__cv_) + throw bad_cast(); +#endif + const char_type* __e; + __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, + __extbuf_, __extbuf_ + __ebs_, __extbe); + if (__e == this->pbase()) + return traits_type::eof(); + if (__r == codecvt_base::noconv) + { + size_t __nmemb = static_cast(this->pptr() - this->pbase()); + if (fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb) + return traits_type::eof(); + } + else if (__r == codecvt_base::ok || __r == codecvt_base::partial) + { + size_t __nmemb = static_cast(__extbe - __extbuf_); + if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb) + return traits_type::eof(); + if (__r == codecvt_base::partial) + { + this->setp((char_type*)__e, this->pptr()); + this->pbump(this->epptr() - this->pbase()); + } + } + else + return traits_type::eof(); + } while (__r == codecvt_base::partial); + } + this->setp(__pb_save, __epb_save); + } + return traits_type::not_eof(__c); +} + +template +basic_streambuf<_CharT, _Traits>* +basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n) +{ + this->setg(0, 0, 0); + this->setp(0, 0); + if (__owns_eb_) + delete [] __extbuf_; + if (__owns_ib_) + delete [] __intbuf_; + __ebs_ = __n; + if (__ebs_ > sizeof(__extbuf_min_)) + { + if (__always_noconv_ && __s) + { + __extbuf_ = (char*)__s; + __owns_eb_ = false; + } + else + { + __extbuf_ = new char[__ebs_]; + __owns_eb_ = true; + } + } + else + { + __extbuf_ = __extbuf_min_; + __ebs_ = sizeof(__extbuf_min_); + __owns_eb_ = false; + } + if (!__always_noconv_) + { + __ibs_ = max(__n, sizeof(__extbuf_min_)); + if (__s && __ibs_ >= sizeof(__extbuf_min_)) + { + __intbuf_ = __s; + __owns_ib_ = false; + } + else + { + __intbuf_ = new char_type[__ibs_]; + __owns_ib_ = true; + } + } + else + { + __ibs_ = 0; + __intbuf_ = 0; + __owns_ib_ = false; + } + return this; +} + +template +typename basic_filebuf<_CharT, _Traits>::pos_type +basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + if (!__cv_) + throw bad_cast(); +#endif + int __width = __cv_->encoding(); + if (__file_ == 0 || (__width <= 0 && __off != 0) || sync()) + return pos_type(off_type(-1)); + // __width > 0 || __off == 0 + int __whence; + switch (__way) + { + case ios_base::beg: + __whence = SEEK_SET; + break; + case ios_base::cur: + __whence = SEEK_CUR; + break; + case ios_base::end: + __whence = SEEK_END; + break; + default: + return pos_type(off_type(-1)); + } +#if defined(_WIN32) || defined(_NEWLIB_VERSION) + if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence)) + return pos_type(off_type(-1)); + pos_type __r = ftell(__file_); +#else + if (fseeko(__file_, __width > 0 ? __width * __off : 0, __whence)) + return pos_type(off_type(-1)); + pos_type __r = ftello(__file_); +#endif + __r.state(__st_); + return __r; +} + +template +typename basic_filebuf<_CharT, _Traits>::pos_type +basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) +{ + if (__file_ == 0 || sync()) + return pos_type(off_type(-1)); +#if defined(_WIN32) || defined(_NEWLIB_VERSION) + if (fseek(__file_, __sp, SEEK_SET)) + return pos_type(off_type(-1)); +#else + if (fseeko(__file_, __sp, SEEK_SET)) + return pos_type(off_type(-1)); +#endif + __st_ = __sp.state(); + return __sp; +} + +template +int +basic_filebuf<_CharT, _Traits>::sync() +{ + if (__file_ == 0) + return 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + if (!__cv_) + throw bad_cast(); +#endif + if (__cm_ & ios_base::out) + { + if (this->pptr() != this->pbase()) + if (overflow() == traits_type::eof()) + return -1; + codecvt_base::result __r; + do + { + char* __extbe; + __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe); + size_t __nmemb = static_cast(__extbe - __extbuf_); + if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb) + return -1; + } while (__r == codecvt_base::partial); + if (__r == codecvt_base::error) + return -1; + if (fflush(__file_)) + return -1; + } + else if (__cm_ & ios_base::in) + { + off_type __c; + state_type __state = __st_last_; + bool __update_st = false; + if (__always_noconv_) + __c = this->egptr() - this->gptr(); + else + { + int __width = __cv_->encoding(); + __c = __extbufend_ - __extbufnext_; + if (__width > 0) + __c += __width * (this->egptr() - this->gptr()); + else + { + if (this->gptr() != this->egptr()) + { + const int __off = __cv_->length(__state, __extbuf_, + __extbufnext_, + this->gptr() - this->eback()); + __c += __extbufnext_ - __extbuf_ - __off; + __update_st = true; + } + } + } +#if defined(_WIN32) || defined(_NEWLIB_VERSION) + if (fseek(__file_, -__c, SEEK_CUR)) + return -1; +#else + if (fseeko(__file_, -__c, SEEK_CUR)) + return -1; +#endif + if (__update_st) + __st_ = __state; + __extbufnext_ = __extbufend_ = __extbuf_; + this->setg(0, 0, 0); + __cm_ = 0; + } + return 0; +} + +template +void +basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) +{ + sync(); + __cv_ = &use_facet >(__loc); + bool __old_anc = __always_noconv_; + __always_noconv_ = __cv_->always_noconv(); + if (__old_anc != __always_noconv_) + { + this->setg(0, 0, 0); + this->setp(0, 0); + // invariant, char_type is char, else we couldn't get here + if (__always_noconv_) // need to dump __intbuf_ + { + if (__owns_eb_) + delete [] __extbuf_; + __owns_eb_ = __owns_ib_; + __ebs_ = __ibs_; + __extbuf_ = (char*)__intbuf_; + __ibs_ = 0; + __intbuf_ = 0; + __owns_ib_ = false; + } + else // need to obtain an __intbuf_. + { // If __extbuf_ is user-supplied, use it, else new __intbuf_ + if (!__owns_eb_ && __extbuf_ != __extbuf_min_) + { + __ibs_ = __ebs_; + __intbuf_ = (char_type*)__extbuf_; + __owns_ib_ = false; + __extbuf_ = new char[__ebs_]; + __owns_eb_ = true; + } + else + { + __ibs_ = __ebs_; + __intbuf_ = new char_type[__ibs_]; + __owns_ib_ = true; + } + } + } +} + +template +bool +basic_filebuf<_CharT, _Traits>::__read_mode() +{ + if (!(__cm_ & ios_base::in)) + { + this->setp(0, 0); + if (__always_noconv_) + this->setg((char_type*)__extbuf_, + (char_type*)__extbuf_ + __ebs_, + (char_type*)__extbuf_ + __ebs_); + else + this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_); + __cm_ = ios_base::in; + return true; + } + return false; +} + +template +void +basic_filebuf<_CharT, _Traits>::__write_mode() +{ + if (!(__cm_ & ios_base::out)) + { + this->setg(0, 0, 0); + if (__ebs_ > sizeof(__extbuf_min_)) + { + if (__always_noconv_) + this->setp((char_type*)__extbuf_, + (char_type*)__extbuf_ + (__ebs_ - 1)); + else + this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1)); + } + else + this->setp(0, 0); + __cm_ = ios_base::out; + } +} + +// basic_ifstream + +template +class _LIBCPP_TYPE_VIS_ONLY basic_ifstream + : public basic_istream<_CharT, _Traits> +{ +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + basic_ifstream(); +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in); + explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in); +#endif +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + basic_ifstream(basic_ifstream&& __rhs); +#endif + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + basic_ifstream& operator=(basic_ifstream&& __rhs); +#endif + void swap(basic_ifstream& __rhs); + + basic_filebuf* rdbuf() const; + bool is_open() const; +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + void open(const char* __s, ios_base::openmode __mode = ios_base::in); + void open(const string& __s, ios_base::openmode __mode = ios_base::in); +#endif + void close(); + +private: + basic_filebuf __sb_; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ifstream<_CharT, _Traits>::basic_ifstream() + : basic_istream(&__sb_) +{ +} + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode) + : basic_istream(&__sb_) +{ + if (__sb_.open(__s, __mode | ios_base::in) == 0) + this->setstate(ios_base::failbit); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode) + : basic_istream(&__sb_) +{ + if (__sb_.open(__s, __mode | ios_base::in) == 0) + this->setstate(ios_base::failbit); +} +#endif + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs) + : basic_istream(_VSTD::move(__rhs)), + __sb_(_VSTD::move(__rhs.__sb_)) +{ + this->set_rdbuf(&__sb_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ifstream<_CharT, _Traits>& +basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) +{ + basic_istream::operator=(_VSTD::move(__rhs)); + __sb_ = _VSTD::move(__rhs.__sb_); + return *this; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +void +basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs) +{ + basic_istream::swap(__rhs); + __sb_.swap(__rhs.__sb_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) +{ + __x.swap(__y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_filebuf<_CharT, _Traits>* +basic_ifstream<_CharT, _Traits>::rdbuf() const +{ + return const_cast*>(&__sb_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +basic_ifstream<_CharT, _Traits>::is_open() const +{ + return __sb_.is_open(); +} + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +template +void +basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode | ios_base::in)) + this->clear(); + else + this->setstate(ios_base::failbit); +} + +template +void +basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode | ios_base::in)) + this->clear(); + else + this->setstate(ios_base::failbit); +} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +void +basic_ifstream<_CharT, _Traits>::close() +{ + if (__sb_.close() == 0) + this->setstate(ios_base::failbit); +} + +// basic_ofstream + +template +class _LIBCPP_TYPE_VIS_ONLY basic_ofstream + : public basic_ostream<_CharT, _Traits> +{ +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + basic_ofstream(); + explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out); + explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + basic_ofstream(basic_ofstream&& __rhs); +#endif + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + basic_ofstream& operator=(basic_ofstream&& __rhs); +#endif + void swap(basic_ofstream& __rhs); + + basic_filebuf* rdbuf() const; + bool is_open() const; +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + void open(const char* __s, ios_base::openmode __mode = ios_base::out); + void open(const string& __s, ios_base::openmode __mode = ios_base::out); +#endif + void close(); + +private: + basic_filebuf __sb_; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ofstream<_CharT, _Traits>::basic_ofstream() + : basic_ostream(&__sb_) +{ +} + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode) + : basic_ostream(&__sb_) +{ + if (__sb_.open(__s, __mode | ios_base::out) == 0) + this->setstate(ios_base::failbit); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode) + : basic_ostream(&__sb_) +{ + if (__sb_.open(__s, __mode | ios_base::out) == 0) + this->setstate(ios_base::failbit); +} +#endif + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs) + : basic_ostream(_VSTD::move(__rhs)), + __sb_(_VSTD::move(__rhs.__sb_)) +{ + this->set_rdbuf(&__sb_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ofstream<_CharT, _Traits>& +basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) +{ + basic_ostream::operator=(_VSTD::move(__rhs)); + __sb_ = _VSTD::move(__rhs.__sb_); + return *this; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +void +basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs) +{ + basic_ostream::swap(__rhs); + __sb_.swap(__rhs.__sb_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) +{ + __x.swap(__y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_filebuf<_CharT, _Traits>* +basic_ofstream<_CharT, _Traits>::rdbuf() const +{ + return const_cast*>(&__sb_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +basic_ofstream<_CharT, _Traits>::is_open() const +{ + return __sb_.is_open(); +} + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +template +void +basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode | ios_base::out)) + this->clear(); + else + this->setstate(ios_base::failbit); +} + +template +void +basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode | ios_base::out)) + this->clear(); + else + this->setstate(ios_base::failbit); +} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +void +basic_ofstream<_CharT, _Traits>::close() +{ + if (__sb_.close() == 0) + this->setstate(ios_base::failbit); +} + +// basic_fstream + +template +class _LIBCPP_TYPE_VIS_ONLY basic_fstream + : public basic_iostream<_CharT, _Traits> +{ +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + basic_fstream(); +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); + explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); +#endif +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + basic_fstream(basic_fstream&& __rhs); +#endif + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + basic_fstream& operator=(basic_fstream&& __rhs); +#endif + void swap(basic_fstream& __rhs); + + basic_filebuf* rdbuf() const; + bool is_open() const; +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); + void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); +#endif + void close(); + +private: + basic_filebuf __sb_; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_fstream<_CharT, _Traits>::basic_fstream() + : basic_iostream(&__sb_) +{ +} + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +template +inline _LIBCPP_INLINE_VISIBILITY +basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode) + : basic_iostream(&__sb_) +{ + if (__sb_.open(__s, __mode) == 0) + this->setstate(ios_base::failbit); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode) + : basic_iostream(&__sb_) +{ + if (__sb_.open(__s, __mode) == 0) + this->setstate(ios_base::failbit); +} +#endif + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs) + : basic_iostream(_VSTD::move(__rhs)), + __sb_(_VSTD::move(__rhs.__sb_)) +{ + this->set_rdbuf(&__sb_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_fstream<_CharT, _Traits>& +basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) +{ + basic_iostream::operator=(_VSTD::move(__rhs)); + __sb_ = _VSTD::move(__rhs.__sb_); + return *this; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +void +basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs) +{ + basic_iostream::swap(__rhs); + __sb_.swap(__rhs.__sb_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) +{ + __x.swap(__y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_filebuf<_CharT, _Traits>* +basic_fstream<_CharT, _Traits>::rdbuf() const +{ + return const_cast*>(&__sb_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +basic_fstream<_CharT, _Traits>::is_open() const +{ + return __sb_.is_open(); +} + +#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +template +void +basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode)) + this->clear(); + else + this->setstate(ios_base::failbit); +} + +template +void +basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode)) + this->clear(); + else + this->setstate(ios_base::failbit); +} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +void +basic_fstream<_CharT, _Traits>::close() +{ + if (__sb_.close() == 0) + this->setstate(ios_base::failbit); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_FSTREAM diff --git a/headers/libs/libc++/functional b/headers/libs/libc++/functional new file mode 100644 index 0000000000..dbe9b01bbd --- /dev/null +++ b/headers/libs/libc++/functional @@ -0,0 +1,2578 @@ +// -*- C++ -*- +//===------------------------ functional ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_FUNCTIONAL +#define _LIBCPP_FUNCTIONAL + +/* + functional synopsis + +namespace std +{ + +template +struct unary_function +{ + typedef Arg argument_type; + typedef Result result_type; +}; + +template +struct binary_function +{ + typedef Arg1 first_argument_type; + typedef Arg2 second_argument_type; + typedef Result result_type; +}; + +template +class reference_wrapper + : public unary_function // if wrapping a unary functor + : public binary_function // if wraping a binary functor +{ +public: + // types + typedef T type; + typedef see below result_type; // Not always defined + + // construct/copy/destroy + reference_wrapper(T&) noexcept; + reference_wrapper(T&&) = delete; // do not bind to temps + reference_wrapper(const reference_wrapper& x) noexcept; + + // assignment + reference_wrapper& operator=(const reference_wrapper& x) noexcept; + + // access + operator T& () const noexcept; + T& get() const noexcept; + + // invoke + template + typename result_of::type + operator() (ArgTypes&&...) const; +}; + +template reference_wrapper ref(T& t) noexcept; +template void ref(const T&& t) = delete; +template reference_wrapper ref(reference_wrappert) noexcept; + +template reference_wrapper cref(const T& t) noexcept; +template void cref(const T&& t) = delete; +template reference_wrapper cref(reference_wrapper t) noexcept; + +template // in C++14 +struct plus : binary_function +{ + T operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct minus : binary_function +{ + T operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct multiplies : binary_function +{ + T operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct divides : binary_function +{ + T operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct modulus : binary_function +{ + T operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct negate : unary_function +{ + T operator()(const T& x) const; +}; + +template // in C++14 +struct equal_to : binary_function +{ + bool operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct not_equal_to : binary_function +{ + bool operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct greater : binary_function +{ + bool operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct less : binary_function +{ + bool operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct greater_equal : binary_function +{ + bool operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct less_equal : binary_function +{ + bool operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct logical_and : binary_function +{ + bool operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct logical_or : binary_function +{ + bool operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct logical_not : unary_function +{ + bool operator()(const T& x) const; +}; + +template // in C++14 +struct bit_and : unary_function +{ + bool operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct bit_or : unary_function +{ + bool operator()(const T& x, const T& y) const; +}; + +template // in C++14 +struct bit_xor : unary_function +{ + bool operator()(const T& x, const T& y) const; +}; + +template // C++14 +struct bit_xor : unary_function +{ + bool operator()(const T& x) const; +}; + +template +class unary_negate + : public unary_function +{ +public: + explicit unary_negate(const Predicate& pred); + bool operator()(const typename Predicate::argument_type& x) const; +}; + +template unary_negate not1(const Predicate& pred); + +template +class binary_negate + : public binary_function +{ +public: + explicit binary_negate(const Predicate& pred); + bool operator()(const typename Predicate::first_argument_type& x, + const typename Predicate::second_argument_type& y) const; +}; + +template binary_negate not2(const Predicate& pred); + +template struct is_bind_expression; +template struct is_placeholder; + +template + unspecified bind(Fn&&, BoundArgs&&...); +template + unspecified bind(Fn&&, BoundArgs&&...); + +namespace placeholders { + // M is the implementation-defined number of placeholders + extern unspecified _1; + extern unspecified _2; + . + . + . + extern unspecified _Mp; +} + +template +class binder1st + : public unary_function +{ +protected: + Operation op; + typename Operation::first_argument_type value; +public: + binder1st(const Operation& x, const typename Operation::first_argument_type y); + typename Operation::result_type operator()( typename Operation::second_argument_type& x) const; + typename Operation::result_type operator()(const typename Operation::second_argument_type& x) const; +}; + +template +binder1st bind1st(const Operation& op, const T& x); + +template +class binder2nd + : public unary_function +{ +protected: + Operation op; + typename Operation::second_argument_type value; +public: + binder2nd(const Operation& x, const typename Operation::second_argument_type y); + typename Operation::result_type operator()( typename Operation::first_argument_type& x) const; + typename Operation::result_type operator()(const typename Operation::first_argument_type& x) const; +}; + +template +binder2nd bind2nd(const Operation& op, const T& x); + +template +class pointer_to_unary_function : public unary_function +{ +public: + explicit pointer_to_unary_function(Result (*f)(Arg)); + Result operator()(Arg x) const; +}; + +template +pointer_to_unary_function ptr_fun(Result (*f)(Arg)); + +template +class pointer_to_binary_function : public binary_function +{ +public: + explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2)); + Result operator()(Arg1 x, Arg2 y) const; +}; + +template +pointer_to_binary_function ptr_fun(Result (*f)(Arg1,Arg2)); + +template +class mem_fun_t : public unary_function +{ +public: + explicit mem_fun_t(S (T::*p)()); + S operator()(T* p) const; +}; + +template +class mem_fun1_t : public binary_function +{ +public: + explicit mem_fun1_t(S (T::*p)(A)); + S operator()(T* p, A x) const; +}; + +template mem_fun_t mem_fun(S (T::*f)()); +template mem_fun1_t mem_fun(S (T::*f)(A)); + +template +class mem_fun_ref_t : public unary_function +{ +public: + explicit mem_fun_ref_t(S (T::*p)()); + S operator()(T& p) const; +}; + +template +class mem_fun1_ref_t : public binary_function +{ +public: + explicit mem_fun1_ref_t(S (T::*p)(A)); + S operator()(T& p, A x) const; +}; + +template mem_fun_ref_t mem_fun_ref(S (T::*f)()); +template mem_fun1_ref_t mem_fun_ref(S (T::*f)(A)); + +template +class const_mem_fun_t : public unary_function +{ +public: + explicit const_mem_fun_t(S (T::*p)() const); + S operator()(const T* p) const; +}; + +template +class const_mem_fun1_t : public binary_function +{ +public: + explicit const_mem_fun1_t(S (T::*p)(A) const); + S operator()(const T* p, A x) const; +}; + +template const_mem_fun_t mem_fun(S (T::*f)() const); +template const_mem_fun1_t mem_fun(S (T::*f)(A) const); + +template +class const_mem_fun_ref_t : public unary_function +{ +public: + explicit const_mem_fun_ref_t(S (T::*p)() const); + S operator()(const T& p) const; +}; + +template +class const_mem_fun1_ref_t : public binary_function +{ +public: + explicit const_mem_fun1_ref_t(S (T::*p)(A) const); + S operator()(const T& p, A x) const; +}; + +template const_mem_fun_ref_t mem_fun_ref(S (T::*f)() const); +template const_mem_fun1_ref_t mem_fun_ref(S (T::*f)(A) const); + +template unspecified mem_fn(R T::*); + +class bad_function_call + : public exception +{ +}; + +template class function; // undefined + +template +class function + : public unary_function // iff sizeof...(ArgTypes) == 1 and + // ArgTypes contains T1 + : public binary_function // iff sizeof...(ArgTypes) == 2 and + // ArgTypes contains T1 and T2 +{ +public: + typedef R result_type; + + // construct/copy/destroy: + function() noexcept; + function(nullptr_t) noexcept; + function(const function&); + function(function&&) noexcept; + template + function(F); + template + function(allocator_arg_t, const Alloc&) noexcept; + template + function(allocator_arg_t, const Alloc&, nullptr_t) noexcept; + template + function(allocator_arg_t, const Alloc&, const function&); + template + function(allocator_arg_t, const Alloc&, function&&); + template + function(allocator_arg_t, const Alloc&, F); + + function& operator=(const function&); + function& operator=(function&&) noexcept; + function& operator=(nullptr_t) noexcept; + template + function& operator=(F&&); + template + function& operator=(reference_wrapper) noexcept; + + ~function(); + + // function modifiers: + void swap(function&) noexcept; + template + void assign(F&&, const Alloc&); + + // function capacity: + explicit operator bool() const noexcept; + + // function invocation: + R operator()(ArgTypes...) const; + + // function target access: + const std::type_info& target_type() const noexcept; + template T* target() noexcept; + template const T* target() const noexcept; +}; + +// Null pointer comparisons: +template + bool operator==(const function&, nullptr_t) noexcept; + +template + bool operator==(nullptr_t, const function&) noexcept; + +template + bool operator!=(const function&, nullptr_t) noexcept; + +template + bool operator!=(nullptr_t, const function&) noexcept; + +// specialized algorithms: +template + void swap(function&, function&) noexcept; + +template struct hash; + +template <> struct hash; +template <> struct hash; +template <> struct hash; +template <> struct hash; +template <> struct hash; +template <> struct hash; +template <> struct hash; +template <> struct hash; +template <> struct hash; +template <> struct hash; +template <> struct hash; +template <> struct hash; +template <> struct hash; +template <> struct hash; +template <> struct hash; + +template <> struct hash; +template <> struct hash; +template <> struct hash; + +template struct hash; + +} // std + +POLICY: For non-variadic implementations, the number of arguments is limited + to 3. It is hoped that the need for non-variadic implementations + will be minimal. + +*/ + +#include <__config> +#include +#include +#include +#include +#include + +#include <__functional_base> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY plus : binary_function<_Tp, _Tp, _Tp> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x + __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY plus +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY minus : binary_function<_Tp, _Tp, _Tp> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x - __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY minus +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY multiplies : binary_function<_Tp, _Tp, _Tp> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x * __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY multiplies +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY divides : binary_function<_Tp, _Tp, _Tp> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x / __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY divides +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY modulus : binary_function<_Tp, _Tp, _Tp> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x % __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY modulus +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY negate : unary_function<_Tp, _Tp> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return -__x;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY negate +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_Tp&& __x) const + _NOEXCEPT_(noexcept(- _VSTD::forward<_Tp>(__x))) + -> decltype (- _VSTD::forward<_Tp>(__x)) + { return - _VSTD::forward<_Tp>(__x); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY equal_to : binary_function<_Tp, _Tp, bool> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x == __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY equal_to +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY not_equal_to : binary_function<_Tp, _Tp, bool> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x != __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY not_equal_to +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY greater : binary_function<_Tp, _Tp, bool> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x > __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY greater +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +// less in <__functional_base> + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY greater_equal : binary_function<_Tp, _Tp, bool> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x >= __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY greater_equal +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY less_equal : binary_function<_Tp, _Tp, bool> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x <= __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY less_equal +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY logical_and : binary_function<_Tp, _Tp, bool> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x && __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY logical_and +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY logical_or : binary_function<_Tp, _Tp, bool> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x || __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY logical_or +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY logical_not : unary_function<_Tp, bool> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x) const + {return !__x;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY logical_not +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_Tp&& __x) const + _NOEXCEPT_(noexcept(!_VSTD::forward<_Tp>(__x))) + -> decltype (!_VSTD::forward<_Tp>(__x)) + { return !_VSTD::forward<_Tp>(__x); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY bit_and : binary_function<_Tp, _Tp, _Tp> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x & __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY bit_and +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY bit_or : binary_function<_Tp, _Tp, _Tp> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x | __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY bit_or +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TYPE_VIS_ONLY bit_xor : binary_function<_Tp, _Tp, _Tp> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x, const _Tp& __y) const + {return __x ^ __y;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TYPE_VIS_ONLY bit_xor +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u))) + -> decltype (_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + + +#if _LIBCPP_STD_VER > 11 +template +struct _LIBCPP_TYPE_VIS_ONLY bit_not : unary_function<_Tp, _Tp> +{ + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _Tp operator()(const _Tp& __x) const + {return ~__x;} +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY bit_not +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_Tp&& __x) const + _NOEXCEPT_(noexcept(~_VSTD::forward<_Tp>(__x))) + -> decltype (~_VSTD::forward<_Tp>(__x)) + { return ~_VSTD::forward<_Tp>(__x); } + typedef void is_transparent; +}; +#endif + +template +class _LIBCPP_TYPE_VIS_ONLY unary_negate + : public unary_function +{ + _Predicate __pred_; +public: + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + explicit unary_negate(const _Predicate& __pred) + : __pred_(__pred) {} + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator()(const typename _Predicate::argument_type& __x) const + {return !__pred_(__x);} +}; + +template +inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +unary_negate<_Predicate> +not1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);} + +template +class _LIBCPP_TYPE_VIS_ONLY binary_negate + : public binary_function +{ + _Predicate __pred_; +public: + _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11 + binary_negate(const _Predicate& __pred) : __pred_(__pred) {} + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + {return !__pred_(__x, __y);} +}; + +template +inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +binary_negate<_Predicate> +not2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);} + +template +class _LIBCPP_TYPE_VIS_ONLY binder1st + : public unary_function +{ +protected: + __Operation op; + typename __Operation::first_argument_type value; +public: + _LIBCPP_INLINE_VISIBILITY binder1st(const __Operation& __x, + const typename __Operation::first_argument_type __y) + : op(__x), value(__y) {} + _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() + (typename __Operation::second_argument_type& __x) const + {return op(value, __x);} + _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() + (const typename __Operation::second_argument_type& __x) const + {return op(value, __x);} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +binder1st<__Operation> +bind1st(const __Operation& __op, const _Tp& __x) + {return binder1st<__Operation>(__op, __x);} + +template +class _LIBCPP_TYPE_VIS_ONLY binder2nd + : public unary_function +{ +protected: + __Operation op; + typename __Operation::second_argument_type value; +public: + _LIBCPP_INLINE_VISIBILITY + binder2nd(const __Operation& __x, const typename __Operation::second_argument_type __y) + : op(__x), value(__y) {} + _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() + ( typename __Operation::first_argument_type& __x) const + {return op(__x, value);} + _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() + (const typename __Operation::first_argument_type& __x) const + {return op(__x, value);} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +binder2nd<__Operation> +bind2nd(const __Operation& __op, const _Tp& __x) + {return binder2nd<__Operation>(__op, __x);} + +template +class _LIBCPP_TYPE_VIS_ONLY pointer_to_unary_function + : public unary_function<_Arg, _Result> +{ + _Result (*__f_)(_Arg); +public: + _LIBCPP_INLINE_VISIBILITY explicit pointer_to_unary_function(_Result (*__f)(_Arg)) + : __f_(__f) {} + _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg __x) const + {return __f_(__x);} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +pointer_to_unary_function<_Arg,_Result> +ptr_fun(_Result (*__f)(_Arg)) + {return pointer_to_unary_function<_Arg,_Result>(__f);} + +template +class _LIBCPP_TYPE_VIS_ONLY pointer_to_binary_function + : public binary_function<_Arg1, _Arg2, _Result> +{ + _Result (*__f_)(_Arg1, _Arg2); +public: + _LIBCPP_INLINE_VISIBILITY explicit pointer_to_binary_function(_Result (*__f)(_Arg1, _Arg2)) + : __f_(__f) {} + _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg1 __x, _Arg2 __y) const + {return __f_(__x, __y);} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +pointer_to_binary_function<_Arg1,_Arg2,_Result> +ptr_fun(_Result (*__f)(_Arg1,_Arg2)) + {return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__f);} + +template +class _LIBCPP_TYPE_VIS_ONLY mem_fun_t : public unary_function<_Tp*, _Sp> +{ + _Sp (_Tp::*__p_)(); +public: + _LIBCPP_INLINE_VISIBILITY explicit mem_fun_t(_Sp (_Tp::*__p)()) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p) const + {return (__p->*__p_)();} +}; + +template +class _LIBCPP_TYPE_VIS_ONLY mem_fun1_t : public binary_function<_Tp*, _Ap, _Sp> +{ + _Sp (_Tp::*__p_)(_Ap); +public: + _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_t(_Sp (_Tp::*__p)(_Ap)) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p, _Ap __x) const + {return (__p->*__p_)(__x);} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +mem_fun_t<_Sp,_Tp> +mem_fun(_Sp (_Tp::*__f)()) + {return mem_fun_t<_Sp,_Tp>(__f);} + +template +inline _LIBCPP_INLINE_VISIBILITY +mem_fun1_t<_Sp,_Tp,_Ap> +mem_fun(_Sp (_Tp::*__f)(_Ap)) + {return mem_fun1_t<_Sp,_Tp,_Ap>(__f);} + +template +class _LIBCPP_TYPE_VIS_ONLY mem_fun_ref_t : public unary_function<_Tp, _Sp> +{ + _Sp (_Tp::*__p_)(); +public: + _LIBCPP_INLINE_VISIBILITY explicit mem_fun_ref_t(_Sp (_Tp::*__p)()) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p) const + {return (__p.*__p_)();} +}; + +template +class _LIBCPP_TYPE_VIS_ONLY mem_fun1_ref_t : public binary_function<_Tp, _Ap, _Sp> +{ + _Sp (_Tp::*__p_)(_Ap); +public: + _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap)) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p, _Ap __x) const + {return (__p.*__p_)(__x);} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +mem_fun_ref_t<_Sp,_Tp> +mem_fun_ref(_Sp (_Tp::*__f)()) + {return mem_fun_ref_t<_Sp,_Tp>(__f);} + +template +inline _LIBCPP_INLINE_VISIBILITY +mem_fun1_ref_t<_Sp,_Tp,_Ap> +mem_fun_ref(_Sp (_Tp::*__f)(_Ap)) + {return mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);} + +template +class _LIBCPP_TYPE_VIS_ONLY const_mem_fun_t : public unary_function +{ + _Sp (_Tp::*__p_)() const; +public: + _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_t(_Sp (_Tp::*__p)() const) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p) const + {return (__p->*__p_)();} +}; + +template +class _LIBCPP_TYPE_VIS_ONLY const_mem_fun1_t : public binary_function +{ + _Sp (_Tp::*__p_)(_Ap) const; +public: + _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_t(_Sp (_Tp::*__p)(_Ap) const) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p, _Ap __x) const + {return (__p->*__p_)(__x);} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +const_mem_fun_t<_Sp,_Tp> +mem_fun(_Sp (_Tp::*__f)() const) + {return const_mem_fun_t<_Sp,_Tp>(__f);} + +template +inline _LIBCPP_INLINE_VISIBILITY +const_mem_fun1_t<_Sp,_Tp,_Ap> +mem_fun(_Sp (_Tp::*__f)(_Ap) const) + {return const_mem_fun1_t<_Sp,_Tp,_Ap>(__f);} + +template +class _LIBCPP_TYPE_VIS_ONLY const_mem_fun_ref_t : public unary_function<_Tp, _Sp> +{ + _Sp (_Tp::*__p_)() const; +public: + _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_ref_t(_Sp (_Tp::*__p)() const) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p) const + {return (__p.*__p_)();} +}; + +template +class _LIBCPP_TYPE_VIS_ONLY const_mem_fun1_ref_t + : public binary_function<_Tp, _Ap, _Sp> +{ + _Sp (_Tp::*__p_)(_Ap) const; +public: + _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap) const) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p, _Ap __x) const + {return (__p.*__p_)(__x);} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +const_mem_fun_ref_t<_Sp,_Tp> +mem_fun_ref(_Sp (_Tp::*__f)() const) + {return const_mem_fun_ref_t<_Sp,_Tp>(__f);} + +template +inline _LIBCPP_INLINE_VISIBILITY +const_mem_fun1_ref_t<_Sp,_Tp,_Ap> +mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const) + {return const_mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);} + +//////////////////////////////////////////////////////////////////////////////// +// MEMFUN +//============================================================================== + +template +class __mem_fn + : public __weak_result_type<_Tp> +{ +public: + // types + typedef _Tp type; +private: + type __f_; + +public: + _LIBCPP_INLINE_VISIBILITY __mem_fn(type __f) _NOEXCEPT : __f_(__f) {} + +#ifndef _LIBCPP_HAS_NO_VARIADICS + // invoke + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return::type + operator() (_ArgTypes&&... __args) const { + return __invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...); + } +#else + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return0::type + operator() (_A0& __a0) const { + return __invoke(__f_, __a0); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return0::type + operator() (_A0 const& __a0) const { + return __invoke(__f_, __a0); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0& __a0, _A1& __a1) const { + return __invoke(__f_, __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0 const& __a0, _A1& __a1) const { + return __invoke(__f_, __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0& __a0, _A1 const& __a1) const { + return __invoke(__f_, __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0 const& __a0, _A1 const& __a1) const { + return __invoke(__f_, __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1& __a1, _A2& __a2) const { + return __invoke(__f_, __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const { + return __invoke(__f_, __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const { + return __invoke(__f_, __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const { + return __invoke(__f_, __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const { + return __invoke(__f_, __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const { + return __invoke(__f_, __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const { + return __invoke(__f_, __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const { + return __invoke(__f_, __a0, __a1, __a2); + } +#endif +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +__mem_fn<_Rp _Tp::*> +mem_fn(_Rp _Tp::* __pm) _NOEXCEPT +{ + return __mem_fn<_Rp _Tp::*>(__pm); +} + +//////////////////////////////////////////////////////////////////////////////// +// FUNCTION +//============================================================================== + +// bad_function_call + +class _LIBCPP_EXCEPTION_ABI bad_function_call + : public exception +{ +}; + +template class _LIBCPP_TYPE_VIS_ONLY function; // undefined + +namespace __function +{ + +template +struct __maybe_derive_from_unary_function +{ +}; + +template +struct __maybe_derive_from_unary_function<_Rp(_A1)> + : public unary_function<_A1, _Rp> +{ +}; + +template +struct __maybe_derive_from_binary_function +{ +}; + +template +struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> + : public binary_function<_A1, _A2, _Rp> +{ +}; + +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Fp const&) { return true; } + +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Fp* __ptr) { return __ptr; } + +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Ret _Class::*__ptr) { return __ptr; } + +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(function<_Fp> const& __f) { return !!__f; } + +} // namespace __function + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +namespace __function { + +template class __base; + +template +class __base<_Rp(_ArgTypes...)> +{ + __base(const __base&); + __base& operator=(const __base&); +public: + _LIBCPP_INLINE_VISIBILITY __base() {} + _LIBCPP_INLINE_VISIBILITY virtual ~__base() {} + virtual __base* __clone() const = 0; + virtual void __clone(__base*) const = 0; + virtual void destroy() _NOEXCEPT = 0; + virtual void destroy_deallocate() _NOEXCEPT = 0; + virtual _Rp operator()(_ArgTypes&& ...) = 0; +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const _NOEXCEPT = 0; + virtual const std::type_info& target_type() const _NOEXCEPT = 0; +#endif // _LIBCPP_NO_RTTI +}; + +template class __func; + +template +class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> + : public __base<_Rp(_ArgTypes...)> +{ + __compressed_pair<_Fp, _Alloc> __f_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __func(_Fp&& __f) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), + _VSTD::forward_as_tuple()) {} + _LIBCPP_INLINE_VISIBILITY + explicit __func(const _Fp& __f, const _Alloc& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), + _VSTD::forward_as_tuple(__a)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __func(const _Fp& __f, _Alloc&& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), + _VSTD::forward_as_tuple(_VSTD::move(__a))) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __func(_Fp&& __f, _Alloc&& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), + _VSTD::forward_as_tuple(_VSTD::move(__a))) {} + virtual __base<_Rp(_ArgTypes...)>* __clone() const; + virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; + virtual void destroy() _NOEXCEPT; + virtual void destroy_deallocate() _NOEXCEPT; + virtual _Rp operator()(_ArgTypes&& ... __arg); +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const _NOEXCEPT; + virtual const std::type_info& target_type() const _NOEXCEPT; +#endif // _LIBCPP_NO_RTTI +}; + +template +__base<_Rp(_ArgTypes...)>* +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); + return __hold.release(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const +{ + ::new (__p) __func(__f_.first(), __f_.second()); +} + +template +void +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT +{ + __f_.~__compressed_pair<_Fp, _Alloc>(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + __f_.~__compressed_pair<_Fp, _Alloc>(); + __a.deallocate(this, 1); +} + +template +_Rp +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) +{ + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const void* +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT +{ + if (__ti == typeid(_Fp)) + return &__f_.first(); + return (const void*)0; +} + +template +const std::type_info& +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT +{ + return typeid(_Fp); +} + +#endif // _LIBCPP_NO_RTTI + +} // __function + +template +class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_ArgTypes...)> + : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, + public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> +{ + typedef __function::__base<_Rp(_ArgTypes...)> __base; + typename aligned_storage<3*sizeof(void*)>::type __buf_; + __base* __f_; + + template ::value && + __invokable<_Fp&, _ArgTypes...>::value> + struct __callable; + template + struct __callable<_Fp, true> + { + static const bool value = is_same::value || + is_convertible::type, + _Rp>::value; + }; + template + struct __callable<_Fp, false> + { + static const bool value = false; + }; +public: + typedef _Rp result_type; + + // construct/copy/destroy: + _LIBCPP_INLINE_VISIBILITY + function() _NOEXCEPT : __f_(0) {} + _LIBCPP_INLINE_VISIBILITY + function(nullptr_t) _NOEXCEPT : __f_(0) {} + function(const function&); + function(function&&) _NOEXCEPT; + template + function(_Fp, typename enable_if + < + __callable<_Fp>::value && + !is_same<_Fp, function>::value + >::type* = 0); + + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&) _NOEXCEPT : __f_(0) {} + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT : __f_(0) {} + template + function(allocator_arg_t, const _Alloc&, const function&); + template + function(allocator_arg_t, const _Alloc&, function&&); + template + function(allocator_arg_t, const _Alloc& __a, _Fp __f, + typename enable_if<__callable<_Fp>::value>::type* = 0); + + function& operator=(const function&); + function& operator=(function&&) _NOEXCEPT; + function& operator=(nullptr_t) _NOEXCEPT; + template + typename enable_if + < + __callable::type>::value && + !is_same::type, function>::value, + function& + >::type + operator=(_Fp&&); + + ~function(); + + // function modifiers: + void swap(function&) _NOEXCEPT; + template + _LIBCPP_INLINE_VISIBILITY + void assign(_Fp&& __f, const _Alloc& __a) + {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);} + + // function capacity: + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return __f_;} + + // deleted overloads close possible hole in the type system + template + bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; + template + bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; +public: + // function invocation: + _Rp operator()(_ArgTypes...) const; + +#ifndef _LIBCPP_NO_RTTI + // function target access: + const std::type_info& target_type() const _NOEXCEPT; + template _Tp* target() _NOEXCEPT; + template const _Tp* target() const _NOEXCEPT; +#endif // _LIBCPP_NO_RTTI +}; + +template +function<_Rp(_ArgTypes...)>::function(const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, + const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + { + __f_ = __f.__f_; + __f.__f_ = 0; + } +} + +template +template +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, + function&& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + { + __f_ = __f.__f_; + __f.__f_ = 0; + } +} + +template +template +function<_Rp(_ArgTypes...)>::function(_Fp __f, + typename enable_if + < + __callable<_Fp>::value && + !is_same<_Fp, function>::value + >::type*) + : __f_(0) +{ + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_ArgTypes...)> _FF; + if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value) + { + __f_ = (__base*)&__buf_; + ::new (__f_) _FF(_VSTD::move(__f)); + } + else + { + typedef allocator<_FF> _Ap; + _Ap __a; + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) _FF(_VSTD::move(__f), allocator<_Fp>(__a)); + __f_ = __hold.release(); + } + } +} + +template +template +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, + typename enable_if<__callable<_Fp>::value>::type*) + : __f_(0) +{ + typedef allocator_traits<_Alloc> __alloc_traits; + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF; + typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; + _Ap __a(__a0); + if (sizeof(_FF) <= sizeof(__buf_) && + is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value) + { + __f_ = (__base*)&__buf_; + ::new (__f_) _FF(_VSTD::move(__f), _Alloc(__a)); + } + else + { + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) _FF(_VSTD::move(__f), _Alloc(__a)); + __f_ = __hold.release(); + } + } +} + +template +function<_Rp(_ArgTypes...)>& +function<_Rp(_ArgTypes...)>::operator=(const function& __f) +{ + function(__f).swap(*this); + return *this; +} + +template +function<_Rp(_ArgTypes...)>& +function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); + __f_ = 0; + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + { + __f_ = __f.__f_; + __f.__f_ = 0; + } + return *this; +} + +template +function<_Rp(_ArgTypes...)>& +function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); + __f_ = 0; + return *this; +} + +template +template +typename enable_if +< + function<_Rp(_ArgTypes...)>::template __callable::type>::value && + !is_same::type, function<_Rp(_ArgTypes...)>>::value, + function<_Rp(_ArgTypes...)>& +>::type +function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) +{ + function(_VSTD::forward<_Fp>(__f)).swap(*this); + return *this; +} + +template +function<_Rp(_ArgTypes...)>::~function() +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); +} + +template +void +function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT +{ + if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) + { + typename aligned_storage::type __tempbuf; + __base* __t = (__base*)&__tempbuf; + __f_->__clone(__t); + __f_->destroy(); + __f_ = 0; + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = 0; + __f_ = (__base*)&__buf_; + __t->__clone((__base*)&__f.__buf_); + __t->destroy(); + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f_ == (__base*)&__buf_) + { + __f_->__clone((__base*)&__f.__buf_); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = (__base*)&__buf_; + } + else + _VSTD::swap(__f_, __f.__f_); +} + +template +_Rp +function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + if (__f_ == 0) + throw bad_function_call(); +#endif // _LIBCPP_NO_EXCEPTIONS + return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const std::type_info& +function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT +{ + if (__f_ == 0) + return typeid(void); + return __f_->target_type(); +} + +template +template +_Tp* +function<_Rp(_ArgTypes...)>::target() _NOEXCEPT +{ + if (__f_ == 0) + return (_Tp*)0; + return (_Tp*)__f_->target(typeid(_Tp)); +} + +template +template +const _Tp* +function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT +{ + if (__f_ == 0) + return (const _Tp*)0; + return (const _Tp*)__f_->target(typeid(_Tp)); +} + +#endif // _LIBCPP_NO_RTTI + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT +{return __x.swap(__y);} + +#else // _LIBCPP_HAS_NO_VARIADICS + +#include <__functional_03> + +#endif + +//////////////////////////////////////////////////////////////////////////////// +// BIND +//============================================================================== + +template struct __is_bind_expression : public false_type {}; +template struct _LIBCPP_TYPE_VIS_ONLY is_bind_expression + : public __is_bind_expression::type> {}; + +template struct __is_placeholder : public integral_constant {}; +template struct _LIBCPP_TYPE_VIS_ONLY is_placeholder + : public __is_placeholder::type> {}; + +namespace placeholders +{ + +template struct __ph {}; + +_LIBCPP_FUNC_VIS extern __ph<1> _1; +_LIBCPP_FUNC_VIS extern __ph<2> _2; +_LIBCPP_FUNC_VIS extern __ph<3> _3; +_LIBCPP_FUNC_VIS extern __ph<4> _4; +_LIBCPP_FUNC_VIS extern __ph<5> _5; +_LIBCPP_FUNC_VIS extern __ph<6> _6; +_LIBCPP_FUNC_VIS extern __ph<7> _7; +_LIBCPP_FUNC_VIS extern __ph<8> _8; +_LIBCPP_FUNC_VIS extern __ph<9> _9; +_LIBCPP_FUNC_VIS extern __ph<10> _10; + +} // placeholders + +template +struct __is_placeholder > + : public integral_constant {}; + + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp& +__mu(reference_wrapper<_Tp> __t, _Uj&) +{ + return __t.get(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __invoke_of<_Ti&, _Uj...>::type +__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>) +{ + return __ti(_VSTD::forward<_Uj>(_VSTD::get<_Indx>(__uj))...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __lazy_enable_if +< + is_bind_expression<_Ti>::value, + __invoke_of<_Ti&, _Uj...> +>::type +__mu(_Ti& __ti, tuple<_Uj...>& __uj) +{ + typedef typename __make_tuple_indices::type __indices; + return __mu_expand(__ti, __uj, __indices()); +} + +template +struct __mu_return2 {}; + +template +struct __mu_return2 +{ + typedef typename tuple_element::value - 1, _Uj>::type type; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + 0 < is_placeholder<_Ti>::value, + typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type +>::type +__mu(_Ti&, _Uj& __uj) +{ + const size_t _Indx = is_placeholder<_Ti>::value - 1; + return _VSTD::forward::type>(_VSTD::get<_Indx>(__uj)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + !is_bind_expression<_Ti>::value && + is_placeholder<_Ti>::value == 0 && + !__is_reference_wrapper<_Ti>::value, + _Ti& +>::type +__mu(_Ti& __ti, _Uj&) +{ + return __ti; +} + +template +struct ____mu_return; + +template +struct ____mu_return_invokable // false +{ + typedef __nat type; +}; + +template +struct ____mu_return_invokable +{ + typedef typename __invoke_of<_Ti&, _Uj...>::type type; +}; + +template +struct ____mu_return<_Ti, false, true, false, tuple<_Uj...> > + : public ____mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...> +{ +}; + +template +struct ____mu_return<_Ti, false, false, true, _TupleUj> +{ + typedef typename tuple_element::value - 1, + _TupleUj>::type&& type; +}; + +template +struct ____mu_return<_Ti, true, false, false, _TupleUj> +{ + typedef typename _Ti::type& type; +}; + +template +struct ____mu_return<_Ti, false, false, false, _TupleUj> +{ + typedef _Ti& type; +}; + +template +struct __mu_return + : public ____mu_return<_Ti, + __is_reference_wrapper<_Ti>::value, + is_bind_expression<_Ti>::value, + 0 < is_placeholder<_Ti>::value && + is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value, + _TupleUj> +{ +}; + +template +struct __is_valid_bind_return +{ + static const bool value = false; +}; + +template +struct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj> +{ + static const bool value = __invokable<_Fp, + typename __mu_return<_BoundArgs, _TupleUj>::type...>::value; +}; + +template +struct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj> +{ + static const bool value = __invokable<_Fp, + typename __mu_return::type...>::value; +}; + +template ::value> +struct __bind_return; + +template +struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true> +{ + typedef typename __invoke_of + < + _Fp&, + typename __mu_return + < + _BoundArgs, + _TupleUj + >::type... + >::type type; +}; + +template +struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true> +{ + typedef typename __invoke_of + < + _Fp&, + typename __mu_return + < + const _BoundArgs, + _TupleUj + >::type... + >::type type; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __bind_return<_Fp, _BoundArgs, _Args>::type +__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>, + _Args&& __args) +{ + return __invoke(__f, __mu(_VSTD::get<_Indx>(__bound_args), __args)...); +} + +template +class __bind + : public __weak_result_type::type> +{ +protected: + typedef typename decay<_Fp>::type _Fd; + typedef tuple::type...> _Td; +private: + _Fd __f_; + _Td __bound_args_; + + typedef typename __make_tuple_indices::type __indices; +public: +#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS + + _LIBCPP_INLINE_VISIBILITY + __bind(const __bind& __b) + : __f_(__b.__f_), + __bound_args_(__b.__bound_args_) {} + + _LIBCPP_INLINE_VISIBILITY + __bind& operator=(const __bind& __b) + { + __f_ = __b.__f_; + __bound_args_ = __b.__bound_args_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __bind(__bind&& __b) + : __f_(_VSTD::move(__b.__f_)), + __bound_args_(_VSTD::move(__b.__bound_args_)) {} + + _LIBCPP_INLINE_VISIBILITY + __bind& operator=(__bind&& __b) + { + __f_ = _VSTD::move(__b.__f_); + __bound_args_ = _VSTD::move(__b.__bound_args_); + return *this; + } + +#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS + + template ::value && + !is_same::type, + __bind>::value + >::type> + _LIBCPP_INLINE_VISIBILITY + explicit __bind(_Gp&& __f, _BA&& ...__bound_args) + : __f_(_VSTD::forward<_Gp>(__f)), + __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {} + + template + _LIBCPP_INLINE_VISIBILITY + typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type + operator()(_Args&& ...__args) + { + return __apply_functor(__f_, __bound_args_, __indices(), + tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...)); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __bind_return >::type + operator()(_Args&& ...__args) const + { + return __apply_functor(__f_, __bound_args_, __indices(), + tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...)); + } +}; + +template +struct __is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {}; + +template +class __bind_r + : public __bind<_Fp, _BoundArgs...> +{ + typedef __bind<_Fp, _BoundArgs...> base; + typedef typename base::_Fd _Fd; + typedef typename base::_Td _Td; +public: + typedef _Rp result_type; + +#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS + + _LIBCPP_INLINE_VISIBILITY + __bind_r(const __bind_r& __b) + : base(_VSTD::forward(__b)) {} + + _LIBCPP_INLINE_VISIBILITY + __bind_r& operator=(const __bind_r& __b) + { + base::operator=(_VSTD::forward(__b)); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __bind_r(__bind_r&& __b) + : base(_VSTD::forward(__b)) {} + + _LIBCPP_INLINE_VISIBILITY + __bind_r& operator=(__bind_r&& __b) + { + base::operator=(_VSTD::forward(__b)); + return *this; + } + +#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS + + template ::value && + !is_same::type, + __bind_r>::value + >::type> + _LIBCPP_INLINE_VISIBILITY + explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args) + : base(_VSTD::forward<_Gp>(__f), + _VSTD::forward<_BA>(__bound_args)...) {} + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + is_convertible >::type, + result_type>::value || is_void<_Rp>::value, + result_type + >::type + operator()(_Args&& ...__args) + { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(static_cast(*this), _VSTD::forward<_Args>(__args)...); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + is_convertible >::type, + result_type>::value || is_void<_Rp>::value, + result_type + >::type + operator()(_Args&& ...__args) const + { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(static_cast(*this), _VSTD::forward<_Args>(__args)...); + } +}; + +template +struct __is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {}; + +template +inline _LIBCPP_INLINE_VISIBILITY +__bind<_Fp, _BoundArgs...> +bind(_Fp&& __f, _BoundArgs&&... __bound_args) +{ + typedef __bind<_Fp, _BoundArgs...> type; + return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__bind_r<_Rp, _Fp, _BoundArgs...> +bind(_Fp&& __f, _BoundArgs&&... __bound_args) +{ + typedef __bind_r<_Rp, _Fp, _BoundArgs...> type; + return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...); +} + +#endif // _LIBCPP_HAS_NO_VARIADICS + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(bool __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(char __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(signed char __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast(__v);} +}; + +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast(__v);} +}; + +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(short __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(int __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(long __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast(__v);} +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public __scalar_hash +{ +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public __scalar_hash +{ +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public __scalar_hash +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(float __v) const _NOEXCEPT + { + // -0.0 and 0.0 should return same hash + if (__v == 0) + return 0; + return __scalar_hash::operator()(__v); + } +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public __scalar_hash +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(double __v) const _NOEXCEPT + { + // -0.0 and 0.0 should return same hash + if (__v == 0) + return 0; + return __scalar_hash::operator()(__v); + } +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash + : public __scalar_hash +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(long double __v) const _NOEXCEPT + { + // -0.0 and 0.0 should return same hash + if (__v == 0) + return 0; +#if defined(__i386__) + // Zero out padding bits + union + { + long double __t; + struct + { + size_t __a; + size_t __b; + size_t __c; + size_t __d; + } __s; + } __u; + __u.__s.__a = 0; + __u.__s.__b = 0; + __u.__s.__c = 0; + __u.__s.__d = 0; + __u.__t = __v; + return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d; +#elif defined(__x86_64__) + // Zero out padding bits + union + { + long double __t; + struct + { + size_t __a; + size_t __b; + } __s; + } __u; + __u.__s.__a = 0; + __u.__s.__b = 0; + __u.__t = __v; + return __u.__s.__a ^ __u.__s.__b; +#else + return __scalar_hash::operator()(__v); +#endif + } +}; + +#if _LIBCPP_STD_VER > 11 +template +struct _LIBCPP_TYPE_VIS_ONLY hash + : public unary_function<_Tp, size_t> +{ + static_assert(is_enum<_Tp>::value, "This hash only works for enumeration types"); + + _LIBCPP_INLINE_VISIBILITY + size_t operator()(_Tp __v) const _NOEXCEPT + { + typedef typename underlying_type<_Tp>::type type; + return hash{}(static_cast(__v)); + } +}; +#endif + + +#if _LIBCPP_STD_VER > 14 +template +result_of_t<_Fn&&(_Args&&...)> +invoke(_Fn&& __f, _Args&&... __args) { + return __invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); +} +#endif + +// struct hash in + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_FUNCTIONAL diff --git a/headers/libs/libc++/future b/headers/libs/libc++/future new file mode 100644 index 0000000000..ce15eafbf7 --- /dev/null +++ b/headers/libs/libc++/future @@ -0,0 +1,2604 @@ +// -*- C++ -*- +//===--------------------------- future -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_FUTURE +#define _LIBCPP_FUTURE + +/* + future synopsis + +namespace std +{ + +enum class future_errc +{ + future_already_retrieved = 1, + promise_already_satisfied, + no_state, + broken_promise +}; + +enum class launch +{ + async = 1, + deferred = 2, + any = async | deferred +}; + +enum class future_status +{ + ready, + timeout, + deferred +}; + +template <> struct is_error_code_enum : public true_type { }; +error_code make_error_code(future_errc e) noexcept; +error_condition make_error_condition(future_errc e) noexcept; + +const error_category& future_category() noexcept; + +class future_error + : public logic_error +{ +public: + future_error(error_code ec); // exposition only + + const error_code& code() const noexcept; + const char* what() const noexcept; +}; + +template +class promise +{ +public: + promise(); + template + promise(allocator_arg_t, const Allocator& a); + promise(promise&& rhs) noexcept; + promise(const promise& rhs) = delete; + ~promise(); + + // assignment + promise& operator=(promise&& rhs) noexcept; + promise& operator=(const promise& rhs) = delete; + void swap(promise& other) noexcept; + + // retrieving the result + future get_future(); + + // setting the result + void set_value(const R& r); + void set_value(R&& r); + void set_exception(exception_ptr p); + + // setting the result with deferred notification + void set_value_at_thread_exit(const R& r); + void set_value_at_thread_exit(R&& r); + void set_exception_at_thread_exit(exception_ptr p); +}; + +template +class promise +{ +public: + promise(); + template + promise(allocator_arg_t, const Allocator& a); + promise(promise&& rhs) noexcept; + promise(const promise& rhs) = delete; + ~promise(); + + // assignment + promise& operator=(promise&& rhs) noexcept; + promise& operator=(const promise& rhs) = delete; + void swap(promise& other) noexcept; + + // retrieving the result + future get_future(); + + // setting the result + void set_value(R& r); + void set_exception(exception_ptr p); + + // setting the result with deferred notification + void set_value_at_thread_exit(R&); + void set_exception_at_thread_exit(exception_ptr p); +}; + +template <> +class promise +{ +public: + promise(); + template + promise(allocator_arg_t, const Allocator& a); + promise(promise&& rhs) noexcept; + promise(const promise& rhs) = delete; + ~promise(); + + // assignment + promise& operator=(promise&& rhs) noexcept; + promise& operator=(const promise& rhs) = delete; + void swap(promise& other) noexcept; + + // retrieving the result + future get_future(); + + // setting the result + void set_value(); + void set_exception(exception_ptr p); + + // setting the result with deferred notification + void set_value_at_thread_exit(); + void set_exception_at_thread_exit(exception_ptr p); +}; + +template void swap(promise& x, promise& y) noexcept; + +template + struct uses_allocator, Alloc> : public true_type {}; + +template +class future +{ +public: + future() noexcept; + future(future&&) noexcept; + future(const future& rhs) = delete; + ~future(); + future& operator=(const future& rhs) = delete; + future& operator=(future&&) noexcept; + shared_future share(); + + // retrieving the value + R get(); + + // functions to check state + bool valid() const noexcept; + + void wait() const; + template + future_status + wait_for(const chrono::duration& rel_time) const; + template + future_status + wait_until(const chrono::time_point& abs_time) const; +}; + +template +class future +{ +public: + future() noexcept; + future(future&&) noexcept; + future(const future& rhs) = delete; + ~future(); + future& operator=(const future& rhs) = delete; + future& operator=(future&&) noexcept; + shared_future share(); + + // retrieving the value + R& get(); + + // functions to check state + bool valid() const noexcept; + + void wait() const; + template + future_status + wait_for(const chrono::duration& rel_time) const; + template + future_status + wait_until(const chrono::time_point& abs_time) const; +}; + +template <> +class future +{ +public: + future() noexcept; + future(future&&) noexcept; + future(const future& rhs) = delete; + ~future(); + future& operator=(const future& rhs) = delete; + future& operator=(future&&) noexcept; + shared_future share(); + + // retrieving the value + void get(); + + // functions to check state + bool valid() const noexcept; + + void wait() const; + template + future_status + wait_for(const chrono::duration& rel_time) const; + template + future_status + wait_until(const chrono::time_point& abs_time) const; +}; + +template +class shared_future +{ +public: + shared_future() noexcept; + shared_future(const shared_future& rhs); + shared_future(future&&) noexcept; + shared_future(shared_future&& rhs) noexcept; + ~shared_future(); + shared_future& operator=(const shared_future& rhs); + shared_future& operator=(shared_future&& rhs) noexcept; + + // retrieving the value + const R& get() const; + + // functions to check state + bool valid() const noexcept; + + void wait() const; + template + future_status + wait_for(const chrono::duration& rel_time) const; + template + future_status + wait_until(const chrono::time_point& abs_time) const; +}; + +template +class shared_future +{ +public: + shared_future() noexcept; + shared_future(const shared_future& rhs); + shared_future(future&&) noexcept; + shared_future(shared_future&& rhs) noexcept; + ~shared_future(); + shared_future& operator=(const shared_future& rhs); + shared_future& operator=(shared_future&& rhs) noexcept; + + // retrieving the value + R& get() const; + + // functions to check state + bool valid() const noexcept; + + void wait() const; + template + future_status + wait_for(const chrono::duration& rel_time) const; + template + future_status + wait_until(const chrono::time_point& abs_time) const; +}; + +template <> +class shared_future +{ +public: + shared_future() noexcept; + shared_future(const shared_future& rhs); + shared_future(future&&) noexcept; + shared_future(shared_future&& rhs) noexcept; + ~shared_future(); + shared_future& operator=(const shared_future& rhs); + shared_future& operator=(shared_future&& rhs) noexcept; + + // retrieving the value + void get() const; + + // functions to check state + bool valid() const noexcept; + + void wait() const; + template + future_status + wait_for(const chrono::duration& rel_time) const; + template + future_status + wait_until(const chrono::time_point& abs_time) const; +}; + +template + future::type(typename decay::type...)>::type> + async(F&& f, Args&&... args); + +template + future::type(typename decay::type...)>::type> + async(launch policy, F&& f, Args&&... args); + +template class packaged_task; // undefined + +template +class packaged_task +{ +public: + typedef R result_type; + + // construction and destruction + packaged_task() noexcept; + template + explicit packaged_task(F&& f); + template + packaged_task(allocator_arg_t, const Allocator& a, F&& f); + ~packaged_task(); + + // no copy + packaged_task(const packaged_task&) = delete; + packaged_task& operator=(const packaged_task&) = delete; + + // move support + packaged_task(packaged_task&& other) noexcept; + packaged_task& operator=(packaged_task&& other) noexcept; + void swap(packaged_task& other) noexcept; + + bool valid() const noexcept; + + // result retrieval + future get_future(); + + // execution + void operator()(ArgTypes... ); + void make_ready_at_thread_exit(ArgTypes...); + + void reset(); +}; + +template + void swap(packaged_task&) noexcept; + +template struct uses_allocator, Alloc>; + +} // std + +*/ + +#include <__config> +#include +#include +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifdef _LIBCPP_HAS_NO_THREADS +#error is not supported on this single threaded system +#else // !_LIBCPP_HAS_NO_THREADS + +_LIBCPP_BEGIN_NAMESPACE_STD + +//enum class future_errc +_LIBCPP_DECLARE_STRONG_ENUM(future_errc) +{ + future_already_retrieved = 1, + promise_already_satisfied, + no_state, + broken_promise +}; +_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc) + +template <> +struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum : public true_type {}; + +#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS +template <> +struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum : public true_type { }; +#endif + +//enum class launch +_LIBCPP_DECLARE_STRONG_ENUM(launch) +{ + async = 1, + deferred = 2, + any = async | deferred +}; +_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch) + +#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS + +#ifdef _LIBCXX_UNDERLYING_TYPE +typedef underlying_type::type __launch_underlying_type; +#else +typedef int __launch_underlying_type; +#endif + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +launch +operator&(launch __x, launch __y) +{ + return static_cast(static_cast<__launch_underlying_type>(__x) & + static_cast<__launch_underlying_type>(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +launch +operator|(launch __x, launch __y) +{ + return static_cast(static_cast<__launch_underlying_type>(__x) | + static_cast<__launch_underlying_type>(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +launch +operator^(launch __x, launch __y) +{ + return static_cast(static_cast<__launch_underlying_type>(__x) ^ + static_cast<__launch_underlying_type>(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +launch +operator~(launch __x) +{ + return static_cast(~static_cast<__launch_underlying_type>(__x) & 3); +} + +inline _LIBCPP_INLINE_VISIBILITY +launch& +operator&=(launch& __x, launch __y) +{ + __x = __x & __y; return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY +launch& +operator|=(launch& __x, launch __y) +{ + __x = __x | __y; return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY +launch& +operator^=(launch& __x, launch __y) +{ + __x = __x ^ __y; return __x; +} + +#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS + +//enum class future_status +_LIBCPP_DECLARE_STRONG_ENUM(future_status) +{ + ready, + timeout, + deferred +}; +_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status) + +_LIBCPP_FUNC_VIS +const error_category& future_category() _NOEXCEPT; + +inline _LIBCPP_INLINE_VISIBILITY +error_code +make_error_code(future_errc __e) _NOEXCEPT +{ + return error_code(static_cast(__e), future_category()); +} + +inline _LIBCPP_INLINE_VISIBILITY +error_condition +make_error_condition(future_errc __e) _NOEXCEPT +{ + return error_condition(static_cast(__e), future_category()); +} + +class _LIBCPP_EXCEPTION_ABI future_error + : public logic_error +{ + error_code __ec_; +public: + future_error(error_code __ec); + + _LIBCPP_INLINE_VISIBILITY + const error_code& code() const _NOEXCEPT {return __ec_;} + + virtual ~future_error() _NOEXCEPT; +}; + +inline _LIBCPP_ALWAYS_INLINE +void __throw_future_error(future_errc _Ev) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw future_error(make_error_code(_Ev)); +#else + assert(!"future_error"); +#endif +} + +class _LIBCPP_TYPE_VIS __assoc_sub_state + : public __shared_count +{ +protected: + exception_ptr __exception_; + mutable mutex __mut_; + mutable condition_variable __cv_; + unsigned __state_; + + virtual void __on_zero_shared() _NOEXCEPT; + void __sub_wait(unique_lock& __lk); +public: + enum + { + __constructed = 1, + __future_attached = 2, + ready = 4, + deferred = 8 + }; + + _LIBCPP_INLINE_VISIBILITY + __assoc_sub_state() : __state_(0) {} + + _LIBCPP_INLINE_VISIBILITY + bool __has_value() const + {return (__state_ & __constructed) || (__exception_ != nullptr);} + + _LIBCPP_INLINE_VISIBILITY + void __set_future_attached() + { + lock_guard __lk(__mut_); + __state_ |= __future_attached; + } + _LIBCPP_INLINE_VISIBILITY + bool __has_future_attached() const {return (__state_ & __future_attached) != 0;} + + _LIBCPP_INLINE_VISIBILITY + void __set_deferred() {__state_ |= deferred;} + + void __make_ready(); + _LIBCPP_INLINE_VISIBILITY + bool __is_ready() const {return (__state_ & ready) != 0;} + + void set_value(); + void set_value_at_thread_exit(); + + void set_exception(exception_ptr __p); + void set_exception_at_thread_exit(exception_ptr __p); + + void copy(); + + void wait(); + template + future_status + _LIBCPP_INLINE_VISIBILITY + wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const; + template + future_status + wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const; + + virtual void __execute(); +}; + +template +future_status +__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const +{ + unique_lock __lk(__mut_); + if (__state_ & deferred) + return future_status::deferred; + while (!(__state_ & ready) && _Clock::now() < __abs_time) + __cv_.wait_until(__lk, __abs_time); + if (__state_ & ready) + return future_status::ready; + return future_status::timeout; +} + +template +inline +future_status +__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const +{ + return wait_until(chrono::steady_clock::now() + __rel_time); +} + +template +class __assoc_state + : public __assoc_sub_state +{ + typedef __assoc_sub_state base; + typedef typename aligned_storage::value>::type _Up; +protected: + _Up __value_; + + virtual void __on_zero_shared() _NOEXCEPT; +public: + + template +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + void set_value(_Arg&& __arg); +#else + void set_value(_Arg& __arg); +#endif + + template +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + void set_value_at_thread_exit(_Arg&& __arg); +#else + void set_value_at_thread_exit(_Arg& __arg); +#endif + + _Rp move(); + typename add_lvalue_reference<_Rp>::type copy(); +}; + +template +void +__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT +{ + if (this->__state_ & base::__constructed) + reinterpret_cast<_Rp*>(&__value_)->~_Rp(); + delete this; +} + +template +template +void +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +__assoc_state<_Rp>::set_value(_Arg&& __arg) +#else +__assoc_state<_Rp>::set_value(_Arg& __arg) +#endif +{ + unique_lock __lk(this->__mut_); + if (this->__has_value()) + __throw_future_error(future_errc::promise_already_satisfied); + ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg)); + this->__state_ |= base::__constructed | base::ready; + __cv_.notify_all(); +} + +template +template +void +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg) +#else +__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg) +#endif +{ + unique_lock __lk(this->__mut_); + if (this->__has_value()) + __throw_future_error(future_errc::promise_already_satisfied); + ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg)); + this->__state_ |= base::__constructed; + __thread_local_data()->__make_ready_at_thread_exit(this); +} + +template +_Rp +__assoc_state<_Rp>::move() +{ + unique_lock __lk(this->__mut_); + this->__sub_wait(__lk); + if (this->__exception_ != nullptr) + rethrow_exception(this->__exception_); + return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_)); +} + +template +typename add_lvalue_reference<_Rp>::type +__assoc_state<_Rp>::copy() +{ + unique_lock __lk(this->__mut_); + this->__sub_wait(__lk); + if (this->__exception_ != nullptr) + rethrow_exception(this->__exception_); + return *reinterpret_cast<_Rp*>(&__value_); +} + +template +class __assoc_state<_Rp&> + : public __assoc_sub_state +{ + typedef __assoc_sub_state base; + typedef _Rp* _Up; +protected: + _Up __value_; + + virtual void __on_zero_shared() _NOEXCEPT; +public: + + void set_value(_Rp& __arg); + void set_value_at_thread_exit(_Rp& __arg); + + _Rp& copy(); +}; + +template +void +__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT +{ + delete this; +} + +template +void +__assoc_state<_Rp&>::set_value(_Rp& __arg) +{ + unique_lock __lk(this->__mut_); + if (this->__has_value()) + __throw_future_error(future_errc::promise_already_satisfied); + __value_ = _VSTD::addressof(__arg); + this->__state_ |= base::__constructed | base::ready; + __cv_.notify_all(); +} + +template +void +__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg) +{ + unique_lock __lk(this->__mut_); + if (this->__has_value()) + __throw_future_error(future_errc::promise_already_satisfied); + __value_ = _VSTD::addressof(__arg); + this->__state_ |= base::__constructed; + __thread_local_data()->__make_ready_at_thread_exit(this); +} + +template +_Rp& +__assoc_state<_Rp&>::copy() +{ + unique_lock __lk(this->__mut_); + this->__sub_wait(__lk); + if (this->__exception_ != nullptr) + rethrow_exception(this->__exception_); + return *__value_; +} + +template +class __assoc_state_alloc + : public __assoc_state<_Rp> +{ + typedef __assoc_state<_Rp> base; + _Alloc __alloc_; + + virtual void __on_zero_shared() _NOEXCEPT; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __assoc_state_alloc(const _Alloc& __a) + : __alloc_(__a) {} +}; + +template +void +__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT +{ + if (this->__state_ & base::__constructed) + reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp(); + typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al; + typedef allocator_traits<_Al> _ATraits; + typedef pointer_traits _PTraits; + _Al __a(__alloc_); + this->~__assoc_state_alloc(); + __a.deallocate(_PTraits::pointer_to(*this), 1); +} + +template +class __assoc_state_alloc<_Rp&, _Alloc> + : public __assoc_state<_Rp&> +{ + typedef __assoc_state<_Rp&> base; + _Alloc __alloc_; + + virtual void __on_zero_shared() _NOEXCEPT; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __assoc_state_alloc(const _Alloc& __a) + : __alloc_(__a) {} +}; + +template +void +__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT +{ + typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al; + typedef allocator_traits<_Al> _ATraits; + typedef pointer_traits _PTraits; + _Al __a(__alloc_); + this->~__assoc_state_alloc(); + __a.deallocate(_PTraits::pointer_to(*this), 1); +} + +template +class __assoc_sub_state_alloc + : public __assoc_sub_state +{ + typedef __assoc_sub_state base; + _Alloc __alloc_; + + virtual void __on_zero_shared() _NOEXCEPT; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __assoc_sub_state_alloc(const _Alloc& __a) + : __alloc_(__a) {} +}; + +template +void +__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT +{ + typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al; + typedef allocator_traits<_Al> _ATraits; + typedef pointer_traits _PTraits; + _Al __a(__alloc_); + this->~__assoc_sub_state_alloc(); + __a.deallocate(_PTraits::pointer_to(*this), 1); +} + +template +class __deferred_assoc_state + : public __assoc_state<_Rp> +{ + typedef __assoc_state<_Rp> base; + + _Fp __func_; + +public: +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + explicit __deferred_assoc_state(_Fp&& __f); +#endif + + virtual void __execute(); +}; + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline +__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f) + : __func_(_VSTD::forward<_Fp>(__f)) +{ + this->__set_deferred(); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +__deferred_assoc_state<_Rp, _Fp>::__execute() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + this->set_value(__func_()); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->set_exception(current_exception()); + } +#endif // _LIBCPP_NO_EXCEPTIONS +} + +template +class __deferred_assoc_state + : public __assoc_sub_state +{ + typedef __assoc_sub_state base; + + _Fp __func_; + +public: +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + explicit __deferred_assoc_state(_Fp&& __f); +#endif + + virtual void __execute(); +}; + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline +__deferred_assoc_state::__deferred_assoc_state(_Fp&& __f) + : __func_(_VSTD::forward<_Fp>(__f)) +{ + this->__set_deferred(); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +__deferred_assoc_state::__execute() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + __func_(); + this->set_value(); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->set_exception(current_exception()); + } +#endif // _LIBCPP_NO_EXCEPTIONS +} + +template +class __async_assoc_state + : public __assoc_state<_Rp> +{ + typedef __assoc_state<_Rp> base; + + _Fp __func_; + + virtual void __on_zero_shared() _NOEXCEPT; +public: +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + explicit __async_assoc_state(_Fp&& __f); +#endif + + virtual void __execute(); +}; + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline +__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f) + : __func_(_VSTD::forward<_Fp>(__f)) +{ +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +__async_assoc_state<_Rp, _Fp>::__execute() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + this->set_value(__func_()); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->set_exception(current_exception()); + } +#endif // _LIBCPP_NO_EXCEPTIONS +} + +template +void +__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT +{ + this->wait(); + base::__on_zero_shared(); +} + +template +class __async_assoc_state + : public __assoc_sub_state +{ + typedef __assoc_sub_state base; + + _Fp __func_; + + virtual void __on_zero_shared() _NOEXCEPT; +public: +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + explicit __async_assoc_state(_Fp&& __f); +#endif + + virtual void __execute(); +}; + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline +__async_assoc_state::__async_assoc_state(_Fp&& __f) + : __func_(_VSTD::forward<_Fp>(__f)) +{ +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +__async_assoc_state::__execute() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + __func_(); + this->set_value(); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->set_exception(current_exception()); + } +#endif // _LIBCPP_NO_EXCEPTIONS +} + +template +void +__async_assoc_state::__on_zero_shared() _NOEXCEPT +{ + this->wait(); + base::__on_zero_shared(); +} + +template class _LIBCPP_TYPE_VIS_ONLY promise; +template class _LIBCPP_TYPE_VIS_ONLY shared_future; + +// future + +template class _LIBCPP_TYPE_VIS_ONLY future; + +template +future<_Rp> +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +__make_deferred_assoc_state(_Fp&& __f); +#else +__make_deferred_assoc_state(_Fp __f); +#endif + +template +future<_Rp> +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +__make_async_assoc_state(_Fp&& __f); +#else +__make_async_assoc_state(_Fp __f); +#endif + +template +class _LIBCPP_TYPE_VIS_ONLY future +{ + __assoc_state<_Rp>* __state_; + + explicit future(__assoc_state<_Rp>* __state); + + template friend class promise; + template friend class shared_future; + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + template + friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); + template + friend future<_R1> __make_async_assoc_state(_Fp&& __f); +#else + template + friend future<_R1> __make_deferred_assoc_state(_Fp __f); + template + friend future<_R1> __make_async_assoc_state(_Fp __f); +#endif + +public: + _LIBCPP_INLINE_VISIBILITY + future() _NOEXCEPT : __state_(nullptr) {} +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + future(future&& __rhs) _NOEXCEPT + : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} + future(const future&) = delete; + future& operator=(const future&) = delete; + _LIBCPP_INLINE_VISIBILITY + future& operator=(future&& __rhs) _NOEXCEPT + { + future(std::move(__rhs)).swap(*this); + return *this; + } +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +private: + future(const future&); + future& operator=(const future&); +public: +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + ~future(); + _LIBCPP_INLINE_VISIBILITY + shared_future<_Rp> share(); + + // retrieving the value + _Rp get(); + + _LIBCPP_INLINE_VISIBILITY + void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} + + // functions to check state + _LIBCPP_INLINE_VISIBILITY + bool valid() const _NOEXCEPT {return __state_ != nullptr;} + + _LIBCPP_INLINE_VISIBILITY + void wait() const {__state_->wait();} + template + _LIBCPP_INLINE_VISIBILITY + future_status + wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const + {return __state_->wait_for(__rel_time);} + template + _LIBCPP_INLINE_VISIBILITY + future_status + wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const + {return __state_->wait_until(__abs_time);} +}; + +template +future<_Rp>::future(__assoc_state<_Rp>* __state) + : __state_(__state) +{ + if (__state_->__has_future_attached()) + __throw_future_error(future_errc::future_already_retrieved); + __state_->__add_shared(); + __state_->__set_future_attached(); +} + +struct __release_shared_count +{ + void operator()(__shared_count* p) {p->__release_shared();} +}; + +template +future<_Rp>::~future() +{ + if (__state_) + __state_->__release_shared(); +} + +template +_Rp +future<_Rp>::get() +{ + unique_ptr<__shared_count, __release_shared_count> __(__state_); + __assoc_state<_Rp>* __s = __state_; + __state_ = nullptr; + return __s->move(); +} + +template +class _LIBCPP_TYPE_VIS_ONLY future<_Rp&> +{ + __assoc_state<_Rp&>* __state_; + + explicit future(__assoc_state<_Rp&>* __state); + + template friend class promise; + template friend class shared_future; + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + template + friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); + template + friend future<_R1> __make_async_assoc_state(_Fp&& __f); +#else + template + friend future<_R1> __make_deferred_assoc_state(_Fp __f); + template + friend future<_R1> __make_async_assoc_state(_Fp __f); +#endif + +public: + _LIBCPP_INLINE_VISIBILITY + future() _NOEXCEPT : __state_(nullptr) {} +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + future(future&& __rhs) _NOEXCEPT + : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} + future(const future&) = delete; + future& operator=(const future&) = delete; + _LIBCPP_INLINE_VISIBILITY + future& operator=(future&& __rhs) _NOEXCEPT + { + future(std::move(__rhs)).swap(*this); + return *this; + } +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +private: + future(const future&); + future& operator=(const future&); +public: +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + ~future(); + _LIBCPP_INLINE_VISIBILITY + shared_future<_Rp&> share(); + + // retrieving the value + _Rp& get(); + + _LIBCPP_INLINE_VISIBILITY + void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} + + // functions to check state + _LIBCPP_INLINE_VISIBILITY + bool valid() const _NOEXCEPT {return __state_ != nullptr;} + + _LIBCPP_INLINE_VISIBILITY + void wait() const {__state_->wait();} + template + _LIBCPP_INLINE_VISIBILITY + future_status + wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const + {return __state_->wait_for(__rel_time);} + template + _LIBCPP_INLINE_VISIBILITY + future_status + wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const + {return __state_->wait_until(__abs_time);} +}; + +template +future<_Rp&>::future(__assoc_state<_Rp&>* __state) + : __state_(__state) +{ + if (__state_->__has_future_attached()) + __throw_future_error(future_errc::future_already_retrieved); + __state_->__add_shared(); + __state_->__set_future_attached(); +} + +template +future<_Rp&>::~future() +{ + if (__state_) + __state_->__release_shared(); +} + +template +_Rp& +future<_Rp&>::get() +{ + unique_ptr<__shared_count, __release_shared_count> __(__state_); + __assoc_state<_Rp&>* __s = __state_; + __state_ = nullptr; + return __s->copy(); +} + +template <> +class _LIBCPP_TYPE_VIS future +{ + __assoc_sub_state* __state_; + + explicit future(__assoc_sub_state* __state); + + template friend class promise; + template friend class shared_future; + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + template + friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); + template + friend future<_R1> __make_async_assoc_state(_Fp&& __f); +#else + template + friend future<_R1> __make_deferred_assoc_state(_Fp __f); + template + friend future<_R1> __make_async_assoc_state(_Fp __f); +#endif + +public: + _LIBCPP_INLINE_VISIBILITY + future() _NOEXCEPT : __state_(nullptr) {} +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + future(future&& __rhs) _NOEXCEPT + : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} + future(const future&) = delete; + future& operator=(const future&) = delete; + _LIBCPP_INLINE_VISIBILITY + future& operator=(future&& __rhs) _NOEXCEPT + { + future(std::move(__rhs)).swap(*this); + return *this; + } +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +private: + future(const future&); + future& operator=(const future&); +public: +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + ~future(); + _LIBCPP_INLINE_VISIBILITY + shared_future share(); + + // retrieving the value + void get(); + + _LIBCPP_INLINE_VISIBILITY + void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} + + // functions to check state + _LIBCPP_INLINE_VISIBILITY + bool valid() const _NOEXCEPT {return __state_ != nullptr;} + + _LIBCPP_INLINE_VISIBILITY + void wait() const {__state_->wait();} + template + _LIBCPP_INLINE_VISIBILITY + future_status + wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const + {return __state_->wait_for(__rel_time);} + template + _LIBCPP_INLINE_VISIBILITY + future_status + wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const + {return __state_->wait_until(__abs_time);} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT +{ + __x.swap(__y); +} + +// promise + +template class packaged_task; + +template +class _LIBCPP_TYPE_VIS_ONLY promise +{ + __assoc_state<_Rp>* __state_; + + _LIBCPP_INLINE_VISIBILITY + explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} + + template friend class packaged_task; +public: + promise(); + template + promise(allocator_arg_t, const _Alloc& __a); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + promise(promise&& __rhs) _NOEXCEPT + : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} + promise(const promise& __rhs) = delete; +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +private: + promise(const promise& __rhs); +public: +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + ~promise(); + + // assignment +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + promise& operator=(promise&& __rhs) _NOEXCEPT + { + promise(std::move(__rhs)).swap(*this); + return *this; + } + promise& operator=(const promise& __rhs) = delete; +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +private: + promise& operator=(const promise& __rhs); +public: +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} + + // retrieving the result + future<_Rp> get_future(); + + // setting the result + void set_value(const _Rp& __r); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + void set_value(_Rp&& __r); +#endif + void set_exception(exception_ptr __p); + + // setting the result with deferred notification + void set_value_at_thread_exit(const _Rp& __r); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + void set_value_at_thread_exit(_Rp&& __r); +#endif + void set_exception_at_thread_exit(exception_ptr __p); +}; + +template +promise<_Rp>::promise() + : __state_(new __assoc_state<_Rp>) +{ +} + +template +template +promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0) +{ + typedef __assoc_state_alloc<_Rp, _Alloc> _State; + typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; + typedef __allocator_destructor<_A2> _D2; + _A2 __a(__a0); + unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); + ::new(static_cast(_VSTD::addressof(*__hold.get()))) _State(__a0); + __state_ = _VSTD::addressof(*__hold.release()); +} + +template +promise<_Rp>::~promise() +{ + if (__state_) + { + if (!__state_->__has_value() && __state_->use_count() > 1) + __state_->set_exception(make_exception_ptr( + future_error(make_error_code(future_errc::broken_promise)) + )); + __state_->__release_shared(); + } +} + +template +future<_Rp> +promise<_Rp>::get_future() +{ + if (__state_ == nullptr) + __throw_future_error(future_errc::no_state); + return future<_Rp>(__state_); +} + +template +void +promise<_Rp>::set_value(const _Rp& __r) +{ + if (__state_ == nullptr) + __throw_future_error(future_errc::no_state); + __state_->set_value(__r); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +promise<_Rp>::set_value(_Rp&& __r) +{ + if (__state_ == nullptr) + __throw_future_error(future_errc::no_state); + __state_->set_value(_VSTD::move(__r)); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +promise<_Rp>::set_exception(exception_ptr __p) +{ + if (__state_ == nullptr) + __throw_future_error(future_errc::no_state); + __state_->set_exception(__p); +} + +template +void +promise<_Rp>::set_value_at_thread_exit(const _Rp& __r) +{ + if (__state_ == nullptr) + __throw_future_error(future_errc::no_state); + __state_->set_value_at_thread_exit(__r); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +promise<_Rp>::set_value_at_thread_exit(_Rp&& __r) +{ + if (__state_ == nullptr) + __throw_future_error(future_errc::no_state); + __state_->set_value_at_thread_exit(_VSTD::move(__r)); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) +{ + if (__state_ == nullptr) + __throw_future_error(future_errc::no_state); + __state_->set_exception_at_thread_exit(__p); +} + +// promise + +template +class _LIBCPP_TYPE_VIS_ONLY promise<_Rp&> +{ + __assoc_state<_Rp&>* __state_; + + _LIBCPP_INLINE_VISIBILITY + explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} + + template friend class packaged_task; + +public: + promise(); + template + promise(allocator_arg_t, const _Allocator& __a); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + promise(promise&& __rhs) _NOEXCEPT + : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} + promise(const promise& __rhs) = delete; +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +private: + promise(const promise& __rhs); +public: +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + ~promise(); + + // assignment +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + promise& operator=(promise&& __rhs) _NOEXCEPT + { + promise(std::move(__rhs)).swap(*this); + return *this; + } + promise& operator=(const promise& __rhs) = delete; +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +private: + promise& operator=(const promise& __rhs); +public: +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} + + // retrieving the result + future<_Rp&> get_future(); + + // setting the result + void set_value(_Rp& __r); + void set_exception(exception_ptr __p); + + // setting the result with deferred notification + void set_value_at_thread_exit(_Rp&); + void set_exception_at_thread_exit(exception_ptr __p); +}; + +template +promise<_Rp&>::promise() + : __state_(new __assoc_state<_Rp&>) +{ +} + +template +template +promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0) +{ + typedef __assoc_state_alloc<_Rp&, _Alloc> _State; + typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; + typedef __allocator_destructor<_A2> _D2; + _A2 __a(__a0); + unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); + ::new(static_cast(_VSTD::addressof(*__hold.get()))) _State(__a0); + __state_ = _VSTD::addressof(*__hold.release()); +} + +template +promise<_Rp&>::~promise() +{ + if (__state_) + { + if (!__state_->__has_value() && __state_->use_count() > 1) + __state_->set_exception(make_exception_ptr( + future_error(make_error_code(future_errc::broken_promise)) + )); + __state_->__release_shared(); + } +} + +template +future<_Rp&> +promise<_Rp&>::get_future() +{ + if (__state_ == nullptr) + __throw_future_error(future_errc::no_state); + return future<_Rp&>(__state_); +} + +template +void +promise<_Rp&>::set_value(_Rp& __r) +{ + if (__state_ == nullptr) + __throw_future_error(future_errc::no_state); + __state_->set_value(__r); +} + +template +void +promise<_Rp&>::set_exception(exception_ptr __p) +{ + if (__state_ == nullptr) + __throw_future_error(future_errc::no_state); + __state_->set_exception(__p); +} + +template +void +promise<_Rp&>::set_value_at_thread_exit(_Rp& __r) +{ + if (__state_ == nullptr) + __throw_future_error(future_errc::no_state); + __state_->set_value_at_thread_exit(__r); +} + +template +void +promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) +{ + if (__state_ == nullptr) + __throw_future_error(future_errc::no_state); + __state_->set_exception_at_thread_exit(__p); +} + +// promise + +template <> +class _LIBCPP_TYPE_VIS promise +{ + __assoc_sub_state* __state_; + + _LIBCPP_INLINE_VISIBILITY + explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} + + template friend class packaged_task; + +public: + promise(); + template + promise(allocator_arg_t, const _Allocator& __a); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + promise(promise&& __rhs) _NOEXCEPT + : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} + promise(const promise& __rhs) = delete; +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +private: + promise(const promise& __rhs); +public: +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + ~promise(); + + // assignment +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + promise& operator=(promise&& __rhs) _NOEXCEPT + { + promise(std::move(__rhs)).swap(*this); + return *this; + } + promise& operator=(const promise& __rhs) = delete; +#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +private: + promise& operator=(const promise& __rhs); +public: +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} + + // retrieving the result + future get_future(); + + // setting the result + void set_value(); + void set_exception(exception_ptr __p); + + // setting the result with deferred notification + void set_value_at_thread_exit(); + void set_exception_at_thread_exit(exception_ptr __p); +}; + +template +promise::promise(allocator_arg_t, const _Alloc& __a0) +{ + typedef __assoc_sub_state_alloc<_Alloc> _State; + typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; + typedef __allocator_destructor<_A2> _D2; + _A2 __a(__a0); + unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); + ::new(static_cast(_VSTD::addressof(*__hold.get()))) _State(__a0); + __state_ = _VSTD::addressof(*__hold.release()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT +{ + __x.swap(__y); +} + +template + struct _LIBCPP_TYPE_VIS_ONLY uses_allocator, _Alloc> + : public true_type {}; + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +// packaged_task + +template class __packaged_task_base; + +template +class __packaged_task_base<_Rp(_ArgTypes...)> +{ + __packaged_task_base(const __packaged_task_base&); + __packaged_task_base& operator=(const __packaged_task_base&); +public: + _LIBCPP_INLINE_VISIBILITY + __packaged_task_base() {} + _LIBCPP_INLINE_VISIBILITY + virtual ~__packaged_task_base() {} + virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0; + virtual void destroy() = 0; + virtual void destroy_deallocate() = 0; + virtual _Rp operator()(_ArgTypes&& ...) = 0; +}; + +template class __packaged_task_func; + +template +class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> + : public __packaged_task_base<_Rp(_ArgTypes...)> +{ + __compressed_pair<_Fp, _Alloc> __f_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {} + _LIBCPP_INLINE_VISIBILITY + explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {} + _LIBCPP_INLINE_VISIBILITY + __packaged_task_func(const _Fp& __f, const _Alloc& __a) + : __f_(__f, __a) {} + _LIBCPP_INLINE_VISIBILITY + __packaged_task_func(_Fp&& __f, const _Alloc& __a) + : __f_(_VSTD::move(__f), __a) {} + virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT; + virtual void destroy(); + virtual void destroy_deallocate(); + virtual _Rp operator()(_ArgTypes&& ... __args); +}; + +template +void +__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to( + __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT +{ + ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second())); +} + +template +void +__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() +{ + __f_.~__compressed_pair<_Fp, _Alloc>(); +} + +template +void +__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() +{ + typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap; + typedef allocator_traits<_Ap> _ATraits; + typedef pointer_traits _PTraits; + _Ap __a(__f_.second()); + __f_.~__compressed_pair<_Fp, _Alloc>(); + __a.deallocate(_PTraits::pointer_to(*this), 1); +} + +template +_Rp +__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) +{ + return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...); +} + +template class __packaged_task_function; + +template +class __packaged_task_function<_Rp(_ArgTypes...)> +{ + typedef __packaged_task_base<_Rp(_ArgTypes...)> __base; + typename aligned_storage<3*sizeof(void*)>::type __buf_; + __base* __f_; + +public: + typedef _Rp result_type; + + // construct/copy/destroy: + _LIBCPP_INLINE_VISIBILITY + __packaged_task_function() _NOEXCEPT : __f_(nullptr) {} + template + __packaged_task_function(_Fp&& __f); + template + __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f); + + __packaged_task_function(__packaged_task_function&&) _NOEXCEPT; + __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT; + + __packaged_task_function(const __packaged_task_function&) = delete; + __packaged_task_function& operator=(const __packaged_task_function&) = delete; + + ~__packaged_task_function(); + + void swap(__packaged_task_function&) _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes...) const; +}; + +template +__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT +{ + if (__f.__f_ == nullptr) + __f_ = nullptr; + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__move_to(__f_); + } + else + { + __f_ = __f.__f_; + __f.__f_ = nullptr; + } +} + +template +template +__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) + : __f_(nullptr) +{ + typedef typename remove_reference::type>::type _FR; + typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new (__f_) _FF(_VSTD::forward<_Fp>(__f)); + } + else + { + typedef allocator<_FF> _Ap; + _Ap __a; + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a)); + __f_ = __hold.release(); + } +} + +template +template +__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function( + allocator_arg_t, const _Alloc& __a0, _Fp&& __f) + : __f_(nullptr) +{ + typedef typename remove_reference::type>::type _FR; + typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new (__f_) _FF(_VSTD::forward<_Fp>(__f)); + } + else + { + typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap; + _Ap __a(__a0); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new (static_cast(_VSTD::addressof(*__hold.get()))) + _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a)); + __f_ = _VSTD::addressof(*__hold.release()); + } +} + +template +__packaged_task_function<_Rp(_ArgTypes...)>& +__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); + __f_ = nullptr; + if (__f.__f_ == nullptr) + __f_ = nullptr; + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__move_to(__f_); + } + else + { + __f_ = __f.__f_; + __f.__f_ = nullptr; + } + return *this; +} + +template +__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function() +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); +} + +template +void +__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT +{ + if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) + { + typename aligned_storage::type __tempbuf; + __base* __t = (__base*)&__tempbuf; + __f_->__move_to(__t); + __f_->destroy(); + __f_ = nullptr; + __f.__f_->__move_to((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = nullptr; + __f_ = (__base*)&__buf_; + __t->__move_to((__base*)&__f.__buf_); + __t->destroy(); + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f_ == (__base*)&__buf_) + { + __f_->__move_to((__base*)&__f.__buf_); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f.__f_->__move_to((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = (__base*)&__buf_; + } + else + _VSTD::swap(__f_, __f.__f_); +} + +template +inline +_Rp +__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const +{ + return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...); +} + +template +class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)> +{ +public: + typedef _Rp result_type; + +private: + __packaged_task_function __f_; + promise __p_; + +public: + // construction and destruction + _LIBCPP_INLINE_VISIBILITY + packaged_task() _NOEXCEPT : __p_(nullptr) {} + template ::type, + packaged_task + >::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {} + template ::type, + packaged_task + >::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) + : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), + __p_(allocator_arg, __a) {} + // ~packaged_task() = default; + + // no copy + packaged_task(const packaged_task&) = delete; + packaged_task& operator=(const packaged_task&) = delete; + + // move support + _LIBCPP_INLINE_VISIBILITY + packaged_task(packaged_task&& __other) _NOEXCEPT + : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} + _LIBCPP_INLINE_VISIBILITY + packaged_task& operator=(packaged_task&& __other) _NOEXCEPT + { + __f_ = _VSTD::move(__other.__f_); + __p_ = _VSTD::move(__other.__p_); + return *this; + } + _LIBCPP_INLINE_VISIBILITY + void swap(packaged_task& __other) _NOEXCEPT + { + __f_.swap(__other.__f_); + __p_.swap(__other.__p_); + } + + _LIBCPP_INLINE_VISIBILITY + bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;} + + // result retrieval + _LIBCPP_INLINE_VISIBILITY + future get_future() {return __p_.get_future();} + + // execution + void operator()(_ArgTypes... __args); + void make_ready_at_thread_exit(_ArgTypes... __args); + + void reset(); +}; + +template +void +packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) +{ + if (__p_.__state_ == nullptr) + __throw_future_error(future_errc::no_state); + if (__p_.__state_->__has_value()) + __throw_future_error(future_errc::promise_already_satisfied); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...)); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __p_.set_exception(current_exception()); + } +#endif // _LIBCPP_NO_EXCEPTIONS +} + +template +void +packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) +{ + if (__p_.__state_ == nullptr) + __throw_future_error(future_errc::no_state); + if (__p_.__state_->__has_value()) + __throw_future_error(future_errc::promise_already_satisfied); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...)); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __p_.set_exception_at_thread_exit(current_exception()); + } +#endif // _LIBCPP_NO_EXCEPTIONS +} + +template +void +packaged_task<_Rp(_ArgTypes...)>::reset() +{ + if (!valid()) + __throw_future_error(future_errc::no_state); + __p_ = promise(); +} + +template +class _LIBCPP_TYPE_VIS_ONLY packaged_task +{ +public: + typedef void result_type; + +private: + __packaged_task_function __f_; + promise __p_; + +public: + // construction and destruction + _LIBCPP_INLINE_VISIBILITY + packaged_task() _NOEXCEPT : __p_(nullptr) {} + template ::type, + packaged_task + >::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {} + template ::type, + packaged_task + >::value + >::type + > + _LIBCPP_INLINE_VISIBILITY + packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) + : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), + __p_(allocator_arg, __a) {} + // ~packaged_task() = default; + + // no copy + packaged_task(const packaged_task&) = delete; + packaged_task& operator=(const packaged_task&) = delete; + + // move support + _LIBCPP_INLINE_VISIBILITY + packaged_task(packaged_task&& __other) _NOEXCEPT + : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} + _LIBCPP_INLINE_VISIBILITY + packaged_task& operator=(packaged_task&& __other) _NOEXCEPT + { + __f_ = _VSTD::move(__other.__f_); + __p_ = _VSTD::move(__other.__p_); + return *this; + } + _LIBCPP_INLINE_VISIBILITY + void swap(packaged_task& __other) _NOEXCEPT + { + __f_.swap(__other.__f_); + __p_.swap(__other.__p_); + } + + _LIBCPP_INLINE_VISIBILITY + bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;} + + // result retrieval + _LIBCPP_INLINE_VISIBILITY + future get_future() {return __p_.get_future();} + + // execution + void operator()(_ArgTypes... __args); + void make_ready_at_thread_exit(_ArgTypes... __args); + + void reset(); +}; + +template +void +packaged_task::operator()(_ArgTypes... __args) +{ + if (__p_.__state_ == nullptr) + __throw_future_error(future_errc::no_state); + if (__p_.__state_->__has_value()) + __throw_future_error(future_errc::promise_already_satisfied); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + __f_(_VSTD::forward<_ArgTypes>(__args)...); + __p_.set_value(); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __p_.set_exception(current_exception()); + } +#endif // _LIBCPP_NO_EXCEPTIONS +} + +template +void +packaged_task::make_ready_at_thread_exit(_ArgTypes... __args) +{ + if (__p_.__state_ == nullptr) + __throw_future_error(future_errc::no_state); + if (__p_.__state_->__has_value()) + __throw_future_error(future_errc::promise_already_satisfied); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + __f_(_VSTD::forward<_ArgTypes>(__args)...); + __p_.set_value_at_thread_exit(); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __p_.set_exception_at_thread_exit(current_exception()); + } +#endif // _LIBCPP_NO_EXCEPTIONS +} + +template +void +packaged_task::reset() +{ + if (!valid()) + __throw_future_error(future_errc::no_state); + __p_ = promise(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT +{ + __x.swap(__y); +} + +template +struct _LIBCPP_TYPE_VIS_ONLY uses_allocator, _Alloc> + : public true_type {}; + +template +future<_Rp> +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +__make_deferred_assoc_state(_Fp&& __f) +#else +__make_deferred_assoc_state(_Fp __f) +#endif +{ + unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> + __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f))); + return future<_Rp>(__h.get()); +} + +template +future<_Rp> +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +__make_async_assoc_state(_Fp&& __f) +#else +__make_async_assoc_state(_Fp __f) +#endif +{ + unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> + __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f))); + _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach(); + return future<_Rp>(__h.get()); +} + +template +class __async_func +{ + tuple<_Fp, _Args...> __f_; + +public: + typedef typename __invoke_of<_Fp, _Args...>::type _Rp; + + _LIBCPP_INLINE_VISIBILITY + explicit __async_func(_Fp&& __f, _Args&&... __args) + : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {} + + _LIBCPP_INLINE_VISIBILITY + __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {} + + _Rp operator()() + { + typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index; + return __execute(_Index()); + } +private: + template + _Rp + __execute(__tuple_indices<_Indices...>) + { + return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...); + } +}; + +inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value ) +{ return (int(__policy) & int(__value)) != 0; } + +template +future::type, typename decay<_Args>::type...>::type> +async(launch __policy, _Fp&& __f, _Args&&... __args) +{ + typedef __async_func::type, typename decay<_Args>::type...> _BF; + typedef typename _BF::_Rp _Rp; + +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif + if (__does_policy_contain(__policy, launch::async)) + return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)), + __decay_copy(_VSTD::forward<_Args>(__args))...)); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch ( ... ) { if (__policy == launch::async) throw ; } +#endif + + if (__does_policy_contain(__policy, launch::deferred)) + return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)), + __decay_copy(_VSTD::forward<_Args>(__args))...)); + return future<_Rp>{}; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +future::type, typename decay<_Args>::type...>::type> +async(_Fp&& __f, _Args&&... __args) +{ + return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f), + _VSTD::forward<_Args>(__args)...); +} + +#endif // _LIBCPP_HAS_NO_VARIADICS + +// shared_future + +template +class _LIBCPP_TYPE_VIS_ONLY shared_future +{ + __assoc_state<_Rp>* __state_; + +public: + _LIBCPP_INLINE_VISIBILITY + shared_future() _NOEXCEPT : __state_(nullptr) {} + _LIBCPP_INLINE_VISIBILITY + shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) + {if (__state_) __state_->__add_shared();} +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_) + {__f.__state_ = nullptr;} + _LIBCPP_INLINE_VISIBILITY + shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) + {__rhs.__state_ = nullptr;} +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + ~shared_future(); + shared_future& operator=(const shared_future& __rhs); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + shared_future& operator=(shared_future&& __rhs) _NOEXCEPT + { + shared_future(std::move(__rhs)).swap(*this); + return *this; + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + // retrieving the value + _LIBCPP_INLINE_VISIBILITY + const _Rp& get() const {return __state_->copy();} + + _LIBCPP_INLINE_VISIBILITY + void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} + + // functions to check state + _LIBCPP_INLINE_VISIBILITY + bool valid() const _NOEXCEPT {return __state_ != nullptr;} + + _LIBCPP_INLINE_VISIBILITY + void wait() const {__state_->wait();} + template + _LIBCPP_INLINE_VISIBILITY + future_status + wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const + {return __state_->wait_for(__rel_time);} + template + _LIBCPP_INLINE_VISIBILITY + future_status + wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const + {return __state_->wait_until(__abs_time);} +}; + +template +shared_future<_Rp>::~shared_future() +{ + if (__state_) + __state_->__release_shared(); +} + +template +shared_future<_Rp>& +shared_future<_Rp>::operator=(const shared_future& __rhs) +{ + if (__rhs.__state_) + __rhs.__state_->__add_shared(); + if (__state_) + __state_->__release_shared(); + __state_ = __rhs.__state_; + return *this; +} + +template +class _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&> +{ + __assoc_state<_Rp&>* __state_; + +public: + _LIBCPP_INLINE_VISIBILITY + shared_future() _NOEXCEPT : __state_(nullptr) {} + _LIBCPP_INLINE_VISIBILITY + shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) + {if (__state_) __state_->__add_shared();} +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_) + {__f.__state_ = nullptr;} + _LIBCPP_INLINE_VISIBILITY + shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) + {__rhs.__state_ = nullptr;} +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + ~shared_future(); + shared_future& operator=(const shared_future& __rhs); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + shared_future& operator=(shared_future&& __rhs) _NOEXCEPT + { + shared_future(std::move(__rhs)).swap(*this); + return *this; + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + // retrieving the value + _LIBCPP_INLINE_VISIBILITY + _Rp& get() const {return __state_->copy();} + + _LIBCPP_INLINE_VISIBILITY + void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} + + // functions to check state + _LIBCPP_INLINE_VISIBILITY + bool valid() const _NOEXCEPT {return __state_ != nullptr;} + + _LIBCPP_INLINE_VISIBILITY + void wait() const {__state_->wait();} + template + _LIBCPP_INLINE_VISIBILITY + future_status + wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const + {return __state_->wait_for(__rel_time);} + template + _LIBCPP_INLINE_VISIBILITY + future_status + wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const + {return __state_->wait_until(__abs_time);} +}; + +template +shared_future<_Rp&>::~shared_future() +{ + if (__state_) + __state_->__release_shared(); +} + +template +shared_future<_Rp&>& +shared_future<_Rp&>::operator=(const shared_future& __rhs) +{ + if (__rhs.__state_) + __rhs.__state_->__add_shared(); + if (__state_) + __state_->__release_shared(); + __state_ = __rhs.__state_; + return *this; +} + +template <> +class _LIBCPP_TYPE_VIS shared_future +{ + __assoc_sub_state* __state_; + +public: + _LIBCPP_INLINE_VISIBILITY + shared_future() _NOEXCEPT : __state_(nullptr) {} + _LIBCPP_INLINE_VISIBILITY + shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) + {if (__state_) __state_->__add_shared();} +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + shared_future(future&& __f) _NOEXCEPT : __state_(__f.__state_) + {__f.__state_ = nullptr;} + _LIBCPP_INLINE_VISIBILITY + shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) + {__rhs.__state_ = nullptr;} +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + ~shared_future(); + shared_future& operator=(const shared_future& __rhs); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + shared_future& operator=(shared_future&& __rhs) _NOEXCEPT + { + shared_future(std::move(__rhs)).swap(*this); + return *this; + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + // retrieving the value + _LIBCPP_INLINE_VISIBILITY + void get() const {__state_->copy();} + + _LIBCPP_INLINE_VISIBILITY + void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} + + // functions to check state + _LIBCPP_INLINE_VISIBILITY + bool valid() const _NOEXCEPT {return __state_ != nullptr;} + + _LIBCPP_INLINE_VISIBILITY + void wait() const {__state_->wait();} + template + _LIBCPP_INLINE_VISIBILITY + future_status + wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const + {return __state_->wait_for(__rel_time);} + template + _LIBCPP_INLINE_VISIBILITY + future_status + wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const + {return __state_->wait_until(__abs_time);} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT +{ + __x.swap(__y); +} + +template +inline +shared_future<_Rp> +future<_Rp>::share() +{ + return shared_future<_Rp>(_VSTD::move(*this)); +} + +template +inline +shared_future<_Rp&> +future<_Rp&>::share() +{ + return shared_future<_Rp&>(_VSTD::move(*this)); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +inline +shared_future +future::share() +{ + return shared_future(_VSTD::move(*this)); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +_LIBCPP_END_NAMESPACE_STD + +#endif // !_LIBCPP_HAS_NO_THREADS + +#endif // _LIBCPP_FUTURE diff --git a/headers/libs/libc++/initializer_list b/headers/libs/libc++/initializer_list new file mode 100644 index 0000000000..663e49b6ee --- /dev/null +++ b/headers/libs/libc++/initializer_list @@ -0,0 +1,118 @@ +// -*- C++ -*- +//===----------------------- initializer_list -----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_INITIALIZER_LIST +#define _LIBCPP_INITIALIZER_LIST + +/* + initializer_list synopsis + +namespace std +{ + +template +class initializer_list +{ +public: + typedef E value_type; + typedef const E& reference; + typedef const E& const_reference; + typedef size_t size_type; + + typedef const E* iterator; + typedef const E* const_iterator; + + initializer_list() noexcept; // constexpr in C++14 + + size_t size() const noexcept; // constexpr in C++14 + const E* begin() const noexcept; // constexpr in C++14 + const E* end() const noexcept; // constexpr in C++14 +}; + +template const E* begin(initializer_list il) noexcept; // constexpr in C++14 +template const E* end(initializer_list il) noexcept; // constexpr in C++14 + +} // std + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +namespace std // purposefully not versioned +{ + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +template +class _LIBCPP_TYPE_VIS_ONLY initializer_list +{ + const _Ep* __begin_; + size_t __size_; + + _LIBCPP_ALWAYS_INLINE + _LIBCPP_CONSTEXPR_AFTER_CXX11 + initializer_list(const _Ep* __b, size_t __s) _NOEXCEPT + : __begin_(__b), + __size_(__s) + {} +public: + typedef _Ep value_type; + typedef const _Ep& reference; + typedef const _Ep& const_reference; + typedef size_t size_type; + + typedef const _Ep* iterator; + typedef const _Ep* const_iterator; + + _LIBCPP_ALWAYS_INLINE + _LIBCPP_CONSTEXPR_AFTER_CXX11 + initializer_list() _NOEXCEPT : __begin_(nullptr), __size_(0) {} + + _LIBCPP_ALWAYS_INLINE + _LIBCPP_CONSTEXPR_AFTER_CXX11 + size_t size() const _NOEXCEPT {return __size_;} + + _LIBCPP_ALWAYS_INLINE + _LIBCPP_CONSTEXPR_AFTER_CXX11 + const _Ep* begin() const _NOEXCEPT {return __begin_;} + + _LIBCPP_ALWAYS_INLINE + _LIBCPP_CONSTEXPR_AFTER_CXX11 + const _Ep* end() const _NOEXCEPT {return __begin_ + __size_;} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR_AFTER_CXX11 +const _Ep* +begin(initializer_list<_Ep> __il) _NOEXCEPT +{ + return __il.begin(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR_AFTER_CXX11 +const _Ep* +end(initializer_list<_Ep> __il) _NOEXCEPT +{ + return __il.end(); +} + +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +} // std + +#endif // _LIBCPP_INITIALIZER_LIST diff --git a/headers/libs/libc++/inttypes.h b/headers/libs/libc++/inttypes.h new file mode 100644 index 0000000000..5c5618bef8 --- /dev/null +++ b/headers/libs/libc++/inttypes.h @@ -0,0 +1,251 @@ +// -*- C++ -*- +//===--------------------------- inttypes.h -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_INTTYPES_H +#define _LIBCPP_INTTYPES_H + +/* + inttypes.h synopsis + +This entire header is C99 / C++0X + +#include // includes + +Macros: + + PRId8 + PRId16 + PRId32 + PRId64 + + PRIdLEAST8 + PRIdLEAST16 + PRIdLEAST32 + PRIdLEAST64 + + PRIdFAST8 + PRIdFAST16 + PRIdFAST32 + PRIdFAST64 + + PRIdMAX + PRIdPTR + + PRIi8 + PRIi16 + PRIi32 + PRIi64 + + PRIiLEAST8 + PRIiLEAST16 + PRIiLEAST32 + PRIiLEAST64 + + PRIiFAST8 + PRIiFAST16 + PRIiFAST32 + PRIiFAST64 + + PRIiMAX + PRIiPTR + + PRIo8 + PRIo16 + PRIo32 + PRIo64 + + PRIoLEAST8 + PRIoLEAST16 + PRIoLEAST32 + PRIoLEAST64 + + PRIoFAST8 + PRIoFAST16 + PRIoFAST32 + PRIoFAST64 + + PRIoMAX + PRIoPTR + + PRIu8 + PRIu16 + PRIu32 + PRIu64 + + PRIuLEAST8 + PRIuLEAST16 + PRIuLEAST32 + PRIuLEAST64 + + PRIuFAST8 + PRIuFAST16 + PRIuFAST32 + PRIuFAST64 + + PRIuMAX + PRIuPTR + + PRIx8 + PRIx16 + PRIx32 + PRIx64 + + PRIxLEAST8 + PRIxLEAST16 + PRIxLEAST32 + PRIxLEAST64 + + PRIxFAST8 + PRIxFAST16 + PRIxFAST32 + PRIxFAST64 + + PRIxMAX + PRIxPTR + + PRIX8 + PRIX16 + PRIX32 + PRIX64 + + PRIXLEAST8 + PRIXLEAST16 + PRIXLEAST32 + PRIXLEAST64 + + PRIXFAST8 + PRIXFAST16 + PRIXFAST32 + PRIXFAST64 + + PRIXMAX + PRIXPTR + + SCNd8 + SCNd16 + SCNd32 + SCNd64 + + SCNdLEAST8 + SCNdLEAST16 + SCNdLEAST32 + SCNdLEAST64 + + SCNdFAST8 + SCNdFAST16 + SCNdFAST32 + SCNdFAST64 + + SCNdMAX + SCNdPTR + + SCNi8 + SCNi16 + SCNi32 + SCNi64 + + SCNiLEAST8 + SCNiLEAST16 + SCNiLEAST32 + SCNiLEAST64 + + SCNiFAST8 + SCNiFAST16 + SCNiFAST32 + SCNiFAST64 + + SCNiMAX + SCNiPTR + + SCNo8 + SCNo16 + SCNo32 + SCNo64 + + SCNoLEAST8 + SCNoLEAST16 + SCNoLEAST32 + SCNoLEAST64 + + SCNoFAST8 + SCNoFAST16 + SCNoFAST32 + SCNoFAST64 + + SCNoMAX + SCNoPTR + + SCNu8 + SCNu16 + SCNu32 + SCNu64 + + SCNuLEAST8 + SCNuLEAST16 + SCNuLEAST32 + SCNuLEAST64 + + SCNuFAST8 + SCNuFAST16 + SCNuFAST32 + SCNuFAST64 + + SCNuMAX + SCNuPTR + + SCNx8 + SCNx16 + SCNx32 + SCNx64 + + SCNxLEAST8 + SCNxLEAST16 + SCNxLEAST32 + SCNxLEAST64 + + SCNxFAST8 + SCNxFAST16 + SCNxFAST32 + SCNxFAST64 + + SCNxMAX + SCNxPTR + +Types: + + imaxdiv_t + +intmax_t imaxabs(intmax_t j); +imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); +intmax_t strtoimax(const char* restrict nptr, char** restrict endptr, int base); +uintmax_t strtoumax(const char* restrict nptr, char** restrict endptr, int base); +intmax_t wcstoimax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base); +uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base); + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#include_next + +#ifdef __cplusplus + +#include + +#undef imaxabs +#undef imaxdiv + +#endif // __cplusplus + +#endif // _LIBCPP_INTTYPES_H diff --git a/headers/libs/libc++/iomanip b/headers/libs/libc++/iomanip new file mode 100644 index 0000000000..a5042c7df8 --- /dev/null +++ b/headers/libs/libc++/iomanip @@ -0,0 +1,654 @@ +// -*- C++ -*- +//===--------------------------- iomanip ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_IOMANIP +#define _LIBCPP_IOMANIP + +/* + iomanip synopsis + +namespace std { + +// types T1, T2, ... are unspecified implementation types +T1 resetiosflags(ios_base::fmtflags mask); +T2 setiosflags (ios_base::fmtflags mask); +T3 setbase(int base); +template T4 setfill(charT c); +T5 setprecision(int n); +T6 setw(int n); +template T7 get_money(moneyT& mon, bool intl = false); +template T8 put_money(const moneyT& mon, bool intl = false); +template T9 get_time(struct tm* tmb, const charT* fmt); +template T10 put_time(const struct tm* tmb, const charT* fmt); + +template + T11 quoted(const charT* s, charT delim=charT('"'), charT escape=charT('\\')); // C++14 + +template + T12 quoted(const basic_string& s, + charT delim=charT('"'), charT escape=charT('\\')); // C++14 + +template + T13 quoted(basic_string& s, + charT delim=charT('"'), charT escape=charT('\\')); // C++14 + +} // std + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// resetiosflags + +class __iom_t1 +{ + ios_base::fmtflags __mask_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __iom_t1(ios_base::fmtflags __m) : __mask_(__m) {} + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t1& __x) + { + __is.unsetf(__x.__mask_); + return __is; + } + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t1& __x) + { + __os.unsetf(__x.__mask_); + return __os; + } +}; + +inline _LIBCPP_INLINE_VISIBILITY +__iom_t1 +resetiosflags(ios_base::fmtflags __mask) +{ + return __iom_t1(__mask); +} + +// setiosflags + +class __iom_t2 +{ + ios_base::fmtflags __mask_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __iom_t2(ios_base::fmtflags __m) : __mask_(__m) {} + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t2& __x) + { + __is.setf(__x.__mask_); + return __is; + } + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t2& __x) + { + __os.setf(__x.__mask_); + return __os; + } +}; + +inline _LIBCPP_INLINE_VISIBILITY +__iom_t2 +setiosflags(ios_base::fmtflags __mask) +{ + return __iom_t2(__mask); +} + +// setbase + +class __iom_t3 +{ + int __base_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __iom_t3(int __b) : __base_(__b) {} + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t3& __x) + { + __is.setf(__x.__base_ == 8 ? ios_base::oct : + __x.__base_ == 10 ? ios_base::dec : + __x.__base_ == 16 ? ios_base::hex : + ios_base::fmtflags(0), ios_base::basefield); + return __is; + } + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t3& __x) + { + __os.setf(__x.__base_ == 8 ? ios_base::oct : + __x.__base_ == 10 ? ios_base::dec : + __x.__base_ == 16 ? ios_base::hex : + ios_base::fmtflags(0), ios_base::basefield); + return __os; + } +}; + +inline _LIBCPP_INLINE_VISIBILITY +__iom_t3 +setbase(int __base) +{ + return __iom_t3(__base); +} + +// setfill + +template +class __iom_t4 +{ + _CharT __fill_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __iom_t4(_CharT __c) : __fill_(__c) {} + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t4& __x) + { + __os.fill(__x.__fill_); + return __os; + } +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +__iom_t4<_CharT> +setfill(_CharT __c) +{ + return __iom_t4<_CharT>(__c); +} + +// setprecision + +class __iom_t5 +{ + int __n_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __iom_t5(int __n) : __n_(__n) {} + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t5& __x) + { + __is.precision(__x.__n_); + return __is; + } + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t5& __x) + { + __os.precision(__x.__n_); + return __os; + } +}; + +inline _LIBCPP_INLINE_VISIBILITY +__iom_t5 +setprecision(int __n) +{ + return __iom_t5(__n); +} + +// setw + +class __iom_t6 +{ + int __n_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __iom_t6(int __n) : __n_(__n) {} + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t6& __x) + { + __is.width(__x.__n_); + return __is; + } + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t6& __x) + { + __os.width(__x.__n_); + return __os; + } +}; + +inline _LIBCPP_INLINE_VISIBILITY +__iom_t6 +setw(int __n) +{ + return __iom_t6(__n); +} + +// get_money + +template class __iom_t7; + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x); + +template +class __iom_t7 +{ + _MoneyT& __mon_; + bool __intl_; +public: + _LIBCPP_INLINE_VISIBILITY + __iom_t7(_MoneyT& __mon, bool __intl) + : __mon_(__mon), __intl_(__intl) {} + + template + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_Mp>& __x); +}; + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typename basic_istream<_CharT, _Traits>::sentry __s(__is); + if (__s) + { + typedef istreambuf_iterator<_CharT, _Traits> _Ip; + typedef money_get<_CharT, _Ip> _Fp; + ios_base::iostate __err = ios_base::goodbit; + const _Fp& __mf = use_facet<_Fp>(__is.getloc()); + __mf.get(_Ip(__is), _Ip(), __x.__intl_, __is, __err, __x.__mon_); + __is.setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __is.__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __is; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__iom_t7<_MoneyT> +get_money(_MoneyT& __mon, bool __intl = false) +{ + return __iom_t7<_MoneyT>(__mon, __intl); +} + +// put_money + +template class __iom_t8; + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x); + +template +class __iom_t8 +{ + const _MoneyT& __mon_; + bool __intl_; +public: + _LIBCPP_INLINE_VISIBILITY + __iom_t8(const _MoneyT& __mon, bool __intl) + : __mon_(__mon), __intl_(__intl) {} + + template + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_Mp>& __x); +}; + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typename basic_ostream<_CharT, _Traits>::sentry __s(__os); + if (__s) + { + typedef ostreambuf_iterator<_CharT, _Traits> _Op; + typedef money_put<_CharT, _Op> _Fp; + const _Fp& __mf = use_facet<_Fp>(__os.getloc()); + if (__mf.put(_Op(__os), __x.__intl_, __os, __os.fill(), __x.__mon_).failed()) + __os.setstate(ios_base::badbit); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __os.__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __os; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__iom_t8<_MoneyT> +put_money(const _MoneyT& __mon, bool __intl = false) +{ + return __iom_t8<_MoneyT>(__mon, __intl); +} + +// get_time + +template class __iom_t9; + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x); + +template +class __iom_t9 +{ + tm* __tm_; + const _CharT* __fmt_; +public: + _LIBCPP_INLINE_VISIBILITY + __iom_t9(tm* __tm, const _CharT* __fmt) + : __tm_(__tm), __fmt_(__fmt) {} + + template + friend + basic_istream<_Cp, _Traits>& + operator>>(basic_istream<_Cp, _Traits>& __is, const __iom_t9<_Cp>& __x); +}; + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typename basic_istream<_CharT, _Traits>::sentry __s(__is); + if (__s) + { + typedef istreambuf_iterator<_CharT, _Traits> _Ip; + typedef time_get<_CharT, _Ip> _Fp; + ios_base::iostate __err = ios_base::goodbit; + const _Fp& __tf = use_facet<_Fp>(__is.getloc()); + __tf.get(_Ip(__is), _Ip(), __is, __err, __x.__tm_, + __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_)); + __is.setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __is.__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __is; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__iom_t9<_CharT> +get_time(tm* __tm, const _CharT* __fmt) +{ + return __iom_t9<_CharT>(__tm, __fmt); +} + +// put_time + +template class __iom_t10; + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x); + +template +class __iom_t10 +{ + const tm* __tm_; + const _CharT* __fmt_; +public: + _LIBCPP_INLINE_VISIBILITY + __iom_t10(const tm* __tm, const _CharT* __fmt) + : __tm_(__tm), __fmt_(__fmt) {} + + template + friend + basic_ostream<_Cp, _Traits>& + operator<<(basic_ostream<_Cp, _Traits>& __os, const __iom_t10<_Cp>& __x); +}; + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typename basic_ostream<_CharT, _Traits>::sentry __s(__os); + if (__s) + { + typedef ostreambuf_iterator<_CharT, _Traits> _Op; + typedef time_put<_CharT, _Op> _Fp; + const _Fp& __tf = use_facet<_Fp>(__os.getloc()); + if (__tf.put(_Op(__os), __os, __os.fill(), __x.__tm_, + __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_)).failed()) + __os.setstate(ios_base::badbit); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __os.__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __os; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__iom_t10<_CharT> +put_time(const tm* __tm, const _CharT* __fmt) +{ + return __iom_t10<_CharT>(__tm, __fmt); +} + +#if _LIBCPP_STD_VER > 11 + +template +std::basic_ostream<_CharT, _Traits> & +__quoted_output ( basic_ostream<_CharT, _Traits> &__os, + _ForwardIterator __first, _ForwardIterator __last, _CharT __delim, _CharT __escape ) +{ + _VSTD::basic_string<_CharT, _Traits> __str; + __str.push_back(__delim); + for ( ; __first != __last; ++ __first ) + { + if (_Traits::eq (*__first, __escape) || _Traits::eq (*__first, __delim)) + __str.push_back(__escape); + __str.push_back(*__first); + } + __str.push_back(__delim); + return __put_character_sequence(__os, __str.data(), __str.size()); +} + +template +basic_istream<_CharT, _Traits> & +__quoted_input ( basic_istream<_CharT, _Traits> &__is, _String & __string, _CharT __delim, _CharT __escape ) +{ + __string.clear (); + _CharT __c; + __is >> __c; + if ( __is.fail ()) + return __is; + + if (!_Traits::eq (__c, __delim)) // no delimiter, read the whole string + { + __is.unget (); + __is >> __string; + return __is; + } + + __save_flags<_CharT, _Traits> sf(__is); + noskipws (__is); + while (true) + { + __is >> __c; + if ( __is.fail ()) + break; + if (_Traits::eq (__c, __escape)) + { + __is >> __c; + if ( __is.fail ()) + break; + } + else if (_Traits::eq (__c, __delim)) + break; + __string.push_back ( __c ); + } + return __is; +} + + +template > +struct __quoted_output_proxy +{ + _Iter __first; + _Iter __last; + _CharT __delim; + _CharT __escape; + + __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e) + : __first(__f), __last(__l), __delim(__d), __escape(__e) {} + // This would be a nice place for a string_ref +}; + +template +basic_ostream<_CharT, _Traits>& operator<<( + basic_ostream<_CharT, _Traits>& __os, + const __quoted_output_proxy<_CharT, _Iter, _Traits> & __proxy) +{ + return __quoted_output (__os, __proxy.__first, __proxy.__last, __proxy.__delim, __proxy.__escape); +} + +template +struct __quoted_proxy +{ + basic_string<_CharT, _Traits, _Allocator> &__string; + _CharT __delim; + _CharT __escape; + + __quoted_proxy(basic_string<_CharT, _Traits, _Allocator> &__s, _CharT __d, _CharT __e) + : __string(__s), __delim(__d), __escape(__e) {} +}; + +template +_LIBCPP_INLINE_VISIBILITY +basic_ostream<_CharT, _Traits>& operator<<( + basic_ostream<_CharT, _Traits>& __os, + const __quoted_proxy<_CharT, _Traits, _Allocator> & __proxy) +{ + return __quoted_output (__os, __proxy.__string.cbegin (), __proxy.__string.cend (), __proxy.__delim, __proxy.__escape); +} + +// extractor for non-const basic_string& proxies +template +_LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& operator>>( + basic_istream<_CharT, _Traits>& __is, + const __quoted_proxy<_CharT, _Traits, _Allocator> & __proxy) +{ + return __quoted_input ( __is, __proxy.__string, __proxy.__delim, __proxy.__escape ); +} + + +template +_LIBCPP_INLINE_VISIBILITY +__quoted_output_proxy<_CharT, const _CharT *> +quoted ( const _CharT *__s, _CharT __delim = _CharT('"'), _CharT __escape =_CharT('\\')) +{ + const _CharT *__end = __s; + while ( *__end ) ++__end; + return __quoted_output_proxy<_CharT, const _CharT *> ( __s, __end, __delim, __escape ); +} + +template +_LIBCPP_INLINE_VISIBILITY +__quoted_output_proxy<_CharT, typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> +quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +{ + return __quoted_output_proxy<_CharT, + typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> + ( __s.cbegin(), __s.cend (), __delim, __escape ); +} + +template +__quoted_proxy<_CharT, _Traits, _Allocator> +quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +{ + return __quoted_proxy<_CharT, _Traits, _Allocator>( __s, __delim, __escape ); +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_IOMANIP diff --git a/headers/libs/libc++/ios b/headers/libs/libc++/ios new file mode 100644 index 0000000000..1deb5f613c --- /dev/null +++ b/headers/libs/libc++/ios @@ -0,0 +1,1028 @@ +// -*- C++ -*- +//===---------------------------- ios -------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_IOS +#define _LIBCPP_IOS + +/* + ios synopsis + +#include + +namespace std +{ + +typedef OFF_T streamoff; +typedef SZ_T streamsize; +template class fpos; + +class ios_base +{ +public: + class failure; + + typedef T1 fmtflags; + static constexpr fmtflags boolalpha; + static constexpr fmtflags dec; + static constexpr fmtflags fixed; + static constexpr fmtflags hex; + static constexpr fmtflags internal; + static constexpr fmtflags left; + static constexpr fmtflags oct; + static constexpr fmtflags right; + static constexpr fmtflags scientific; + static constexpr fmtflags showbase; + static constexpr fmtflags showpoint; + static constexpr fmtflags showpos; + static constexpr fmtflags skipws; + static constexpr fmtflags unitbuf; + static constexpr fmtflags uppercase; + static constexpr fmtflags adjustfield; + static constexpr fmtflags basefield; + static constexpr fmtflags floatfield; + + typedef T2 iostate; + static constexpr iostate badbit; + static constexpr iostate eofbit; + static constexpr iostate failbit; + static constexpr iostate goodbit; + + typedef T3 openmode; + static constexpr openmode app; + static constexpr openmode ate; + static constexpr openmode binary; + static constexpr openmode in; + static constexpr openmode out; + static constexpr openmode trunc; + + typedef T4 seekdir; + static constexpr seekdir beg; + static constexpr seekdir cur; + static constexpr seekdir end; + + class Init; + + // 27.5.2.2 fmtflags state: + fmtflags flags() const; + fmtflags flags(fmtflags fmtfl); + fmtflags setf(fmtflags fmtfl); + fmtflags setf(fmtflags fmtfl, fmtflags mask); + void unsetf(fmtflags mask); + + streamsize precision() const; + streamsize precision(streamsize prec); + streamsize width() const; + streamsize width(streamsize wide); + + // 27.5.2.3 locales: + locale imbue(const locale& loc); + locale getloc() const; + + // 27.5.2.5 storage: + static int xalloc(); + long& iword(int index); + void*& pword(int index); + + // destructor + virtual ~ios_base(); + + // 27.5.2.6 callbacks; + enum event { erase_event, imbue_event, copyfmt_event }; + typedef void (*event_callback)(event, ios_base&, int index); + void register_callback(event_callback fn, int index); + + ios_base(const ios_base&) = delete; + ios_base& operator=(const ios_base&) = delete; + + static bool sync_with_stdio(bool sync = true); + +protected: + ios_base(); +}; + +template > +class basic_ios + : public ios_base +{ +public: + // types: + typedef charT char_type; + typedef typename traits::int_type int_type; // removed in C++17 + typedef typename traits::pos_type pos_type; // removed in C++17 + typedef typename traits::off_type off_type; // removed in C++17 + typedef traits traits_type; + + operator unspecified-bool-type() const; + bool operator!() const; + iostate rdstate() const; + void clear(iostate state = goodbit); + void setstate(iostate state); + bool good() const; + bool eof() const; + bool fail() const; + bool bad() const; + + iostate exceptions() const; + void exceptions(iostate except); + + // 27.5.4.1 Constructor/destructor: + explicit basic_ios(basic_streambuf* sb); + virtual ~basic_ios(); + + // 27.5.4.2 Members: + basic_ostream* tie() const; + basic_ostream* tie(basic_ostream* tiestr); + + basic_streambuf* rdbuf() const; + basic_streambuf* rdbuf(basic_streambuf* sb); + + basic_ios& copyfmt(const basic_ios& rhs); + + char_type fill() const; + char_type fill(char_type ch); + + locale imbue(const locale& loc); + + char narrow(char_type c, char dfault) const; + char_type widen(char c) const; + + basic_ios(const basic_ios& ) = delete; + basic_ios& operator=(const basic_ios&) = delete; + +protected: + basic_ios(); + void init(basic_streambuf* sb); + void move(basic_ios& rhs); + void swap(basic_ios& rhs) noexcept; + void set_rdbuf(basic_streambuf* sb); +}; + +// 27.5.5, manipulators: +ios_base& boolalpha (ios_base& str); +ios_base& noboolalpha(ios_base& str); +ios_base& showbase (ios_base& str); +ios_base& noshowbase (ios_base& str); +ios_base& showpoint (ios_base& str); +ios_base& noshowpoint(ios_base& str); +ios_base& showpos (ios_base& str); +ios_base& noshowpos (ios_base& str); +ios_base& skipws (ios_base& str); +ios_base& noskipws (ios_base& str); +ios_base& uppercase (ios_base& str); +ios_base& nouppercase(ios_base& str); +ios_base& unitbuf (ios_base& str); +ios_base& nounitbuf (ios_base& str); + +// 27.5.5.2 adjustfield: +ios_base& internal (ios_base& str); +ios_base& left (ios_base& str); +ios_base& right (ios_base& str); + +// 27.5.5.3 basefield: +ios_base& dec (ios_base& str); +ios_base& hex (ios_base& str); +ios_base& oct (ios_base& str); + +// 27.5.5.4 floatfield: +ios_base& fixed (ios_base& str); +ios_base& scientific (ios_base& str); +ios_base& hexfloat (ios_base& str); +ios_base& defaultfloat(ios_base& str); + +// 27.5.5.5 error reporting: +enum class io_errc +{ + stream = 1 +}; + +concept_map ErrorCodeEnum { }; +error_code make_error_code(io_errc e) noexcept; +error_condition make_error_condition(io_errc e) noexcept; +storage-class-specifier const error_category& iostream_category() noexcept; + +} // std + +*/ + +#include <__config> +#include +#include <__locale> +#include + +#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) +#include // for __xindex_ +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +typedef ptrdiff_t streamsize; + +class _LIBCPP_TYPE_VIS ios_base +{ +public: + class _LIBCPP_TYPE_VIS failure; + + typedef unsigned int fmtflags; + static const fmtflags boolalpha = 0x0001; + static const fmtflags dec = 0x0002; + static const fmtflags fixed = 0x0004; + static const fmtflags hex = 0x0008; + static const fmtflags internal = 0x0010; + static const fmtflags left = 0x0020; + static const fmtflags oct = 0x0040; + static const fmtflags right = 0x0080; + static const fmtflags scientific = 0x0100; + static const fmtflags showbase = 0x0200; + static const fmtflags showpoint = 0x0400; + static const fmtflags showpos = 0x0800; + static const fmtflags skipws = 0x1000; + static const fmtflags unitbuf = 0x2000; + static const fmtflags uppercase = 0x4000; + static const fmtflags adjustfield = left | right | internal; + static const fmtflags basefield = dec | oct | hex; + static const fmtflags floatfield = scientific | fixed; + + typedef unsigned int iostate; + static const iostate badbit = 0x1; + static const iostate eofbit = 0x2; + static const iostate failbit = 0x4; + static const iostate goodbit = 0x0; + + typedef unsigned int openmode; + static const openmode app = 0x01; + static const openmode ate = 0x02; + static const openmode binary = 0x04; + static const openmode in = 0x08; + static const openmode out = 0x10; + static const openmode trunc = 0x20; + + enum seekdir {beg, cur, end}; + +#if _LIBCPP_STD_VER <= 14 + typedef iostate io_state; + typedef openmode open_mode; + typedef seekdir seek_dir; + + typedef _VSTD::streamoff streamoff; + typedef _VSTD::streampos streampos; +#endif + + class _LIBCPP_TYPE_VIS Init; + + // 27.5.2.2 fmtflags state: + _LIBCPP_INLINE_VISIBILITY fmtflags flags() const; + _LIBCPP_INLINE_VISIBILITY fmtflags flags(fmtflags __fmtfl); + _LIBCPP_INLINE_VISIBILITY fmtflags setf(fmtflags __fmtfl); + _LIBCPP_INLINE_VISIBILITY fmtflags setf(fmtflags __fmtfl, fmtflags __mask); + _LIBCPP_INLINE_VISIBILITY void unsetf(fmtflags __mask); + + _LIBCPP_INLINE_VISIBILITY streamsize precision() const; + _LIBCPP_INLINE_VISIBILITY streamsize precision(streamsize __prec); + _LIBCPP_INLINE_VISIBILITY streamsize width() const; + _LIBCPP_INLINE_VISIBILITY streamsize width(streamsize __wide); + + // 27.5.2.3 locales: + locale imbue(const locale& __loc); + locale getloc() const; + + // 27.5.2.5 storage: + static int xalloc(); + long& iword(int __index); + void*& pword(int __index); + + // destructor + virtual ~ios_base(); + + // 27.5.2.6 callbacks; + enum event { erase_event, imbue_event, copyfmt_event }; + typedef void (*event_callback)(event, ios_base&, int __index); + void register_callback(event_callback __fn, int __index); + +private: + ios_base(const ios_base&); // = delete; + ios_base& operator=(const ios_base&); // = delete; + +public: + static bool sync_with_stdio(bool __sync = true); + + _LIBCPP_INLINE_VISIBILITY iostate rdstate() const; + void clear(iostate __state = goodbit); + _LIBCPP_INLINE_VISIBILITY void setstate(iostate __state); + + _LIBCPP_INLINE_VISIBILITY bool good() const; + _LIBCPP_INLINE_VISIBILITY bool eof() const; + _LIBCPP_INLINE_VISIBILITY bool fail() const; + _LIBCPP_INLINE_VISIBILITY bool bad() const; + + _LIBCPP_INLINE_VISIBILITY iostate exceptions() const; + _LIBCPP_INLINE_VISIBILITY void exceptions(iostate __iostate); + + void __set_badbit_and_consider_rethrow(); + void __set_failbit_and_consider_rethrow(); + +protected: + _LIBCPP_INLINE_VISIBILITY + ios_base() {// purposefully does no initialization + } + + void init(void* __sb); + _LIBCPP_ALWAYS_INLINE void* rdbuf() const {return __rdbuf_;} + + _LIBCPP_ALWAYS_INLINE + void rdbuf(void* __sb) + { + __rdbuf_ = __sb; + clear(); + } + + void __call_callbacks(event); + void copyfmt(const ios_base&); + void move(ios_base&); + void swap(ios_base&) _NOEXCEPT; + + _LIBCPP_ALWAYS_INLINE + void set_rdbuf(void* __sb) + { + __rdbuf_ = __sb; + } + +private: + // All data members must be scalars + fmtflags __fmtflags_; + streamsize __precision_; + streamsize __width_; + iostate __rdstate_; + iostate __exceptions_; + void* __rdbuf_; + void* __loc_; + event_callback* __fn_; + int* __index_; + size_t __event_size_; + size_t __event_cap_; +// TODO(EricWF): Enable this for both Clang and GCC. Currently it is only +// enabled with clang. +#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS) + static atomic __xindex_; +#else + static int __xindex_; +#endif + long* __iarray_; + size_t __iarray_size_; + size_t __iarray_cap_; + void** __parray_; + size_t __parray_size_; + size_t __parray_cap_; +}; + +//enum class io_errc +_LIBCPP_DECLARE_STRONG_ENUM(io_errc) +{ + stream = 1 +}; +_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(io_errc) + +template <> +struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum : public true_type { }; + +#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS +template <> +struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum : public true_type { }; +#endif + +_LIBCPP_FUNC_VIS +const error_category& iostream_category() _NOEXCEPT; + +inline _LIBCPP_INLINE_VISIBILITY +error_code +make_error_code(io_errc __e) _NOEXCEPT +{ + return error_code(static_cast(__e), iostream_category()); +} + +inline _LIBCPP_INLINE_VISIBILITY +error_condition +make_error_condition(io_errc __e) _NOEXCEPT +{ + return error_condition(static_cast(__e), iostream_category()); +} + +class _LIBCPP_EXCEPTION_ABI ios_base::failure + : public system_error +{ +public: + explicit failure(const string& __msg, const error_code& __ec = io_errc::stream); + explicit failure(const char* __msg, const error_code& __ec = io_errc::stream); + virtual ~failure() throw(); +}; + +class _LIBCPP_TYPE_VIS ios_base::Init +{ +public: + Init(); + ~Init(); +}; + +// fmtflags + +inline _LIBCPP_INLINE_VISIBILITY +ios_base::fmtflags +ios_base::flags() const +{ + return __fmtflags_; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base::fmtflags +ios_base::flags(fmtflags __fmtfl) +{ + fmtflags __r = __fmtflags_; + __fmtflags_ = __fmtfl; + return __r; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base::fmtflags +ios_base::setf(fmtflags __fmtfl) +{ + fmtflags __r = __fmtflags_; + __fmtflags_ |= __fmtfl; + return __r; +} + +inline _LIBCPP_INLINE_VISIBILITY +void +ios_base::unsetf(fmtflags __mask) +{ + __fmtflags_ &= ~__mask; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base::fmtflags +ios_base::setf(fmtflags __fmtfl, fmtflags __mask) +{ + fmtflags __r = __fmtflags_; + unsetf(__mask); + __fmtflags_ |= __fmtfl & __mask; + return __r; +} + +// precision + +inline _LIBCPP_INLINE_VISIBILITY +streamsize +ios_base::precision() const +{ + return __precision_; +} + +inline _LIBCPP_INLINE_VISIBILITY +streamsize +ios_base::precision(streamsize __prec) +{ + streamsize __r = __precision_; + __precision_ = __prec; + return __r; +} + +// width + +inline _LIBCPP_INLINE_VISIBILITY +streamsize +ios_base::width() const +{ + return __width_; +} + +inline _LIBCPP_INLINE_VISIBILITY +streamsize +ios_base::width(streamsize __wide) +{ + streamsize __r = __width_; + __width_ = __wide; + return __r; +} + +// iostate + +inline _LIBCPP_INLINE_VISIBILITY +ios_base::iostate +ios_base::rdstate() const +{ + return __rdstate_; +} + +inline _LIBCPP_INLINE_VISIBILITY +void +ios_base::setstate(iostate __state) +{ + clear(__rdstate_ | __state); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool +ios_base::good() const +{ + return __rdstate_ == 0; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool +ios_base::eof() const +{ + return (__rdstate_ & eofbit) != 0; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool +ios_base::fail() const +{ + return (__rdstate_ & (failbit | badbit)) != 0; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool +ios_base::bad() const +{ + return (__rdstate_ & badbit) != 0; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base::iostate +ios_base::exceptions() const +{ + return __exceptions_; +} + +inline _LIBCPP_INLINE_VISIBILITY +void +ios_base::exceptions(iostate __iostate) +{ + __exceptions_ = __iostate; + clear(__rdstate_); +} + +template +class _LIBCPP_TYPE_VIS_ONLY basic_ios + : public ios_base +{ +public: + // types: + typedef _CharT char_type; + typedef _Traits traits_type; + + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + _LIBCPP_ALWAYS_INLINE + _LIBCPP_EXPLICIT + operator bool() const {return !fail();} + _LIBCPP_ALWAYS_INLINE bool operator!() const {return fail();} + _LIBCPP_ALWAYS_INLINE iostate rdstate() const {return ios_base::rdstate();} + _LIBCPP_ALWAYS_INLINE void clear(iostate __state = goodbit) {ios_base::clear(__state);} + _LIBCPP_ALWAYS_INLINE void setstate(iostate __state) {ios_base::setstate(__state);} + _LIBCPP_ALWAYS_INLINE bool good() const {return ios_base::good();} + _LIBCPP_ALWAYS_INLINE bool eof() const {return ios_base::eof();} + _LIBCPP_ALWAYS_INLINE bool fail() const {return ios_base::fail();} + _LIBCPP_ALWAYS_INLINE bool bad() const {return ios_base::bad();} + + _LIBCPP_ALWAYS_INLINE iostate exceptions() const {return ios_base::exceptions();} + _LIBCPP_ALWAYS_INLINE void exceptions(iostate __iostate) {ios_base::exceptions(__iostate);} + + // 27.5.4.1 Constructor/destructor: + _LIBCPP_INLINE_VISIBILITY + explicit basic_ios(basic_streambuf* __sb); + virtual ~basic_ios(); + + // 27.5.4.2 Members: + _LIBCPP_INLINE_VISIBILITY + basic_ostream* tie() const; + _LIBCPP_INLINE_VISIBILITY + basic_ostream* tie(basic_ostream* __tiestr); + + _LIBCPP_INLINE_VISIBILITY + basic_streambuf* rdbuf() const; + _LIBCPP_INLINE_VISIBILITY + basic_streambuf* rdbuf(basic_streambuf* __sb); + + basic_ios& copyfmt(const basic_ios& __rhs); + + _LIBCPP_INLINE_VISIBILITY + char_type fill() const; + _LIBCPP_INLINE_VISIBILITY + char_type fill(char_type __ch); + + _LIBCPP_INLINE_VISIBILITY + locale imbue(const locale& __loc); + + _LIBCPP_INLINE_VISIBILITY + char narrow(char_type __c, char __dfault) const; + _LIBCPP_INLINE_VISIBILITY + char_type widen(char __c) const; + +protected: + _LIBCPP_ALWAYS_INLINE + basic_ios() {// purposefully does no initialization + } + _LIBCPP_INLINE_VISIBILITY + void init(basic_streambuf* __sb); + + _LIBCPP_INLINE_VISIBILITY + void move(basic_ios& __rhs); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_ALWAYS_INLINE + void move(basic_ios&& __rhs) {move(__rhs);} +#endif + _LIBCPP_INLINE_VISIBILITY + void swap(basic_ios& __rhs) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + void set_rdbuf(basic_streambuf* __sb); +private: + basic_ostream* __tie_; + mutable int_type __fill_; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ios<_CharT, _Traits>::basic_ios(basic_streambuf* __sb) +{ + init(__sb); +} + +template +basic_ios<_CharT, _Traits>::~basic_ios() +{ +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +basic_ios<_CharT, _Traits>::init(basic_streambuf* __sb) +{ + ios_base::init(__sb); + __tie_ = 0; + __fill_ = traits_type::eof(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ostream<_CharT, _Traits>* +basic_ios<_CharT, _Traits>::tie() const +{ + return __tie_; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ostream<_CharT, _Traits>* +basic_ios<_CharT, _Traits>::tie(basic_ostream* __tiestr) +{ + basic_ostream* __r = __tie_; + __tie_ = __tiestr; + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_streambuf<_CharT, _Traits>* +basic_ios<_CharT, _Traits>::rdbuf() const +{ + return static_cast*>(ios_base::rdbuf()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_streambuf<_CharT, _Traits>* +basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf* __sb) +{ + basic_streambuf* __r = rdbuf(); + ios_base::rdbuf(__sb); + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +locale +basic_ios<_CharT, _Traits>::imbue(const locale& __loc) +{ + locale __r = getloc(); + ios_base::imbue(__loc); + if (rdbuf()) + rdbuf()->pubimbue(__loc); + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +char +basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const +{ + return use_facet >(getloc()).narrow(__c, __dfault); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_CharT +basic_ios<_CharT, _Traits>::widen(char __c) const +{ + return use_facet >(getloc()).widen(__c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_CharT +basic_ios<_CharT, _Traits>::fill() const +{ + if (traits_type::eq_int_type(traits_type::eof(), __fill_)) + __fill_ = widen(' '); + return __fill_; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_CharT +basic_ios<_CharT, _Traits>::fill(char_type __ch) +{ + char_type __r = __fill_; + __fill_ = __ch; + return __r; +} + +template +basic_ios<_CharT, _Traits>& +basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs) +{ + if (this != &__rhs) + { + __call_callbacks(erase_event); + ios_base::copyfmt(__rhs); + __tie_ = __rhs.__tie_; + __fill_ = __rhs.__fill_; + __call_callbacks(copyfmt_event); + exceptions(__rhs.exceptions()); + } + return *this; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +basic_ios<_CharT, _Traits>::move(basic_ios& __rhs) +{ + ios_base::move(__rhs); + __tie_ = __rhs.__tie_; + __rhs.__tie_ = 0; + __fill_ = __rhs.__fill_; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +basic_ios<_CharT, _Traits>::swap(basic_ios& __rhs) _NOEXCEPT +{ + ios_base::swap(__rhs); + _VSTD::swap(__tie_, __rhs.__tie_); + _VSTD::swap(__fill_, __rhs.__fill_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +basic_ios<_CharT, _Traits>::set_rdbuf(basic_streambuf* __sb) +{ + ios_base::set_rdbuf(__sb); +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +boolalpha(ios_base& __str) +{ + __str.setf(ios_base::boolalpha); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +noboolalpha(ios_base& __str) +{ + __str.unsetf(ios_base::boolalpha); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +showbase(ios_base& __str) +{ + __str.setf(ios_base::showbase); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +noshowbase(ios_base& __str) +{ + __str.unsetf(ios_base::showbase); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +showpoint(ios_base& __str) +{ + __str.setf(ios_base::showpoint); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +noshowpoint(ios_base& __str) +{ + __str.unsetf(ios_base::showpoint); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +showpos(ios_base& __str) +{ + __str.setf(ios_base::showpos); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +noshowpos(ios_base& __str) +{ + __str.unsetf(ios_base::showpos); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +skipws(ios_base& __str) +{ + __str.setf(ios_base::skipws); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +noskipws(ios_base& __str) +{ + __str.unsetf(ios_base::skipws); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +uppercase(ios_base& __str) +{ + __str.setf(ios_base::uppercase); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +nouppercase(ios_base& __str) +{ + __str.unsetf(ios_base::uppercase); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +unitbuf(ios_base& __str) +{ + __str.setf(ios_base::unitbuf); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +nounitbuf(ios_base& __str) +{ + __str.unsetf(ios_base::unitbuf); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +internal(ios_base& __str) +{ + __str.setf(ios_base::internal, ios_base::adjustfield); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +left(ios_base& __str) +{ + __str.setf(ios_base::left, ios_base::adjustfield); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +right(ios_base& __str) +{ + __str.setf(ios_base::right, ios_base::adjustfield); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +dec(ios_base& __str) +{ + __str.setf(ios_base::dec, ios_base::basefield); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +hex(ios_base& __str) +{ + __str.setf(ios_base::hex, ios_base::basefield); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +oct(ios_base& __str) +{ + __str.setf(ios_base::oct, ios_base::basefield); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +fixed(ios_base& __str) +{ + __str.setf(ios_base::fixed, ios_base::floatfield); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +scientific(ios_base& __str) +{ + __str.setf(ios_base::scientific, ios_base::floatfield); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +hexfloat(ios_base& __str) +{ + __str.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield); + return __str; +} + +inline _LIBCPP_INLINE_VISIBILITY +ios_base& +defaultfloat(ios_base& __str) +{ + __str.unsetf(ios_base::floatfield); + return __str; +} + +template +class __save_flags +{ + typedef basic_ios<_CharT, _Traits> __stream_type; + typedef typename __stream_type::fmtflags fmtflags; + + __stream_type& __stream_; + fmtflags __fmtflags_; + _CharT __fill_; + + __save_flags(const __save_flags&); + __save_flags& operator=(const __save_flags&); +public: + _LIBCPP_INLINE_VISIBILITY + explicit __save_flags(__stream_type& __stream) + : __stream_(__stream), + __fmtflags_(__stream.flags()), + __fill_(__stream.fill()) + {} + _LIBCPP_INLINE_VISIBILITY + ~__save_flags() + { + __stream_.flags(__fmtflags_); + __stream_.fill(__fill_); + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_IOS diff --git a/headers/libs/libc++/iosfwd b/headers/libs/libc++/iosfwd new file mode 100644 index 0000000000..eccfd349a4 --- /dev/null +++ b/headers/libs/libc++/iosfwd @@ -0,0 +1,199 @@ +// -*- C++ -*- +//===--------------------------- iosfwd -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_IOSFWD +#define _LIBCPP_IOSFWD + +/* + iosfwd synopsis + +namespace std +{ + +template struct char_traits; +template class allocator; + +class ios_base; +template > class basic_ios; + +template > class basic_streambuf; +template > class basic_istream; +template > class basic_ostream; +template > class basic_iostream; + +template , class Allocator = allocator > + class basic_stringbuf; +template , class Allocator = allocator > + class basic_istringstream; +template , class Allocator = allocator > + class basic_ostringstream; +template , class Allocator = allocator > + class basic_stringstream; + +template > class basic_filebuf; +template > class basic_ifstream; +template > class basic_ofstream; +template > class basic_fstream; + +template > class istreambuf_iterator; +template > class ostreambuf_iterator; + +typedef basic_ios ios; +typedef basic_ios wios; + +typedef basic_streambuf streambuf; +typedef basic_istream istream; +typedef basic_ostream ostream; +typedef basic_iostream iostream; + +typedef basic_stringbuf stringbuf; +typedef basic_istringstream istringstream; +typedef basic_ostringstream ostringstream; +typedef basic_stringstream stringstream; + +typedef basic_filebuf filebuf; +typedef basic_ifstream ifstream; +typedef basic_ofstream ofstream; +typedef basic_fstream fstream; + +typedef basic_streambuf wstreambuf; +typedef basic_istream wistream; +typedef basic_ostream wostream; +typedef basic_iostream wiostream; + +typedef basic_stringbuf wstringbuf; +typedef basic_istringstream wistringstream; +typedef basic_ostringstream wostringstream; +typedef basic_stringstream wstringstream; + +typedef basic_filebuf wfilebuf; +typedef basic_ifstream wifstream; +typedef basic_ofstream wofstream; +typedef basic_fstream wfstream; + +template class fpos; +typedef fpos::state_type> streampos; +typedef fpos::state_type> wstreampos; + +} // std + +*/ + +#include <__config> +#include // for mbstate_t + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +class _LIBCPP_TYPE_VIS ios_base; + +template struct _LIBCPP_TYPE_VIS_ONLY char_traits; +template class _LIBCPP_TYPE_VIS_ONLY allocator; + +template > + class _LIBCPP_TYPE_VIS_ONLY basic_ios; + +template > + class _LIBCPP_TYPE_VIS_ONLY basic_streambuf; +template > + class _LIBCPP_TYPE_VIS_ONLY basic_istream; +template > + class _LIBCPP_TYPE_VIS_ONLY basic_ostream; +template > + class _LIBCPP_TYPE_VIS_ONLY basic_iostream; + +template , + class _Allocator = allocator<_CharT> > + class _LIBCPP_TYPE_VIS_ONLY basic_stringbuf; +template , + class _Allocator = allocator<_CharT> > + class _LIBCPP_TYPE_VIS_ONLY basic_istringstream; +template , + class _Allocator = allocator<_CharT> > + class _LIBCPP_TYPE_VIS_ONLY basic_ostringstream; +template , + class _Allocator = allocator<_CharT> > + class _LIBCPP_TYPE_VIS_ONLY basic_stringstream; + +template > + class _LIBCPP_TYPE_VIS_ONLY basic_filebuf; +template > + class _LIBCPP_TYPE_VIS_ONLY basic_ifstream; +template > + class _LIBCPP_TYPE_VIS_ONLY basic_ofstream; +template > + class _LIBCPP_TYPE_VIS_ONLY basic_fstream; + +template > + class _LIBCPP_TYPE_VIS_ONLY istreambuf_iterator; +template > + class _LIBCPP_TYPE_VIS_ONLY ostreambuf_iterator; + +typedef basic_ios ios; +typedef basic_ios wios; + +typedef basic_streambuf streambuf; +typedef basic_istream istream; +typedef basic_ostream ostream; +typedef basic_iostream iostream; + +typedef basic_stringbuf stringbuf; +typedef basic_istringstream istringstream; +typedef basic_ostringstream ostringstream; +typedef basic_stringstream stringstream; + +typedef basic_filebuf filebuf; +typedef basic_ifstream ifstream; +typedef basic_ofstream ofstream; +typedef basic_fstream fstream; + +typedef basic_streambuf wstreambuf; +typedef basic_istream wistream; +typedef basic_ostream wostream; +typedef basic_iostream wiostream; + +typedef basic_stringbuf wstringbuf; +typedef basic_istringstream wistringstream; +typedef basic_ostringstream wostringstream; +typedef basic_stringstream wstringstream; + +typedef basic_filebuf wfilebuf; +typedef basic_ifstream wifstream; +typedef basic_ofstream wofstream; +typedef basic_fstream wfstream; + +template class _LIBCPP_TYPE_VIS_ONLY fpos; +typedef fpos streampos; +typedef fpos wstreampos; +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS +typedef fpos u16streampos; +typedef fpos u32streampos; +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + +#if defined(_NEWLIB_VERSION) +// On newlib, off_t is 'long int' +typedef long int streamoff; // for char_traits in +#else +typedef long long streamoff; // for char_traits in +#endif + +template + class _Traits = char_traits<_CharT>, + class _Allocator = allocator<_CharT> > + class _LIBCPP_TYPE_VIS_ONLY basic_string; +typedef basic_string, allocator > string; +typedef basic_string, allocator > wstring; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_IOSFWD diff --git a/headers/libs/libc++/iostream b/headers/libs/libc++/iostream new file mode 100644 index 0000000000..136a849777 --- /dev/null +++ b/headers/libs/libc++/iostream @@ -0,0 +1,64 @@ +// -*- C++ -*- +//===--------------------------- iostream ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_IOSTREAM +#define _LIBCPP_IOSTREAM + +/* + iostream synopsis + +#include +#include +#include +#include + +namespace std { + +extern istream cin; +extern ostream cout; +extern ostream cerr; +extern ostream clog; +extern wistream wcin; +extern wostream wcout; +extern wostream wcerr; +extern wostream wclog; + +} // std + +*/ + +#include <__config> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_HAS_NO_STDIN +extern _LIBCPP_FUNC_VIS istream cin; +extern _LIBCPP_FUNC_VIS wistream wcin; +#endif +#ifndef _LIBCPP_HAS_NO_STDOUT +extern _LIBCPP_FUNC_VIS ostream cout; +extern _LIBCPP_FUNC_VIS wostream wcout; +#endif +extern _LIBCPP_FUNC_VIS ostream cerr; +extern _LIBCPP_FUNC_VIS wostream wcerr; +extern _LIBCPP_FUNC_VIS ostream clog; +extern _LIBCPP_FUNC_VIS wostream wclog; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_IOSTREAM diff --git a/headers/libs/libc++/istream b/headers/libs/libc++/istream new file mode 100644 index 0000000000..0bcc7eeaf6 --- /dev/null +++ b/headers/libs/libc++/istream @@ -0,0 +1,1733 @@ +// -*- C++ -*- +//===--------------------------- istream ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_ISTREAM +#define _LIBCPP_ISTREAM + +/* + istream synopsis + +template > +class basic_istream + : virtual public basic_ios +{ +public: + // types (inherited from basic_ios (27.5.4)): + typedef charT char_type; + typedef traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // 27.7.1.1.1 Constructor/destructor: + explicit basic_istream(basic_streambuf* sb); + basic_istream(basic_istream&& rhs); + virtual ~basic_istream(); + + // 27.7.1.1.2 Assign/swap: + basic_istream& operator=(basic_istream&& rhs); + void swap(basic_istream& rhs); + + // 27.7.1.1.3 Prefix/suffix: + class sentry; + + // 27.7.1.2 Formatted input: + basic_istream& operator>>(basic_istream& (*pf)(basic_istream&)); + basic_istream& operator>>(basic_ios& + (*pf)(basic_ios&)); + basic_istream& operator>>(ios_base& (*pf)(ios_base&)); + basic_istream& operator>>(basic_streambuf* sb); + basic_istream& operator>>(bool& n); + basic_istream& operator>>(short& n); + basic_istream& operator>>(unsigned short& n); + basic_istream& operator>>(int& n); + basic_istream& operator>>(unsigned int& n); + basic_istream& operator>>(long& n); + basic_istream& operator>>(unsigned long& n); + basic_istream& operator>>(long long& n); + basic_istream& operator>>(unsigned long long& n); + basic_istream& operator>>(float& f); + basic_istream& operator>>(double& f); + basic_istream& operator>>(long double& f); + basic_istream& operator>>(void*& p); + + // 27.7.1.3 Unformatted input: + streamsize gcount() const; + int_type get(); + basic_istream& get(char_type& c); + basic_istream& get(char_type* s, streamsize n); + basic_istream& get(char_type* s, streamsize n, char_type delim); + basic_istream& get(basic_streambuf& sb); + basic_istream& get(basic_streambuf& sb, char_type delim); + + basic_istream& getline(char_type* s, streamsize n); + basic_istream& getline(char_type* s, streamsize n, char_type delim); + + basic_istream& ignore(streamsize n = 1, int_type delim = traits_type::eof()); + int_type peek(); + basic_istream& read (char_type* s, streamsize n); + streamsize readsome(char_type* s, streamsize n); + + basic_istream& putback(char_type c); + basic_istream& unget(); + int sync(); + + pos_type tellg(); + basic_istream& seekg(pos_type); + basic_istream& seekg(off_type, ios_base::seekdir); +protected: + basic_istream(const basic_istream& rhs) = delete; + basic_istream(basic_istream&& rhs); + // 27.7.2.1.2 Assign/swap: + basic_istream& operator=(const basic_istream& rhs) = delete; + basic_istream& operator=(basic_istream&& rhs); + void swap(basic_istream& rhs); +}; + +// 27.7.1.2.3 character extraction templates: +template + basic_istream& operator>>(basic_istream&, charT&); + +template + basic_istream& operator>>(basic_istream&, unsigned char&); + +template + basic_istream& operator>>(basic_istream&, signed char&); + +template + basic_istream& operator>>(basic_istream&, charT*); + +template + basic_istream& operator>>(basic_istream&, unsigned char*); + +template + basic_istream& operator>>(basic_istream&, signed char*); + +template + void + swap(basic_istream& x, basic_istream& y); + +typedef basic_istream istream; +typedef basic_istream wistream; + +template > +class basic_iostream : + public basic_istream, + public basic_ostream +{ +public: + // types: + typedef charT char_type; + typedef traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // constructor/destructor + explicit basic_iostream(basic_streambuf* sb); + basic_iostream(basic_iostream&& rhs); + virtual ~basic_iostream(); + + // assign/swap + basic_iostream& operator=(basic_iostream&& rhs); + void swap(basic_iostream& rhs); +}; + +template + void + swap(basic_iostream& x, basic_iostream& y); + +typedef basic_iostream iostream; +typedef basic_iostream wiostream; + +template + basic_istream& + ws(basic_istream& is); + +template + basic_istream& + operator>>(basic_istream&& is, T& x); + +} // std + +*/ + +#include <__config> +#include + +#include <__undef_min_max> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TYPE_VIS_ONLY basic_istream + : virtual public basic_ios<_CharT, _Traits> +{ + streamsize __gc_; +public: + // types (inherited from basic_ios (27.5.4)): + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // 27.7.1.1.1 Constructor/destructor: + explicit basic_istream(basic_streambuf* __sb); + virtual ~basic_istream(); +protected: +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + basic_istream(basic_istream&& __rhs); +#endif + // 27.7.1.1.2 Assign/swap: +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + basic_istream& operator=(basic_istream&& __rhs); +#endif + void swap(basic_istream& __rhs); + +#if _LIBCPP_STD_VER > 11 +#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS + basic_istream (const basic_istream& __rhs) = delete; + basic_istream& operator=(const basic_istream& __rhs) = delete; +#else + basic_istream (const basic_istream& __rhs); // not defined + basic_istream& operator=(const basic_istream& __rhs); // not defined +#endif +#endif +public: + + // 27.7.1.1.3 Prefix/suffix: + class _LIBCPP_TYPE_VIS_ONLY sentry; + + // 27.7.1.2 Formatted input: + basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&)); + basic_istream& operator>>(basic_ios& + (*__pf)(basic_ios&)); + basic_istream& operator>>(ios_base& (*__pf)(ios_base&)); + basic_istream& operator>>(basic_streambuf* __sb); + basic_istream& operator>>(bool& __n); + basic_istream& operator>>(short& __n); + basic_istream& operator>>(unsigned short& __n); + basic_istream& operator>>(int& __n); + basic_istream& operator>>(unsigned int& __n); + basic_istream& operator>>(long& __n); + basic_istream& operator>>(unsigned long& __n); + basic_istream& operator>>(long long& __n); + basic_istream& operator>>(unsigned long long& __n); + basic_istream& operator>>(float& __f); + basic_istream& operator>>(double& __f); + basic_istream& operator>>(long double& __f); + basic_istream& operator>>(void*& __p); + + // 27.7.1.3 Unformatted input: + _LIBCPP_INLINE_VISIBILITY + streamsize gcount() const {return __gc_;} + int_type get(); + basic_istream& get(char_type& __c); + basic_istream& get(char_type* __s, streamsize __n); + basic_istream& get(char_type* __s, streamsize __n, char_type __dlm); + basic_istream& get(basic_streambuf& __sb); + basic_istream& get(basic_streambuf& __sb, char_type __dlm); + + basic_istream& getline(char_type* __s, streamsize __n); + basic_istream& getline(char_type* __s, streamsize __n, char_type __dlm); + + basic_istream& ignore(streamsize __n = 1, int_type __dlm = traits_type::eof()); + int_type peek(); + basic_istream& read (char_type* __s, streamsize __n); + streamsize readsome(char_type* __s, streamsize __n); + + basic_istream& putback(char_type __c); + basic_istream& unget(); + int sync(); + + pos_type tellg(); + basic_istream& seekg(pos_type __pos); + basic_istream& seekg(off_type __off, ios_base::seekdir __dir); +}; + +template +class _LIBCPP_TYPE_VIS_ONLY basic_istream<_CharT, _Traits>::sentry +{ + bool __ok_; + + sentry(const sentry&); // = delete; + sentry& operator=(const sentry&); // = delete; + +public: + explicit sentry(basic_istream<_CharT, _Traits>& __is, bool __noskipws = false); +// ~sentry() = default; + + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_EXPLICIT + operator bool() const {return __ok_;} +}; + +template +basic_istream<_CharT, _Traits>::sentry::sentry(basic_istream<_CharT, _Traits>& __is, + bool __noskipws) + : __ok_(false) +{ + if (__is.good()) + { + if (__is.tie()) + __is.tie()->flush(); + if (!__noskipws && (__is.flags() & ios_base::skipws)) + { + typedef istreambuf_iterator<_CharT, _Traits> _Ip; + const ctype<_CharT>& __ct = use_facet >(__is.getloc()); + _Ip __i(__is); + _Ip __eof; + for (; __i != __eof; ++__i) + if (!__ct.is(__ct.space, *__i)) + break; + if (__i == __eof) + __is.setstate(ios_base::failbit | ios_base::eofbit); + } + __ok_ = __is.good(); + } + else + __is.setstate(ios_base::failbit); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>::basic_istream(basic_streambuf* __sb) + : __gc_(0) +{ + this->init(__sb); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>::basic_istream(basic_istream&& __rhs) + : __gc_(__rhs.__gc_) +{ + __rhs.__gc_ = 0; + this->move(__rhs); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator=(basic_istream&& __rhs) +{ + swap(__rhs); + return *this; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +basic_istream<_CharT, _Traits>::~basic_istream() +{ +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +basic_istream<_CharT, _Traits>::swap(basic_istream& __rhs) +{ + _VSTD::swap(__gc_, __rhs.__gc_); + basic_ios::swap(__rhs); +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(unsigned short& __n) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this); + if (__s) + { + typedef istreambuf_iterator _Ip; + typedef num_get _Fp; + ios_base::iostate __err = ios_base::goodbit; + use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(unsigned int& __n) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this); + if (__s) + { + typedef istreambuf_iterator _Ip; + typedef num_get _Fp; + ios_base::iostate __err = ios_base::goodbit; + use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(long& __n) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this); + if (__s) + { + typedef istreambuf_iterator _Ip; + typedef num_get _Fp; + ios_base::iostate __err = ios_base::goodbit; + use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(unsigned long& __n) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this); + if (__s) + { + typedef istreambuf_iterator _Ip; + typedef num_get _Fp; + ios_base::iostate __err = ios_base::goodbit; + use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(long long& __n) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this); + if (__s) + { + typedef istreambuf_iterator _Ip; + typedef num_get _Fp; + ios_base::iostate __err = ios_base::goodbit; + use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(unsigned long long& __n) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this); + if (__s) + { + typedef istreambuf_iterator _Ip; + typedef num_get _Fp; + ios_base::iostate __err = ios_base::goodbit; + use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(float& __n) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this); + if (__s) + { + typedef istreambuf_iterator _Ip; + typedef num_get _Fp; + ios_base::iostate __err = ios_base::goodbit; + use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(double& __n) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this); + if (__s) + { + typedef istreambuf_iterator _Ip; + typedef num_get _Fp; + ios_base::iostate __err = ios_base::goodbit; + use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(long double& __n) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this); + if (__s) + { + typedef istreambuf_iterator _Ip; + typedef num_get _Fp; + ios_base::iostate __err = ios_base::goodbit; + use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(bool& __n) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this); + if (__s) + { + typedef istreambuf_iterator _Ip; + typedef num_get _Fp; + ios_base::iostate __err = ios_base::goodbit; + use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(void*& __n) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this); + if (__s) + { + typedef istreambuf_iterator _Ip; + typedef num_get _Fp; + ios_base::iostate __err = ios_base::goodbit; + use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(short& __n) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this); + if (__s) + { + typedef istreambuf_iterator _Ip; + typedef num_get _Fp; + ios_base::iostate __err = ios_base::goodbit; + long __temp; + use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __temp); + if (__temp < numeric_limits::min()) + { + __err |= ios_base::failbit; + __n = numeric_limits::min(); + } + else if (__temp > numeric_limits::max()) + { + __err |= ios_base::failbit; + __n = numeric_limits::max(); + } + else + __n = static_cast(__temp); + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(int& __n) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this); + if (__s) + { + typedef istreambuf_iterator _Ip; + typedef num_get _Fp; + ios_base::iostate __err = ios_base::goodbit; + long __temp; + use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __temp); + if (__temp < numeric_limits::min()) + { + __err |= ios_base::failbit; + __n = numeric_limits::min(); + } + else if (__temp > numeric_limits::max()) + { + __err |= ios_base::failbit; + __n = numeric_limits::max(); + } + else + __n = static_cast(__temp); + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(basic_istream& (*__pf)(basic_istream&)) +{ + return __pf(*this); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(basic_ios& + (*__pf)(basic_ios&)) +{ + __pf(*this); + return *this; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(ios_base& (*__pf)(ios_base&)) +{ + __pf(*this); + return *this; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typename basic_istream<_CharT, _Traits>::sentry __sen(__is); + if (__sen) + { + streamsize __n = __is.width(); + if (__n <= 0) + __n = numeric_limits::max() / sizeof(_CharT) - 1; + streamsize __c = 0; + const ctype<_CharT>& __ct = use_facet >(__is.getloc()); + ios_base::iostate __err = ios_base::goodbit; + while (__c < __n-1) + { + typename _Traits::int_type __i = __is.rdbuf()->sgetc(); + if (_Traits::eq_int_type(__i, _Traits::eof())) + { + __err |= ios_base::eofbit; + break; + } + _CharT __ch = _Traits::to_char_type(__i); + if (__ct.is(__ct.space, __ch)) + break; + *__s++ = __ch; + ++__c; + __is.rdbuf()->sbumpc(); + } + *__s = _CharT(); + __is.width(0); + if (__c == 0) + __err |= ios_base::failbit; + __is.setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __is.__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __is; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream& +operator>>(basic_istream& __is, unsigned char* __s) +{ + return __is >> (char*)__s; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream& +operator>>(basic_istream& __is, signed char* __s) +{ + return __is >> (char*)__s; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typename basic_istream<_CharT, _Traits>::sentry __sen(__is); + if (__sen) + { + typename _Traits::int_type __i = __is.rdbuf()->sbumpc(); + if (_Traits::eq_int_type(__i, _Traits::eof())) + __is.setstate(ios_base::eofbit | ios_base::failbit); + else + __c = _Traits::to_char_type(__i); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __is.__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __is; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream& +operator>>(basic_istream& __is, unsigned char& __c) +{ + return __is >> (char&)__c; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream& +operator>>(basic_istream& __is, signed char& __c) +{ + return __is >> (char&)__c; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(basic_streambuf* __sb) +{ + __gc_ = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this, true); + if (__s) + { + if (__sb) + { +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + ios_base::iostate __err = ios_base::goodbit; + while (true) + { + typename traits_type::int_type __i = this->rdbuf()->sgetc(); + if (traits_type::eq_int_type(__i, _Traits::eof())) + { + __err |= ios_base::eofbit; + break; + } + if (traits_type::eq_int_type( + __sb->sputc(traits_type::to_char_type(__i)), + traits_type::eof())) + break; + ++__gc_; + this->rdbuf()->sbumpc(); + } + if (__gc_ == 0) + __err |= ios_base::failbit; + this->setstate(__err); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + if (__gc_ == 0) + this->__set_failbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + } + else + this->setstate(ios_base::failbit); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +typename basic_istream<_CharT, _Traits>::int_type +basic_istream<_CharT, _Traits>::get() +{ + __gc_ = 0; + int_type __r = traits_type::eof(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __s(*this, true); + if (__s) + { + __r = this->rdbuf()->sbumpc(); + if (traits_type::eq_int_type(__r, traits_type::eof())) + this->setstate(ios_base::failbit | ios_base::eofbit); + else + __gc_ = 1; + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::get(char_type& __c) +{ + int_type __ch = get(); + if (__ch != traits_type::eof()) + __c = traits_type::to_char_type(__ch); + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __dlm) +{ + __gc_ = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __sen(*this, true); + if (__sen) + { + if (__n > 0) + { + ios_base::iostate __err = ios_base::goodbit; + while (__gc_ < __n-1) + { + int_type __i = this->rdbuf()->sgetc(); + if (traits_type::eq_int_type(__i, traits_type::eof())) + { + __err |= ios_base::eofbit; + break; + } + char_type __ch = traits_type::to_char_type(__i); + if (traits_type::eq(__ch, __dlm)) + break; + *__s++ = __ch; + ++__gc_; + this->rdbuf()->sbumpc(); + } + *__s = char_type(); + if (__gc_ == 0) + __err |= ios_base::failbit; + this->setstate(__err); + } + else + this->setstate(ios_base::failbit); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n) +{ + return get(__s, __n, this->widen('\n')); +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::get(basic_streambuf& __sb, + char_type __dlm) +{ + __gc_ = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __sen(*this, true); + if (__sen) + { + ios_base::iostate __err = ios_base::goodbit; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + while (true) + { + typename traits_type::int_type __i = this->rdbuf()->sgetc(); + if (traits_type::eq_int_type(__i, traits_type::eof())) + { + __err |= ios_base::eofbit; + break; + } + char_type __ch = traits_type::to_char_type(__i); + if (traits_type::eq(__ch, __dlm)) + break; + if (traits_type::eq_int_type(__sb.sputc(__ch), traits_type::eof())) + break; + ++__gc_; + this->rdbuf()->sbumpc(); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCPP_NO_EXCEPTIONS + if (__gc_ == 0) + __err |= ios_base::failbit; + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::get(basic_streambuf& __sb) +{ + return get(__sb, this->widen('\n')); +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_type __dlm) +{ + __gc_ = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __sen(*this, true); + if (__sen) + { + ios_base::iostate __err = ios_base::goodbit; + while (true) + { + typename traits_type::int_type __i = this->rdbuf()->sgetc(); + if (traits_type::eq_int_type(__i, traits_type::eof())) + { + __err |= ios_base::eofbit; + break; + } + char_type __ch = traits_type::to_char_type(__i); + if (traits_type::eq(__ch, __dlm)) + { + this->rdbuf()->sbumpc(); + ++__gc_; + break; + } + if (__gc_ >= __n-1) + { + __err |= ios_base::failbit; + break; + } + *__s++ = __ch; + this->rdbuf()->sbumpc(); + ++__gc_; + } + if (__n > 0) + *__s = char_type(); + if (__gc_ == 0) + __err |= ios_base::failbit; + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n) +{ + return getline(__s, __n, this->widen('\n')); +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm) +{ + __gc_ = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __sen(*this, true); + if (__sen) + { + ios_base::iostate __err = ios_base::goodbit; + if (__n == numeric_limits::max()) + { + while (true) + { + typename traits_type::int_type __i = this->rdbuf()->sbumpc(); + if (traits_type::eq_int_type(__i, traits_type::eof())) + { + __err |= ios_base::eofbit; + break; + } + ++__gc_; + if (traits_type::eq_int_type(__i, __dlm)) + break; + } + } + else + { + while (__gc_ < __n) + { + typename traits_type::int_type __i = this->rdbuf()->sbumpc(); + if (traits_type::eq_int_type(__i, traits_type::eof())) + { + __err |= ios_base::eofbit; + break; + } + ++__gc_; + if (traits_type::eq_int_type(__i, __dlm)) + break; + } + } + this->setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +typename basic_istream<_CharT, _Traits>::int_type +basic_istream<_CharT, _Traits>::peek() +{ + __gc_ = 0; + int_type __r = traits_type::eof(); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __sen(*this, true); + if (__sen) + { + __r = this->rdbuf()->sgetc(); + if (traits_type::eq_int_type(__r, traits_type::eof())) + this->setstate(ios_base::eofbit); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __r; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n) +{ + __gc_ = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __sen(*this, true); + if (__sen) + { + __gc_ = this->rdbuf()->sgetn(__s, __n); + if (__gc_ != __n) + this->setstate(ios_base::failbit | ios_base::eofbit); + } + else + this->setstate(ios_base::failbit); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +streamsize +basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n) +{ + __gc_ = 0; + streamsize __c = this->rdbuf()->in_avail(); + switch (__c) + { + case -1: + this->setstate(ios_base::eofbit); + break; + case 0: + break; + default: + read(__s, _VSTD::min(__c, __n)); + break; + } + return __gc_; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::putback(char_type __c) +{ + __gc_ = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + this->clear(this->rdstate() & ~ios_base::eofbit); + sentry __sen(*this, true); + if (__sen) + { + if (this->rdbuf() == 0 || this->rdbuf()->sputbackc(__c) == traits_type::eof()) + this->setstate(ios_base::badbit); + } + else + this->setstate(ios_base::failbit); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::unget() +{ + __gc_ = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + this->clear(this->rdstate() & ~ios_base::eofbit); + sentry __sen(*this, true); + if (__sen) + { + if (this->rdbuf() == 0 || this->rdbuf()->sungetc() == traits_type::eof()) + this->setstate(ios_base::badbit); + } + else + this->setstate(ios_base::failbit); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +int +basic_istream<_CharT, _Traits>::sync() +{ + int __r = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __sen(*this, true); + if (__sen) + { + if (this->rdbuf() == 0) + return -1; + if (this->rdbuf()->pubsync() == -1) + { + this->setstate(ios_base::badbit); + return -1; + } + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __r; +} + +template +typename basic_istream<_CharT, _Traits>::pos_type +basic_istream<_CharT, _Traits>::tellg() +{ + pos_type __r(-1); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __sen(*this, true); + if (__sen) + __r = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __r; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::seekg(pos_type __pos) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + this->clear(this->rdstate() & ~ios_base::eofbit); + sentry __sen(*this, true); + if (__sen) + { + if (this->rdbuf()->pubseekpos(__pos, ios_base::in) == pos_type(-1)) + this->setstate(ios_base::failbit); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + this->clear(this->rdstate() & ~ios_base::eofbit); + sentry __sen(*this, true); + if (__sen) + { + if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::in) == pos_type(-1)) + this->setstate(ios_base::failbit); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return *this; +} + +template +basic_istream<_CharT, _Traits>& +ws(basic_istream<_CharT, _Traits>& __is) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true); + if (__sen) + { + const ctype<_CharT>& __ct = use_facet >(__is.getloc()); + while (true) + { + typename _Traits::int_type __i = __is.rdbuf()->sgetc(); + if (_Traits::eq_int_type(__i, _Traits::eof())) + { + __is.setstate(ios_base::eofbit); + break; + } + if (!__ct.is(__ct.space, _Traits::to_char_type(__i))) + break; + __is.rdbuf()->sbumpc(); + } + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __is.__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __is; +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp& __x) +{ + __is >> __x; + return __is; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +class _LIBCPP_TYPE_VIS_ONLY basic_iostream + : public basic_istream<_CharT, _Traits>, + public basic_ostream<_CharT, _Traits> +{ +public: + // types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // constructor/destructor + explicit basic_iostream(basic_streambuf* __sb); + virtual ~basic_iostream(); +protected: +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + basic_iostream(basic_iostream&& __rhs); +#endif + + // assign/swap +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + basic_iostream& operator=(basic_iostream&& __rhs); +#endif + void swap(basic_iostream& __rhs); +public: +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_iostream<_CharT, _Traits>::basic_iostream(basic_streambuf* __sb) + : basic_istream<_CharT, _Traits>(__sb) +{ +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_iostream<_CharT, _Traits>::basic_iostream(basic_iostream&& __rhs) + : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs)) +{ +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_iostream<_CharT, _Traits>& +basic_iostream<_CharT, _Traits>::operator=(basic_iostream&& __rhs) +{ + swap(__rhs); + return *this; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +basic_iostream<_CharT, _Traits>::~basic_iostream() +{ +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +basic_iostream<_CharT, _Traits>::swap(basic_iostream& __rhs) +{ + basic_istream::swap(__rhs); +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Allocator>& __str) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typename basic_istream<_CharT, _Traits>::sentry __sen(__is); + if (__sen) + { + __str.clear(); + streamsize __n = __is.width(); + if (__n <= 0) + __n = __str.max_size(); + if (__n <= 0) + __n = numeric_limits::max(); + streamsize __c = 0; + const ctype<_CharT>& __ct = use_facet >(__is.getloc()); + ios_base::iostate __err = ios_base::goodbit; + while (__c < __n) + { + typename _Traits::int_type __i = __is.rdbuf()->sgetc(); + if (_Traits::eq_int_type(__i, _Traits::eof())) + { + __err |= ios_base::eofbit; + break; + } + _CharT __ch = _Traits::to_char_type(__i); + if (__ct.is(__ct.space, __ch)) + break; + __str.push_back(__ch); + ++__c; + __is.rdbuf()->sbumpc(); + } + __is.width(0); + if (__c == 0) + __err |= ios_base::failbit; + __is.setstate(__err); + } + else + __is.setstate(ios_base::failbit); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __is.__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __is; +} + +template +basic_istream<_CharT, _Traits>& +getline(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true); + if (__sen) + { + __str.clear(); + ios_base::iostate __err = ios_base::goodbit; + streamsize __extr = 0; + while (true) + { + typename _Traits::int_type __i = __is.rdbuf()->sbumpc(); + if (_Traits::eq_int_type(__i, _Traits::eof())) + { + __err |= ios_base::eofbit; + break; + } + ++__extr; + _CharT __ch = _Traits::to_char_type(__i); + if (_Traits::eq(__ch, __dlm)) + break; + __str.push_back(__ch); + if (__str.size() == __str.max_size()) + { + __err |= ios_base::failbit; + break; + } + } + if (__extr == 0) + __err |= ios_base::failbit; + __is.setstate(__err); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __is.__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __is; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +getline(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Allocator>& __str) +{ + return getline(__is, __str, __is.widen('\n')); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +getline(basic_istream<_CharT, _Traits>&& __is, + basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm) +{ + return getline(__is, __str, __dlm); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +getline(basic_istream<_CharT, _Traits>&& __is, + basic_string<_CharT, _Traits, _Allocator>& __str) +{ + return getline(__is, __str, __is.widen('\n')); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typename basic_istream<_CharT, _Traits>::sentry __sen(__is); + if (__sen) + { + basic_string<_CharT, _Traits> __str; + const ctype<_CharT>& __ct = use_facet >(__is.getloc()); + streamsize __c = 0; + ios_base::iostate __err = ios_base::goodbit; + _CharT __zero = __ct.widen('0'); + _CharT __one = __ct.widen('1'); + while (__c < _Size) + { + typename _Traits::int_type __i = __is.rdbuf()->sgetc(); + if (_Traits::eq_int_type(__i, _Traits::eof())) + { + __err |= ios_base::eofbit; + break; + } + _CharT __ch = _Traits::to_char_type(__i); + if (!_Traits::eq(__ch, __zero) && !_Traits::eq(__ch, __one)) + break; + __str.push_back(__ch); + ++__c; + __is.rdbuf()->sbumpc(); + } + __x = bitset<_Size>(__str); + if (__c == 0) + __err |= ios_base::failbit; + __is.setstate(__err); + } + else + __is.setstate(ios_base::failbit); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __is.__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS + return __is; +} + +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_istream) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_istream) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_iostream) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_ISTREAM diff --git a/headers/libs/libc++/iterator b/headers/libs/libc++/iterator new file mode 100644 index 0000000000..8dd6bd59c1 --- /dev/null +++ b/headers/libs/libc++/iterator @@ -0,0 +1,1614 @@ +// -*- C++ -*- +//===-------------------------- iterator ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_ITERATOR +#define _LIBCPP_ITERATOR + +/* + iterator synopsis + +namespace std +{ + +template +struct iterator_traits +{ + typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::value_type value_type; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::reference reference; + typedef typename Iterator::iterator_category iterator_category; +}; + +template +struct iterator_traits +{ + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef random_access_iterator_tag iterator_category; +}; + +template +struct iterator_traits +{ + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef const T* pointer; + typedef const T& reference; + typedef random_access_iterator_tag iterator_category; +}; + +template +struct iterator +{ + typedef T value_type; + typedef Distance difference_type; + typedef Pointer pointer; + typedef Reference reference; + typedef Category iterator_category; +}; + +struct input_iterator_tag {}; +struct output_iterator_tag {}; +struct forward_iterator_tag : public input_iterator_tag {}; +struct bidirectional_iterator_tag : public forward_iterator_tag {}; +struct random_access_iterator_tag : public bidirectional_iterator_tag {}; + +// extension: second argument not conforming to C++03 +template +void advance(InputIterator& i, + typename iterator_traits::difference_type n); + +template +typename iterator_traits::difference_type +distance(InputIterator first, InputIterator last); + +template +class reverse_iterator + : public iterator::iterator_category, + typename iterator_traits::value_type, + typename iterator_traits::difference_type, + typename iterator_traits::pointer, + typename iterator_traits::reference> +{ +protected: + Iterator current; +public: + typedef Iterator iterator_type; + typedef typename iterator_traits::difference_type difference_type; + typedef typename iterator_traits::reference reference; + typedef typename iterator_traits::pointer pointer; + + reverse_iterator(); + explicit reverse_iterator(Iterator x); + template reverse_iterator(const reverse_iterator& u); + Iterator base() const; + reference operator*() const; + pointer operator->() const; + reverse_iterator& operator++(); + reverse_iterator operator++(int); + reverse_iterator& operator--(); + reverse_iterator operator--(int); + reverse_iterator operator+ (difference_type n) const; + reverse_iterator& operator+=(difference_type n); + reverse_iterator operator- (difference_type n) const; + reverse_iterator& operator-=(difference_type n); + reference operator[](difference_type n) const; +}; + +template +bool +operator==(const reverse_iterator& x, const reverse_iterator& y); + +template +bool +operator<(const reverse_iterator& x, const reverse_iterator& y); + +template +bool +operator!=(const reverse_iterator& x, const reverse_iterator& y); + +template +bool +operator>(const reverse_iterator& x, const reverse_iterator& y); + +template +bool +operator>=(const reverse_iterator& x, const reverse_iterator& y); + +template +bool +operator<=(const reverse_iterator& x, const reverse_iterator& y); + +template +typename reverse_iterator::difference_type +operator-(const reverse_iterator& x, const reverse_iterator& y); + +template +reverse_iterator +operator+(typename reverse_iterator::difference_type n, const reverse_iterator& x); + +template reverse_iterator make_reverse_iterator(Iterator i); // C++14 + +template +class back_insert_iterator +{ +protected: + Container* container; +public: + typedef Container container_type; + typedef void value_type; + typedef void difference_type; + typedef back_insert_iterator& reference; + typedef void pointer; + + explicit back_insert_iterator(Container& x); + back_insert_iterator& operator=(const typename Container::value_type& value); + back_insert_iterator& operator*(); + back_insert_iterator& operator++(); + back_insert_iterator operator++(int); +}; + +template back_insert_iterator back_inserter(Container& x); + +template +class front_insert_iterator +{ +protected: + Container* container; +public: + typedef Container container_type; + typedef void value_type; + typedef void difference_type; + typedef front_insert_iterator& reference; + typedef void pointer; + + explicit front_insert_iterator(Container& x); + front_insert_iterator& operator=(const typename Container::value_type& value); + front_insert_iterator& operator*(); + front_insert_iterator& operator++(); + front_insert_iterator operator++(int); +}; + +template front_insert_iterator front_inserter(Container& x); + +template +class insert_iterator +{ +protected: + Container* container; + typename Container::iterator iter; +public: + typedef Container container_type; + typedef void value_type; + typedef void difference_type; + typedef insert_iterator& reference; + typedef void pointer; + + insert_iterator(Container& x, typename Container::iterator i); + insert_iterator& operator=(const typename Container::value_type& value); + insert_iterator& operator*(); + insert_iterator& operator++(); + insert_iterator& operator++(int); +}; + +template +insert_iterator inserter(Container& x, Iterator i); + +template , class Distance = ptrdiff_t> +class istream_iterator + : public iterator +{ +public: + typedef charT char_type; + typedef traits traits_type; + typedef basic_istream istream_type; + + constexpr istream_iterator(); + istream_iterator(istream_type& s); + istream_iterator(const istream_iterator& x); + ~istream_iterator(); + + const T& operator*() const; + const T* operator->() const; + istream_iterator& operator++(); + istream_iterator operator++(int); +}; + +template +bool operator==(const istream_iterator& x, + const istream_iterator& y); +template +bool operator!=(const istream_iterator& x, + const istream_iterator& y); + +template > +class ostream_iterator + : public iterator +{ +public: + typedef charT char_type; + typedef traits traits_type; + typedef basic_ostream ostream_type; + + ostream_iterator(ostream_type& s); + ostream_iterator(ostream_type& s, const charT* delimiter); + ostream_iterator(const ostream_iterator& x); + ~ostream_iterator(); + ostream_iterator& operator=(const T& value); + + ostream_iterator& operator*(); + ostream_iterator& operator++(); + ostream_iterator& operator++(int); +}; + +template > +class istreambuf_iterator + : public iterator +{ +public: + typedef charT char_type; + typedef traits traits_type; + typedef typename traits::int_type int_type; + typedef basic_streambuf streambuf_type; + typedef basic_istream istream_type; + + istreambuf_iterator() noexcept; + istreambuf_iterator(istream_type& s) noexcept; + istreambuf_iterator(streambuf_type* s) noexcept; + istreambuf_iterator(a-private-type) noexcept; + + charT operator*() const; + pointer operator->() const; + istreambuf_iterator& operator++(); + a-private-type operator++(int); + + bool equal(const istreambuf_iterator& b) const; +}; + +template +bool operator==(const istreambuf_iterator& a, + const istreambuf_iterator& b); +template +bool operator!=(const istreambuf_iterator& a, + const istreambuf_iterator& b); + +template > +class ostreambuf_iterator + : public iterator +{ +public: + typedef charT char_type; + typedef traits traits_type; + typedef basic_streambuf streambuf_type; + typedef basic_ostream ostream_type; + + ostreambuf_iterator(ostream_type& s) noexcept; + ostreambuf_iterator(streambuf_type* s) noexcept; + ostreambuf_iterator& operator=(charT c); + ostreambuf_iterator& operator*(); + ostreambuf_iterator& operator++(); + ostreambuf_iterator& operator++(int); + bool failed() const noexcept; +}; + +template auto begin(C& c) -> decltype(c.begin()); +template auto begin(const C& c) -> decltype(c.begin()); +template auto end(C& c) -> decltype(c.end()); +template auto end(const C& c) -> decltype(c.end()); +template T* begin(T (&array)[N]); +template T* end(T (&array)[N]); + +template auto cbegin(const C& c) -> decltype(std::begin(c)); // C++14 +template auto cend(const C& c) -> decltype(std::end(c)); // C++14 +template auto rbegin(C& c) -> decltype(c.rbegin()); // C++14 +template auto rbegin(const C& c) -> decltype(c.rbegin()); // C++14 +template auto rend(C& c) -> decltype(c.rend()); // C++14 +template auto rend(const C& c) -> decltype(c.rend()); // C++14 +template reverse_iterator rbegin(initializer_list il); // C++14 +template reverse_iterator rend(initializer_list il); // C++14 +template reverse_iterator rbegin(T (&array)[N]); // C++14 +template reverse_iterator rend(T (&array)[N]); // C++14 +template auto crbegin(const C& c) -> decltype(std::rbegin(c)); // C++14 +template auto crend(const C& c) -> decltype(std::rend(c)); // C++14 + +// 24.8, container access: +template constexpr auto size(const C& c) -> decltype(c.size()); // C++17 +template constexpr size_t size(const T (&array)[N]) noexcept; // C++17 +template constexpr auto empty(const C& c) -> decltype(c.empty()); // C++17 +template constexpr bool empty(const T (&array)[N]) noexcept; // C++17 +template constexpr bool empty(initializer_list il) noexcept; // C++17 +template constexpr auto data(C& c) -> decltype(c.data()); // C++17 +template constexpr auto data(const C& c) -> decltype(c.data()); // C++17 +template constexpr T* data(T (&array)[N]) noexcept; // C++17 +template constexpr const E* data(initializer_list il) noexcept; // C++17 + +} // std + +*/ + +#include <__config> +#include <__functional_base> +#include +#include +#include +#include +#ifdef __APPLE__ +#include +#endif + +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct _LIBCPP_TYPE_VIS_ONLY input_iterator_tag {}; +struct _LIBCPP_TYPE_VIS_ONLY output_iterator_tag {}; +struct _LIBCPP_TYPE_VIS_ONLY forward_iterator_tag : public input_iterator_tag {}; +struct _LIBCPP_TYPE_VIS_ONLY bidirectional_iterator_tag : public forward_iterator_tag {}; +struct _LIBCPP_TYPE_VIS_ONLY random_access_iterator_tag : public bidirectional_iterator_tag {}; + +template +struct __has_iterator_category +{ +private: + struct __two {char __lx; char __lxx;}; + template static __two __test(...); + template static char __test(typename _Up::iterator_category* = 0); +public: + static const bool value = sizeof(__test<_Tp>(0)) == 1; +}; + +template struct __iterator_traits_impl {}; + +template +struct __iterator_traits_impl<_Iter, true> +{ + typedef typename _Iter::difference_type difference_type; + typedef typename _Iter::value_type value_type; + typedef typename _Iter::pointer pointer; + typedef typename _Iter::reference reference; + typedef typename _Iter::iterator_category iterator_category; +}; + +template struct __iterator_traits {}; + +template +struct __iterator_traits<_Iter, true> + : __iterator_traits_impl + < + _Iter, + is_convertible::value || + is_convertible::value + > +{}; + +// iterator_traits will only have the nested types if Iterator::iterator_category +// exists. Else iterator_traits will be an empty class. This is a +// conforming extension which allows some programs to compile and behave as +// the client expects instead of failing at compile time. + +template +struct _LIBCPP_TYPE_VIS_ONLY iterator_traits + : __iterator_traits<_Iter, __has_iterator_category<_Iter>::value> {}; + +template +struct _LIBCPP_TYPE_VIS_ONLY iterator_traits<_Tp*> +{ + typedef ptrdiff_t difference_type; + typedef typename remove_const<_Tp>::type value_type; + typedef _Tp* pointer; + typedef _Tp& reference; + typedef random_access_iterator_tag iterator_category; +}; + +template >::value> +struct __has_iterator_category_convertible_to + : public integral_constant::iterator_category, _Up>::value> +{}; + +template +struct __has_iterator_category_convertible_to<_Tp, _Up, false> : public false_type {}; + +template +struct __is_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {}; + +template +struct __is_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {}; + +template +struct __is_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {}; + +template +struct __is_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {}; + +template +struct _LIBCPP_TYPE_VIS_ONLY iterator +{ + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Pointer pointer; + typedef _Reference reference; + typedef _Category iterator_category; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +void __advance(_InputIter& __i, + typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) +{ + for (; __n > 0; --__n) + ++__i; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void __advance(_BiDirIter& __i, + typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) +{ + if (__n >= 0) + for (; __n > 0; --__n) + ++__i; + else + for (; __n < 0; ++__n) + --__i; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void __advance(_RandIter& __i, + typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) +{ + __i += __n; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void advance(_InputIter& __i, + typename iterator_traits<_InputIter>::difference_type __n) +{ + __advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename iterator_traits<_InputIter>::difference_type +__distance(_InputIter __first, _InputIter __last, input_iterator_tag) +{ + typename iterator_traits<_InputIter>::difference_type __r(0); + for (; __first != __last; ++__first) + ++__r; + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename iterator_traits<_RandIter>::difference_type +__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag) +{ + return __last - __first; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename iterator_traits<_InputIter>::difference_type +distance(_InputIter __first, _InputIter __last) +{ + return __distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_InputIter +next(_InputIter __x, + typename iterator_traits<_InputIter>::difference_type __n = 1, + typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0) +{ + _VSTD::advance(__x, __n); + return __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_BidiretionalIter +prev(_BidiretionalIter __x, + typename iterator_traits<_BidiretionalIter>::difference_type __n = 1, + typename enable_if<__is_bidirectional_iterator<_BidiretionalIter>::value>::type* = 0) +{ + _VSTD::advance(__x, -__n); + return __x; +} + +template +class _LIBCPP_TYPE_VIS_ONLY reverse_iterator + : public iterator::iterator_category, + typename iterator_traits<_Iter>::value_type, + typename iterator_traits<_Iter>::difference_type, + typename iterator_traits<_Iter>::pointer, + typename iterator_traits<_Iter>::reference> +{ +private: + mutable _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break +protected: + _Iter current; +public: + typedef _Iter iterator_type; + typedef typename iterator_traits<_Iter>::difference_type difference_type; + typedef typename iterator_traits<_Iter>::reference reference; + typedef typename iterator_traits<_Iter>::pointer pointer; + + _LIBCPP_INLINE_VISIBILITY reverse_iterator() : current() {} + _LIBCPP_INLINE_VISIBILITY explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {} + template _LIBCPP_INLINE_VISIBILITY reverse_iterator(const reverse_iterator<_Up>& __u) + : __t(__u.base()), current(__u.base()) {} + _LIBCPP_INLINE_VISIBILITY _Iter base() const {return current;} + _LIBCPP_INLINE_VISIBILITY reference operator*() const {_Iter __tmp = current; return *--__tmp;} + _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return _VSTD::addressof(operator*());} + _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator++() {--current; return *this;} + _LIBCPP_INLINE_VISIBILITY reverse_iterator operator++(int) + {reverse_iterator __tmp(*this); --current; return __tmp;} + _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator--() {++current; return *this;} + _LIBCPP_INLINE_VISIBILITY reverse_iterator operator--(int) + {reverse_iterator __tmp(*this); ++current; return __tmp;} + _LIBCPP_INLINE_VISIBILITY reverse_iterator operator+ (difference_type __n) const + {return reverse_iterator(current - __n);} + _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator+=(difference_type __n) + {current -= __n; return *this;} + _LIBCPP_INLINE_VISIBILITY reverse_iterator operator- (difference_type __n) const + {return reverse_iterator(current + __n);} + _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator-=(difference_type __n) + {current += __n; return *this;} + _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const + {return *(*this + __n);} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __x.base() == __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __x.base() > __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __x.base() != __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __x.base() < __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __x.base() <= __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __x.base() >= __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename reverse_iterator<_Iter1>::difference_type +operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __y.base() - __x.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +reverse_iterator<_Iter> +operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x) +{ + return reverse_iterator<_Iter>(__x.base() - __n); +} + +#if _LIBCPP_STD_VER > 11 +template +inline _LIBCPP_INLINE_VISIBILITY +reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) +{ + return reverse_iterator<_Iter>(__i); +} +#endif + +template +class _LIBCPP_TYPE_VIS_ONLY back_insert_iterator + : public iterator&> +{ +protected: + _Container* container; +public: + typedef _Container container_type; + + _LIBCPP_INLINE_VISIBILITY explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {} + _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(const typename _Container::value_type& __value_) + {container->push_back(__value_); return *this;} +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(typename _Container::value_type&& __value_) + {container->push_back(_VSTD::move(__value_)); return *this;} +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY back_insert_iterator operator++(int) {return *this;} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +back_insert_iterator<_Container> +back_inserter(_Container& __x) +{ + return back_insert_iterator<_Container>(__x); +} + +template +class _LIBCPP_TYPE_VIS_ONLY front_insert_iterator + : public iterator&> +{ +protected: + _Container* container; +public: + typedef _Container container_type; + + _LIBCPP_INLINE_VISIBILITY explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {} + _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(const typename _Container::value_type& __value_) + {container->push_front(__value_); return *this;} +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(typename _Container::value_type&& __value_) + {container->push_front(_VSTD::move(__value_)); return *this;} +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY front_insert_iterator operator++(int) {return *this;} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +front_insert_iterator<_Container> +front_inserter(_Container& __x) +{ + return front_insert_iterator<_Container>(__x); +} + +template +class _LIBCPP_TYPE_VIS_ONLY insert_iterator + : public iterator&> +{ +protected: + _Container* container; + typename _Container::iterator iter; +public: + typedef _Container container_type; + + _LIBCPP_INLINE_VISIBILITY insert_iterator(_Container& __x, typename _Container::iterator __i) + : container(_VSTD::addressof(__x)), iter(__i) {} + _LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(const typename _Container::value_type& __value_) + {iter = container->insert(iter, __value_); ++iter; return *this;} +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(typename _Container::value_type&& __value_) + {iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;} +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY insert_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY insert_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY insert_iterator& operator++(int) {return *this;} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +insert_iterator<_Container> +inserter(_Container& __x, typename _Container::iterator __i) +{ + return insert_iterator<_Container>(__x, __i); +} + +template , class _Distance = ptrdiff_t> +class _LIBCPP_TYPE_VIS_ONLY istream_iterator + : public iterator +{ +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_istream<_CharT,_Traits> istream_type; +private: + istream_type* __in_stream_; + _Tp __value_; +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(0), __value_() {} + _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(&__s) + { + if (!(*__in_stream_ >> __value_)) + __in_stream_ = 0; + } + + _LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;} + _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return &(operator*());} + _LIBCPP_INLINE_VISIBILITY istream_iterator& operator++() + { + if (!(*__in_stream_ >> __value_)) + __in_stream_ = 0; + return *this; + } + _LIBCPP_INLINE_VISIBILITY istream_iterator operator++(int) + {istream_iterator __t(*this); ++(*this); return __t;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const istream_iterator& __x, const istream_iterator& __y) + {return __x.__in_stream_ == __y.__in_stream_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const istream_iterator& __x, const istream_iterator& __y) + {return !(__x == __y);} +}; + +template > +class _LIBCPP_TYPE_VIS_ONLY ostream_iterator + : public iterator +{ +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_ostream<_CharT,_Traits> ostream_type; +private: + ostream_type* __out_stream_; + const char_type* __delim_; +public: + _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) + : __out_stream_(&__s), __delim_(0) {} + _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) + : __out_stream_(&__s), __delim_(__delimiter) {} + _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_) + { + *__out_stream_ << __value_; + if (__delim_) + *__out_stream_ << __delim_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++(int) {return *this;} +}; + +template +class _LIBCPP_TYPE_VIS_ONLY istreambuf_iterator + : public iterator +{ +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename _Traits::int_type int_type; + typedef basic_streambuf<_CharT,_Traits> streambuf_type; + typedef basic_istream<_CharT,_Traits> istream_type; +private: + mutable streambuf_type* __sbuf_; + + class __proxy + { + char_type __keep_; + streambuf_type* __sbuf_; + _LIBCPP_INLINE_VISIBILITY __proxy(char_type __c, streambuf_type* __s) + : __keep_(__c), __sbuf_(__s) {} + friend class istreambuf_iterator; + public: + _LIBCPP_INLINE_VISIBILITY char_type operator*() const {return __keep_;} + }; + + _LIBCPP_INLINE_VISIBILITY + bool __test_for_eof() const + { + if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof())) + __sbuf_ = 0; + return __sbuf_ == 0; + } +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(0) {} + _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT + : __sbuf_(__s.rdbuf()) {} + _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT + : __sbuf_(__s) {} + _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT + : __sbuf_(__p.__sbuf_) {} + + _LIBCPP_INLINE_VISIBILITY char_type operator*() const + {return static_cast(__sbuf_->sgetc());} + _LIBCPP_INLINE_VISIBILITY char_type* operator->() const {return nullptr;} + _LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++() + { + __sbuf_->sbumpc(); + return *this; + } + _LIBCPP_INLINE_VISIBILITY __proxy operator++(int) + { + return __proxy(__sbuf_->sbumpc(), __sbuf_); + } + + _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const + {return __test_for_eof() == __b.__test_for_eof();} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a, + const istreambuf_iterator<_CharT,_Traits>& __b) + {return __a.equal(__b);} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a, + const istreambuf_iterator<_CharT,_Traits>& __b) + {return !__a.equal(__b);} + +template +class _LIBCPP_TYPE_VIS_ONLY ostreambuf_iterator + : public iterator +{ +public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_streambuf<_CharT,_Traits> streambuf_type; + typedef basic_ostream<_CharT,_Traits> ostream_type; +private: + streambuf_type* __sbuf_; +public: + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT + : __sbuf_(__s.rdbuf()) {} + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT + : __sbuf_(__s) {} + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator=(_CharT __c) + { + if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof())) + __sbuf_ = 0; + return *this; + } + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++(int) {return *this;} + _LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == 0;} + +#if !defined(__APPLE__) || \ + (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \ + (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0) + + template + friend + _LIBCPP_HIDDEN + ostreambuf_iterator<_Ch, _Tr> + __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s, + const _Ch* __ob, const _Ch* __op, const _Ch* __oe, + ios_base& __iob, _Ch __fl); +#endif +}; + +template +class _LIBCPP_TYPE_VIS_ONLY move_iterator +{ +private: + _Iter __i; +public: + typedef _Iter iterator_type; + typedef typename iterator_traits::iterator_category iterator_category; + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::difference_type difference_type; + typedef typename iterator_traits::pointer pointer; +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + typedef value_type&& reference; +#else + typedef typename iterator_traits::reference reference; +#endif + + _LIBCPP_INLINE_VISIBILITY move_iterator() : __i() {} + _LIBCPP_INLINE_VISIBILITY explicit move_iterator(_Iter __x) : __i(__x) {} + template _LIBCPP_INLINE_VISIBILITY move_iterator(const move_iterator<_Up>& __u) + : __i(__u.base()) {} + _LIBCPP_INLINE_VISIBILITY _Iter base() const {return __i;} + _LIBCPP_INLINE_VISIBILITY reference operator*() const { + return static_cast(*__i); + } + _LIBCPP_INLINE_VISIBILITY pointer operator->() const { + typename iterator_traits::reference __ref = *__i; + return &__ref; + } + _LIBCPP_INLINE_VISIBILITY move_iterator& operator++() {++__i; return *this;} + _LIBCPP_INLINE_VISIBILITY move_iterator operator++(int) + {move_iterator __tmp(*this); ++__i; return __tmp;} + _LIBCPP_INLINE_VISIBILITY move_iterator& operator--() {--__i; return *this;} + _LIBCPP_INLINE_VISIBILITY move_iterator operator--(int) + {move_iterator __tmp(*this); --__i; return __tmp;} + _LIBCPP_INLINE_VISIBILITY move_iterator operator+ (difference_type __n) const + {return move_iterator(__i + __n);} + _LIBCPP_INLINE_VISIBILITY move_iterator& operator+=(difference_type __n) + {__i += __n; return *this;} + _LIBCPP_INLINE_VISIBILITY move_iterator operator- (difference_type __n) const + {return move_iterator(__i - __n);} + _LIBCPP_INLINE_VISIBILITY move_iterator& operator-=(difference_type __n) + {__i -= __n; return *this;} + _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const + { + return static_cast(__i[__n]); + } +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() == __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() < __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() != __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() > __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() >= __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() <= __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename move_iterator<_Iter1>::difference_type +operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() - __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +move_iterator<_Iter> +operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) +{ + return move_iterator<_Iter>(__x.base() + __n); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +move_iterator<_Iter> +make_move_iterator(_Iter __i) +{ + return move_iterator<_Iter>(__i); +} + +// __wrap_iter + +template class __wrap_iter; + +template +_LIBCPP_INLINE_VISIBILITY +bool +operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY +bool +operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY +bool +operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY +bool +operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY +bool +operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY +bool +operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY +typename __wrap_iter<_Iter1>::difference_type +operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY +__wrap_iter<_Iter> +operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT; + +template _Op _LIBCPP_INLINE_VISIBILITY copy(_Ip, _Ip, _Op); +template _B2 _LIBCPP_INLINE_VISIBILITY copy_backward(_B1, _B1, _B2); +template _Op _LIBCPP_INLINE_VISIBILITY move(_Ip, _Ip, _Op); +template _B2 _LIBCPP_INLINE_VISIBILITY move_backward(_B1, _B1, _B2); + +template +_LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_trivially_copy_assignable<_Tp>::value, + _Tp* +>::type +__unwrap_iter(__wrap_iter<_Tp*>); + +template +class __wrap_iter +{ +public: + typedef _Iter iterator_type; + typedef typename iterator_traits::iterator_category iterator_category; + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::difference_type difference_type; + typedef typename iterator_traits::pointer pointer; + typedef typename iterator_traits::reference reference; +private: + iterator_type __i; +public: + _LIBCPP_INLINE_VISIBILITY __wrap_iter() _NOEXCEPT +#if _LIBCPP_STD_VER > 11 + : __i{} +#endif + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_i(this); +#endif + } + template _LIBCPP_INLINE_VISIBILITY __wrap_iter(const __wrap_iter<_Up>& __u, + typename enable_if::value>::type* = 0) _NOEXCEPT + : __i(__u.base()) + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__iterator_copy(this, &__u); +#endif + } +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __wrap_iter(const __wrap_iter& __x) + : __i(__x.base()) + { + __get_db()->__iterator_copy(this, &__x); + } + _LIBCPP_INLINE_VISIBILITY + __wrap_iter& operator=(const __wrap_iter& __x) + { + if (this != &__x) + { + __get_db()->__iterator_copy(this, &__x); + __i = __x.__i; + } + return *this; + } + _LIBCPP_INLINE_VISIBILITY + ~__wrap_iter() + { + __get_db()->__erase_i(this); + } +#endif + _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable iterator"); +#endif + return *__i; + } + _LIBCPP_INLINE_VISIBILITY pointer operator->() const _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable iterator"); +#endif + return (pointer)&reinterpret_cast(*__i); + } + _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable iterator"); +#endif + ++__i; + return *this; + } + _LIBCPP_INLINE_VISIBILITY __wrap_iter operator++(int) _NOEXCEPT + {__wrap_iter __tmp(*this); ++(*this); return __tmp;} + _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator--() _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), + "Attempted to decrement non-decrementable iterator"); +#endif + --__i; + return *this; + } + _LIBCPP_INLINE_VISIBILITY __wrap_iter operator--(int) _NOEXCEPT + {__wrap_iter __tmp(*this); --(*this); return __tmp;} + _LIBCPP_INLINE_VISIBILITY __wrap_iter operator+ (difference_type __n) const _NOEXCEPT + {__wrap_iter __w(*this); __w += __n; return __w;} + _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator+=(difference_type __n) _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n), + "Attempted to add/subtract iterator outside of valid range"); +#endif + __i += __n; + return *this; + } + _LIBCPP_INLINE_VISIBILITY __wrap_iter operator- (difference_type __n) const _NOEXCEPT + {return *this + (-__n);} + _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator-=(difference_type __n) _NOEXCEPT + {*this += -__n; return *this;} + _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n), + "Attempted to subscript iterator outside of valid range"); +#endif + return __i[__n]; + } + + _LIBCPP_INLINE_VISIBILITY iterator_type base() const _NOEXCEPT {return __i;} + +private: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY __wrap_iter(const void* __p, iterator_type __x) : __i(__x) + { + __get_db()->__insert_ic(this, __p); + } +#else + _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {} +#endif + + template friend class __wrap_iter; + template friend class basic_string; + template friend class _LIBCPP_TYPE_VIS_ONLY vector; + + template + friend + bool + operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + + template + friend + bool + operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + + template + friend + bool + operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + + template + friend + bool + operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + + template + friend + bool + operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + + template + friend + bool + operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + + template + friend + typename __wrap_iter<_Iter1>::difference_type + operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + + template + friend + __wrap_iter<_Iter1> + operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT; + + template friend _Op copy(_Ip, _Ip, _Op); + template friend _B2 copy_backward(_B1, _B1, _B2); + template friend _Op move(_Ip, _Ip, _Op); + template friend _B2 move_backward(_B1, _B1, _B2); + + template + friend + typename enable_if + < + is_trivially_copy_assignable<_Tp>::value, + _Tp* + >::type + __unwrap_iter(__wrap_iter<_Tp*>); +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +{ + return __x.base() == __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), + "Attempted to compare incomparable iterators"); +#endif + return __x.base() < __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __wrap_iter<_Iter1>::difference_type +operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), + "Attempted to subtract incompatible iterators"); +#endif + return __x.base() - __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__wrap_iter<_Iter> +operator+(typename __wrap_iter<_Iter>::difference_type __n, + __wrap_iter<_Iter> __x) _NOEXCEPT +{ + __x += __n; + return __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp* +begin(_Tp (&__array)[_Np]) +{ + return __array; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp* +end(_Tp (&__array)[_Np]) +{ + return __array + _Np; +} + +#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN) + +template +inline _LIBCPP_INLINE_VISIBILITY +auto +begin(_Cp& __c) -> decltype(__c.begin()) +{ + return __c.begin(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto +begin(const _Cp& __c) -> decltype(__c.begin()) +{ + return __c.begin(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto +end(_Cp& __c) -> decltype(__c.end()) +{ + return __c.end(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto +end(const _Cp& __c) -> decltype(__c.end()) +{ + return __c.end(); +} + +#if _LIBCPP_STD_VER > 11 + +template +inline _LIBCPP_INLINE_VISIBILITY +reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np]) +{ + return reverse_iterator<_Tp*>(__array + _Np); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np]) +{ + return reverse_iterator<_Tp*>(__array); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +reverse_iterator rbegin(initializer_list<_Ep> __il) +{ + return reverse_iterator(__il.end()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +reverse_iterator rend(initializer_list<_Ep> __il) +{ + return reverse_iterator(__il.begin()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +auto cbegin(const _Cp& __c) -> decltype(begin(__c)) +{ + return begin(__c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +auto cend(const _Cp& __c) -> decltype(end(__c)) +{ + return end(__c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto rbegin(_Cp& __c) -> decltype(__c.rbegin()) +{ + return __c.rbegin(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto rbegin(const _Cp& __c) -> decltype(__c.rbegin()) +{ + return __c.rbegin(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto rend(_Cp& __c) -> decltype(__c.rend()) +{ + return __c.rend(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto rend(const _Cp& __c) -> decltype(__c.rend()) +{ + return __c.rend(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto crbegin(const _Cp& __c) -> decltype(rbegin(__c)) +{ + return rbegin(__c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto crend(const _Cp& __c) -> decltype(rend(__c)) +{ + return rend(__c); +} + +#endif + + +#else // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN) + +template +inline _LIBCPP_INLINE_VISIBILITY +typename _Cp::iterator +begin(_Cp& __c) +{ + return __c.begin(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename _Cp::const_iterator +begin(const _Cp& __c) +{ + return __c.begin(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename _Cp::iterator +end(_Cp& __c) +{ + return __c.end(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename _Cp::const_iterator +end(const _Cp& __c) +{ + return __c.end(); +} + +#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN) + +#if _LIBCPP_STD_VER > 14 +template +constexpr auto size(const _Cont& __c) -> decltype(__c.size()) { return __c.size(); } + +template +constexpr size_t size(const _Tp (&__array)[_Sz]) noexcept { return _Sz; } + +template +constexpr auto empty(const _Cont& __c) -> decltype(__c.empty()) { return __c.empty(); } + +template +constexpr bool empty(const _Tp (&__array)[_Sz]) noexcept { return false; } + +template +constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; } + +template constexpr +auto data(_Cont& __c) -> decltype(__c.data()) { return __c.data(); } + +template constexpr +auto data(const _Cont& __c) -> decltype(__c.data()) { return __c.data(); } + +template +constexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; } + +template +constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); } +#endif + + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_ITERATOR diff --git a/headers/libs/libc++/limits b/headers/libs/libc++/limits new file mode 100644 index 0000000000..ce967ea1b2 --- /dev/null +++ b/headers/libs/libc++/limits @@ -0,0 +1,813 @@ +// -*- C++ -*- +//===---------------------------- limits ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_LIMITS +#define _LIBCPP_LIMITS + +/* + limits synopsis + +namespace std +{ + +template +class numeric_limits +{ +public: + static constexpr bool is_specialized = false; + static constexpr T min() noexcept; + static constexpr T max() noexcept; + static constexpr T lowest() noexcept; + + static constexpr int digits = 0; + static constexpr int digits10 = 0; + static constexpr int max_digits10 = 0; + static constexpr bool is_signed = false; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr int radix = 0; + static constexpr T epsilon() noexcept; + static constexpr T round_error() noexcept; + + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + static constexpr T infinity() noexcept; + static constexpr T quiet_NaN() noexcept; + static constexpr T signaling_NaN() noexcept; + static constexpr T denorm_min() noexcept; + + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = false; + static constexpr bool is_modulo = false; + + static constexpr bool traps = false; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_toward_zero; +}; + +enum float_round_style +{ + round_indeterminate = -1, + round_toward_zero = 0, + round_to_nearest = 1, + round_toward_infinity = 2, + round_toward_neg_infinity = 3 +}; + +enum float_denorm_style +{ + denorm_indeterminate = -1, + denorm_absent = 0, + denorm_present = 1 +}; + +template<> class numeric_limits; + +template<> class numeric_limits; +template<> class numeric_limits; +template<> class numeric_limits; +template<> class numeric_limits; +template<> class numeric_limits; +template<> class numeric_limits; + +template<> class numeric_limits; +template<> class numeric_limits; +template<> class numeric_limits; +template<> class numeric_limits; +template<> class numeric_limits; +template<> class numeric_limits; +template<> class numeric_limits; +template<> class numeric_limits; + +template<> class numeric_limits; +template<> class numeric_limits; +template<> class numeric_limits; + +} // std + +*/ + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#include <__config> +#include + +#include <__undef_min_max> + +#if defined(_LIBCPP_MSVCRT) +#include "support/win32/limits_win32.h" +#endif // _LIBCPP_MSVCRT + +#if defined(__IBMCPP__) +#include "support/ibm/limits.h" +#endif // __IBMCPP__ + +_LIBCPP_BEGIN_NAMESPACE_STD + +enum float_round_style +{ + round_indeterminate = -1, + round_toward_zero = 0, + round_to_nearest = 1, + round_toward_infinity = 2, + round_toward_neg_infinity = 3 +}; + +enum float_denorm_style +{ + denorm_indeterminate = -1, + denorm_absent = 0, + denorm_present = 1 +}; + +template ::value> +class __libcpp_numeric_limits +{ +protected: + typedef _Tp type; + + static _LIBCPP_CONSTEXPR const bool is_specialized = false; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return type();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return type();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return type();} + + static _LIBCPP_CONSTEXPR const int digits = 0; + static _LIBCPP_CONSTEXPR const int digits10 = 0; + static _LIBCPP_CONSTEXPR const int max_digits10 = 0; + static _LIBCPP_CONSTEXPR const bool is_signed = false; + static _LIBCPP_CONSTEXPR const bool is_integer = false; + static _LIBCPP_CONSTEXPR const bool is_exact = false; + static _LIBCPP_CONSTEXPR const int radix = 0; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return type();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return type();} + + static _LIBCPP_CONSTEXPR const int min_exponent = 0; + static _LIBCPP_CONSTEXPR const int min_exponent10 = 0; + static _LIBCPP_CONSTEXPR const int max_exponent = 0; + static _LIBCPP_CONSTEXPR const int max_exponent10 = 0; + + static _LIBCPP_CONSTEXPR const bool has_infinity = false; + static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = false; + static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = false; + static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_absent; + static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return type();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return type();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return type();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return type();} + + static _LIBCPP_CONSTEXPR const bool is_iec559 = false; + static _LIBCPP_CONSTEXPR const bool is_bounded = false; + static _LIBCPP_CONSTEXPR const bool is_modulo = false; + + static _LIBCPP_CONSTEXPR const bool traps = false; + static _LIBCPP_CONSTEXPR const bool tinyness_before = false; + static _LIBCPP_CONSTEXPR const float_round_style round_style = round_toward_zero; +}; + +template +struct __libcpp_compute_min +{ + static _LIBCPP_CONSTEXPR const _Tp value = _Tp(_Tp(1) << digits); +}; + +template +struct __libcpp_compute_min<_Tp, digits, false> +{ + static _LIBCPP_CONSTEXPR const _Tp value = _Tp(0); +}; + +template +class __libcpp_numeric_limits<_Tp, true> +{ +protected: + typedef _Tp type; + + static _LIBCPP_CONSTEXPR const bool is_specialized = true; + + static _LIBCPP_CONSTEXPR const bool is_signed = type(-1) < type(0); + static _LIBCPP_CONSTEXPR const int digits = static_cast(sizeof(type) * __CHAR_BIT__ - is_signed); + static _LIBCPP_CONSTEXPR const int digits10 = digits * 3 / 10; + static _LIBCPP_CONSTEXPR const int max_digits10 = 0; + static _LIBCPP_CONSTEXPR const type __min = __libcpp_compute_min::value; + static _LIBCPP_CONSTEXPR const type __max = is_signed ? type(type(~0) ^ __min) : type(~0); + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __min;} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __max;} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return min();} + + static _LIBCPP_CONSTEXPR const bool is_integer = true; + static _LIBCPP_CONSTEXPR const bool is_exact = true; + static _LIBCPP_CONSTEXPR const int radix = 2; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return type(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return type(0);} + + static _LIBCPP_CONSTEXPR const int min_exponent = 0; + static _LIBCPP_CONSTEXPR const int min_exponent10 = 0; + static _LIBCPP_CONSTEXPR const int max_exponent = 0; + static _LIBCPP_CONSTEXPR const int max_exponent10 = 0; + + static _LIBCPP_CONSTEXPR const bool has_infinity = false; + static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = false; + static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = false; + static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_absent; + static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return type(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return type(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return type(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return type(0);} + + static _LIBCPP_CONSTEXPR const bool is_iec559 = false; + static _LIBCPP_CONSTEXPR const bool is_bounded = true; + static _LIBCPP_CONSTEXPR const bool is_modulo = !_VSTD::is_signed<_Tp>::value; + +#if defined(__i386__) || defined(__x86_64__) || defined(__pnacl__) + static _LIBCPP_CONSTEXPR const bool traps = true; +#else + static _LIBCPP_CONSTEXPR const bool traps = false; +#endif + static _LIBCPP_CONSTEXPR const bool tinyness_before = false; + static _LIBCPP_CONSTEXPR const float_round_style round_style = round_toward_zero; +}; + +template <> +class __libcpp_numeric_limits +{ +protected: + typedef bool type; + + static _LIBCPP_CONSTEXPR const bool is_specialized = true; + + static _LIBCPP_CONSTEXPR const bool is_signed = false; + static _LIBCPP_CONSTEXPR const int digits = 1; + static _LIBCPP_CONSTEXPR const int digits10 = 0; + static _LIBCPP_CONSTEXPR const int max_digits10 = 0; + static _LIBCPP_CONSTEXPR const type __min = false; + static _LIBCPP_CONSTEXPR const type __max = true; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __min;} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __max;} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return min();} + + static _LIBCPP_CONSTEXPR const bool is_integer = true; + static _LIBCPP_CONSTEXPR const bool is_exact = true; + static _LIBCPP_CONSTEXPR const int radix = 2; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return type(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return type(0);} + + static _LIBCPP_CONSTEXPR const int min_exponent = 0; + static _LIBCPP_CONSTEXPR const int min_exponent10 = 0; + static _LIBCPP_CONSTEXPR const int max_exponent = 0; + static _LIBCPP_CONSTEXPR const int max_exponent10 = 0; + + static _LIBCPP_CONSTEXPR const bool has_infinity = false; + static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = false; + static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = false; + static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_absent; + static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return type(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return type(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return type(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return type(0);} + + static _LIBCPP_CONSTEXPR const bool is_iec559 = false; + static _LIBCPP_CONSTEXPR const bool is_bounded = true; + static _LIBCPP_CONSTEXPR const bool is_modulo = false; + + static _LIBCPP_CONSTEXPR const bool traps = false; + static _LIBCPP_CONSTEXPR const bool tinyness_before = false; + static _LIBCPP_CONSTEXPR const float_round_style round_style = round_toward_zero; +}; + +template <> +class __libcpp_numeric_limits +{ +protected: + typedef float type; + + static _LIBCPP_CONSTEXPR const bool is_specialized = true; + + static _LIBCPP_CONSTEXPR const bool is_signed = true; + static _LIBCPP_CONSTEXPR const int digits = __FLT_MANT_DIG__; + static _LIBCPP_CONSTEXPR const int digits10 = __FLT_DIG__; + static _LIBCPP_CONSTEXPR const int max_digits10 = 2+(digits * 30103)/100000; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __FLT_MIN__;} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __FLT_MAX__;} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return -max();} + + static _LIBCPP_CONSTEXPR const bool is_integer = false; + static _LIBCPP_CONSTEXPR const bool is_exact = false; + static _LIBCPP_CONSTEXPR const int radix = __FLT_RADIX__; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __FLT_EPSILON__;} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return 0.5F;} + + static _LIBCPP_CONSTEXPR const int min_exponent = __FLT_MIN_EXP__; + static _LIBCPP_CONSTEXPR const int min_exponent10 = __FLT_MIN_10_EXP__; + static _LIBCPP_CONSTEXPR const int max_exponent = __FLT_MAX_EXP__; + static _LIBCPP_CONSTEXPR const int max_exponent10 = __FLT_MAX_10_EXP__; + + static _LIBCPP_CONSTEXPR const bool has_infinity = true; + static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = true; + static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = true; + static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_present; + static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __builtin_huge_valf();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __builtin_nanf("");} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __builtin_nansf("");} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __FLT_DENORM_MIN__;} + + static _LIBCPP_CONSTEXPR const bool is_iec559 = true; + static _LIBCPP_CONSTEXPR const bool is_bounded = true; + static _LIBCPP_CONSTEXPR const bool is_modulo = false; + + static _LIBCPP_CONSTEXPR const bool traps = false; + static _LIBCPP_CONSTEXPR const bool tinyness_before = false; + static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest; +}; + +template <> +class __libcpp_numeric_limits +{ +protected: + typedef double type; + + static _LIBCPP_CONSTEXPR const bool is_specialized = true; + + static _LIBCPP_CONSTEXPR const bool is_signed = true; + static _LIBCPP_CONSTEXPR const int digits = __DBL_MANT_DIG__; + static _LIBCPP_CONSTEXPR const int digits10 = __DBL_DIG__; + static _LIBCPP_CONSTEXPR const int max_digits10 = 2+(digits * 30103)/100000; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __DBL_MIN__;} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __DBL_MAX__;} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return -max();} + + static _LIBCPP_CONSTEXPR const bool is_integer = false; + static _LIBCPP_CONSTEXPR const bool is_exact = false; + static _LIBCPP_CONSTEXPR const int radix = __FLT_RADIX__; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __DBL_EPSILON__;} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return 0.5;} + + static _LIBCPP_CONSTEXPR const int min_exponent = __DBL_MIN_EXP__; + static _LIBCPP_CONSTEXPR const int min_exponent10 = __DBL_MIN_10_EXP__; + static _LIBCPP_CONSTEXPR const int max_exponent = __DBL_MAX_EXP__; + static _LIBCPP_CONSTEXPR const int max_exponent10 = __DBL_MAX_10_EXP__; + + static _LIBCPP_CONSTEXPR const bool has_infinity = true; + static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = true; + static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = true; + static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_present; + static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __builtin_huge_val();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __builtin_nan("");} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __builtin_nans("");} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __DBL_DENORM_MIN__;} + + static _LIBCPP_CONSTEXPR const bool is_iec559 = true; + static _LIBCPP_CONSTEXPR const bool is_bounded = true; + static _LIBCPP_CONSTEXPR const bool is_modulo = false; + + static _LIBCPP_CONSTEXPR const bool traps = false; + static _LIBCPP_CONSTEXPR const bool tinyness_before = false; + static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest; +}; + +template <> +class __libcpp_numeric_limits +{ +protected: + typedef long double type; + + static _LIBCPP_CONSTEXPR const bool is_specialized = true; + + static _LIBCPP_CONSTEXPR const bool is_signed = true; + static _LIBCPP_CONSTEXPR const int digits = __LDBL_MANT_DIG__; + static _LIBCPP_CONSTEXPR const int digits10 = __LDBL_DIG__; + static _LIBCPP_CONSTEXPR const int max_digits10 = 2+(digits * 30103)/100000; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __LDBL_MIN__;} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __LDBL_MAX__;} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return -max();} + + static _LIBCPP_CONSTEXPR const bool is_integer = false; + static _LIBCPP_CONSTEXPR const bool is_exact = false; + static _LIBCPP_CONSTEXPR const int radix = __FLT_RADIX__; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __LDBL_EPSILON__;} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return 0.5;} + + static _LIBCPP_CONSTEXPR const int min_exponent = __LDBL_MIN_EXP__; + static _LIBCPP_CONSTEXPR const int min_exponent10 = __LDBL_MIN_10_EXP__; + static _LIBCPP_CONSTEXPR const int max_exponent = __LDBL_MAX_EXP__; + static _LIBCPP_CONSTEXPR const int max_exponent10 = __LDBL_MAX_10_EXP__; + + static _LIBCPP_CONSTEXPR const bool has_infinity = true; + static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = true; + static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = true; + static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_present; + static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __builtin_huge_vall();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __builtin_nanl("");} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __builtin_nansl("");} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __LDBL_DENORM_MIN__;} + +#if (defined(__ppc__) || defined(__ppc64__)) + static _LIBCPP_CONSTEXPR const bool is_iec559 = false; +#else + static _LIBCPP_CONSTEXPR const bool is_iec559 = true; +#endif + static _LIBCPP_CONSTEXPR const bool is_bounded = true; + static _LIBCPP_CONSTEXPR const bool is_modulo = false; + + static _LIBCPP_CONSTEXPR const bool traps = false; + static _LIBCPP_CONSTEXPR const bool tinyness_before = false; + static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest; +}; + +template +class _LIBCPP_TYPE_VIS_ONLY numeric_limits + : private __libcpp_numeric_limits::type> +{ + typedef __libcpp_numeric_limits::type> __base; + typedef typename __base::type type; +public: + static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __base::min();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __base::max();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return __base::lowest();} + + static _LIBCPP_CONSTEXPR const int digits = __base::digits; + static _LIBCPP_CONSTEXPR const int digits10 = __base::digits10; + static _LIBCPP_CONSTEXPR const int max_digits10 = __base::max_digits10; + static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed; + static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer; + static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact; + static _LIBCPP_CONSTEXPR const int radix = __base::radix; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __base::epsilon();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return __base::round_error();} + + static _LIBCPP_CONSTEXPR const int min_exponent = __base::min_exponent; + static _LIBCPP_CONSTEXPR const int min_exponent10 = __base::min_exponent10; + static _LIBCPP_CONSTEXPR const int max_exponent = __base::max_exponent; + static _LIBCPP_CONSTEXPR const int max_exponent10 = __base::max_exponent10; + + static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity; + static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN; + static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN; + static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm; + static _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __base::infinity();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __base::quiet_NaN();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __base::signaling_NaN();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __base::denorm_min();} + + static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559; + static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded; + static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo; + + static _LIBCPP_CONSTEXPR const bool traps = __base::traps; + static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before; + static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style; +}; + +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_specialized; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::digits; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::digits10; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::max_digits10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_signed; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_integer; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_exact; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::radix; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::min_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::min_exponent10; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::max_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::max_exponent10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_infinity; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_quiet_NaN; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_signaling_NaN; +template + _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits<_Tp>::has_denorm; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_denorm_loss; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_iec559; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_bounded; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_modulo; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::traps; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::tinyness_before; +template + _LIBCPP_CONSTEXPR const float_round_style numeric_limits<_Tp>::round_style; + +template +class _LIBCPP_TYPE_VIS_ONLY numeric_limits + : private numeric_limits<_Tp> +{ + typedef numeric_limits<_Tp> __base; + typedef _Tp type; +public: + static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __base::min();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __base::max();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return __base::lowest();} + + static _LIBCPP_CONSTEXPR const int digits = __base::digits; + static _LIBCPP_CONSTEXPR const int digits10 = __base::digits10; + static _LIBCPP_CONSTEXPR const int max_digits10 = __base::max_digits10; + static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed; + static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer; + static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact; + static _LIBCPP_CONSTEXPR const int radix = __base::radix; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __base::epsilon();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return __base::round_error();} + + static _LIBCPP_CONSTEXPR const int min_exponent = __base::min_exponent; + static _LIBCPP_CONSTEXPR const int min_exponent10 = __base::min_exponent10; + static _LIBCPP_CONSTEXPR const int max_exponent = __base::max_exponent; + static _LIBCPP_CONSTEXPR const int max_exponent10 = __base::max_exponent10; + + static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity; + static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN; + static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN; + static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm; + static _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __base::infinity();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __base::quiet_NaN();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __base::signaling_NaN();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __base::denorm_min();} + + static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559; + static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded; + static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo; + + static _LIBCPP_CONSTEXPR const bool traps = __base::traps; + static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before; + static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style; +}; + +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_specialized; +template + _LIBCPP_CONSTEXPR const int numeric_limits::digits; +template + _LIBCPP_CONSTEXPR const int numeric_limits::digits10; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_digits10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_signed; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_integer; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_exact; +template + _LIBCPP_CONSTEXPR const int numeric_limits::radix; +template + _LIBCPP_CONSTEXPR const int numeric_limits::min_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits::min_exponent10; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_exponent10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_infinity; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_quiet_NaN; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_signaling_NaN; +template + _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits::has_denorm; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_denorm_loss; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_iec559; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_bounded; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_modulo; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::traps; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::tinyness_before; +template + _LIBCPP_CONSTEXPR const float_round_style numeric_limits::round_style; + +template +class _LIBCPP_TYPE_VIS_ONLY numeric_limits + : private numeric_limits<_Tp> +{ + typedef numeric_limits<_Tp> __base; + typedef _Tp type; +public: + static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __base::min();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __base::max();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return __base::lowest();} + + static _LIBCPP_CONSTEXPR const int digits = __base::digits; + static _LIBCPP_CONSTEXPR const int digits10 = __base::digits10; + static _LIBCPP_CONSTEXPR const int max_digits10 = __base::max_digits10; + static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed; + static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer; + static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact; + static _LIBCPP_CONSTEXPR const int radix = __base::radix; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __base::epsilon();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return __base::round_error();} + + static _LIBCPP_CONSTEXPR const int min_exponent = __base::min_exponent; + static _LIBCPP_CONSTEXPR const int min_exponent10 = __base::min_exponent10; + static _LIBCPP_CONSTEXPR const int max_exponent = __base::max_exponent; + static _LIBCPP_CONSTEXPR const int max_exponent10 = __base::max_exponent10; + + static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity; + static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN; + static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN; + static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm; + static _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __base::infinity();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __base::quiet_NaN();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __base::signaling_NaN();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __base::denorm_min();} + + static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559; + static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded; + static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo; + + static _LIBCPP_CONSTEXPR const bool traps = __base::traps; + static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before; + static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style; +}; + +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_specialized; +template + _LIBCPP_CONSTEXPR const int numeric_limits::digits; +template + _LIBCPP_CONSTEXPR const int numeric_limits::digits10; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_digits10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_signed; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_integer; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_exact; +template + _LIBCPP_CONSTEXPR const int numeric_limits::radix; +template + _LIBCPP_CONSTEXPR const int numeric_limits::min_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits::min_exponent10; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_exponent10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_infinity; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_quiet_NaN; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_signaling_NaN; +template + _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits::has_denorm; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_denorm_loss; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_iec559; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_bounded; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_modulo; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::traps; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::tinyness_before; +template + _LIBCPP_CONSTEXPR const float_round_style numeric_limits::round_style; + +template +class _LIBCPP_TYPE_VIS_ONLY numeric_limits + : private numeric_limits<_Tp> +{ + typedef numeric_limits<_Tp> __base; + typedef _Tp type; +public: + static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __base::min();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __base::max();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return __base::lowest();} + + static _LIBCPP_CONSTEXPR const int digits = __base::digits; + static _LIBCPP_CONSTEXPR const int digits10 = __base::digits10; + static _LIBCPP_CONSTEXPR const int max_digits10 = __base::max_digits10; + static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed; + static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer; + static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact; + static _LIBCPP_CONSTEXPR const int radix = __base::radix; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __base::epsilon();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return __base::round_error();} + + static _LIBCPP_CONSTEXPR const int min_exponent = __base::min_exponent; + static _LIBCPP_CONSTEXPR const int min_exponent10 = __base::min_exponent10; + static _LIBCPP_CONSTEXPR const int max_exponent = __base::max_exponent; + static _LIBCPP_CONSTEXPR const int max_exponent10 = __base::max_exponent10; + + static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity; + static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN; + static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN; + static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm; + static _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss; + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __base::infinity();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __base::quiet_NaN();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __base::signaling_NaN();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __base::denorm_min();} + + static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559; + static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded; + static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo; + + static _LIBCPP_CONSTEXPR const bool traps = __base::traps; + static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before; + static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style; +}; + +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_specialized; +template + _LIBCPP_CONSTEXPR const int numeric_limits::digits; +template + _LIBCPP_CONSTEXPR const int numeric_limits::digits10; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_digits10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_signed; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_integer; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_exact; +template + _LIBCPP_CONSTEXPR const int numeric_limits::radix; +template + _LIBCPP_CONSTEXPR const int numeric_limits::min_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits::min_exponent10; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_exponent10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_infinity; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_quiet_NaN; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_signaling_NaN; +template + _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits::has_denorm; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_denorm_loss; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_iec559; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_bounded; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_modulo; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::traps; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::tinyness_before; +template + _LIBCPP_CONSTEXPR const float_round_style numeric_limits::round_style; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_LIMITS diff --git a/headers/libs/libc++/list b/headers/libs/libc++/list new file mode 100644 index 0000000000..28d505582c --- /dev/null +++ b/headers/libs/libc++/list @@ -0,0 +1,2329 @@ +// -*- C++ -*- +//===---------------------------- list ------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_LIST +#define _LIBCPP_LIST + +/* + list synopsis + +namespace std +{ + +template > +class list +{ +public: + + // types: + typedef T value_type; + typedef Alloc allocator_type; + typedef typename allocator_type::reference reference; + typedef typename allocator_type::const_reference const_reference; + typedef typename allocator_type::pointer pointer; + typedef typename allocator_type::const_pointer const_pointer; + typedef implementation-defined iterator; + typedef implementation-defined const_iterator; + typedef implementation-defined size_type; + typedef implementation-defined difference_type; + typedef reverse_iterator reverse_iterator; + typedef reverse_iterator const_reverse_iterator; + + list() + noexcept(is_nothrow_default_constructible::value); + explicit list(const allocator_type& a); + explicit list(size_type n); + explicit list(size_type n, const allocator_type& a); // C++14 + list(size_type n, const value_type& value); + list(size_type n, const value_type& value, const allocator_type& a); + template + list(Iter first, Iter last); + template + list(Iter first, Iter last, const allocator_type& a); + list(const list& x); + list(const list&, const allocator_type& a); + list(list&& x) + noexcept(is_nothrow_move_constructible::value); + list(list&&, const allocator_type& a); + list(initializer_list); + list(initializer_list, const allocator_type& a); + + ~list(); + + list& operator=(const list& x); + list& operator=(list&& x) + noexcept( + allocator_type::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value); + list& operator=(initializer_list); + template + void assign(Iter first, Iter last); + void assign(size_type n, const value_type& t); + void assign(initializer_list); + + allocator_type get_allocator() const noexcept; + + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + reference front(); + const_reference front() const; + reference back(); + const_reference back() const; + + bool empty() const noexcept; + size_type size() const noexcept; + size_type max_size() const noexcept; + + template + void emplace_front(Args&&... args); + void pop_front(); + template + void emplace_back(Args&&... args); + void pop_back(); + void push_front(const value_type& x); + void push_front(value_type&& x); + void push_back(const value_type& x); + void push_back(value_type&& x); + template + iterator emplace(const_iterator position, Args&&... args); + iterator insert(const_iterator position, const value_type& x); + iterator insert(const_iterator position, value_type&& x); + iterator insert(const_iterator position, size_type n, const value_type& x); + template + iterator insert(const_iterator position, Iter first, Iter last); + iterator insert(const_iterator position, initializer_list il); + + iterator erase(const_iterator position); + iterator erase(const_iterator position, const_iterator last); + + void resize(size_type sz); + void resize(size_type sz, const value_type& c); + + void swap(list&) + noexcept(allocator_traits::is_always_equal::value); // C++17 + void clear() noexcept; + + void splice(const_iterator position, list& x); + void splice(const_iterator position, list&& x); + void splice(const_iterator position, list& x, const_iterator i); + void splice(const_iterator position, list&& x, const_iterator i); + void splice(const_iterator position, list& x, const_iterator first, + const_iterator last); + void splice(const_iterator position, list&& x, const_iterator first, + const_iterator last); + + void remove(const value_type& value); + template void remove_if(Pred pred); + void unique(); + template + void unique(BinaryPredicate binary_pred); + void merge(list& x); + void merge(list&& x); + template + void merge(list& x, Compare comp); + template + void merge(list&& x, Compare comp); + void sort(); + template + void sort(Compare comp); + void reverse() noexcept; +}; + +template + bool operator==(const list& x, const list& y); +template + bool operator< (const list& x, const list& y); +template + bool operator!=(const list& x, const list& y); +template + bool operator> (const list& x, const list& y); +template + bool operator>=(const list& x, const list& y); +template + bool operator<=(const list& x, const list& y); + +template + void swap(list& x, list& y) + noexcept(noexcept(x.swap(y))); + +} // std + +*/ + +#include <__config> + +#include +#include +#include +#include +#include + +#include <__undef_min_max> + +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template struct __list_node; + +template +struct __list_node_base +{ + typedef typename __rebind_pointer<_VoidPtr, __list_node<_Tp, _VoidPtr> >::type + pointer; + typedef typename __rebind_pointer<_VoidPtr, __list_node_base>::type + __base_pointer; + + pointer __prev_; + pointer __next_; + + _LIBCPP_INLINE_VISIBILITY + __list_node_base() : __prev_(__self()), __next_(__self()) {} + + _LIBCPP_INLINE_VISIBILITY + pointer __self() + { + return static_cast(pointer_traits<__base_pointer>::pointer_to(*this)); + } +}; + +template +struct __list_node + : public __list_node_base<_Tp, _VoidPtr> +{ + _Tp __value_; +}; + +template > class _LIBCPP_TYPE_VIS_ONLY list; +template class __list_imp; +template class _LIBCPP_TYPE_VIS_ONLY __list_const_iterator; + +template +class _LIBCPP_TYPE_VIS_ONLY __list_iterator +{ + typedef typename __rebind_pointer<_VoidPtr, __list_node<_Tp, _VoidPtr> >::type + __node_pointer; + + __node_pointer __ptr_; + +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + explicit __list_iterator(__node_pointer __p, const void* __c) _NOEXCEPT + : __ptr_(__p) + { + __get_db()->__insert_ic(this, __c); + } +#else + _LIBCPP_INLINE_VISIBILITY + explicit __list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} +#endif + + + + template friend class list; + template friend class __list_imp; + template friend class __list_const_iterator; +public: + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef value_type& reference; + typedef typename __rebind_pointer<_VoidPtr, value_type>::type pointer; + typedef typename pointer_traits::difference_type difference_type; + + _LIBCPP_INLINE_VISIBILITY + __list_iterator() _NOEXCEPT : __ptr_(nullptr) + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_i(this); +#endif + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + __list_iterator(const __list_iterator& __p) + : __ptr_(__p.__ptr_) + { + __get_db()->__iterator_copy(this, &__p); + } + + _LIBCPP_INLINE_VISIBILITY + ~__list_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __list_iterator& operator=(const __list_iterator& __p) + { + if (this != &__p) + { + __get_db()->__iterator_copy(this, &__p); + __ptr_ = __p.__ptr_; + } + return *this; + } + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable list::iterator"); +#endif + return __ptr_->__value_; + } + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable list::iterator"); +#endif + return pointer_traits::pointer_to(__ptr_->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __list_iterator& operator++() + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable list::iterator"); +#endif + __ptr_ = __ptr_->__next_; + return *this; + } + _LIBCPP_INLINE_VISIBILITY + __list_iterator operator++(int) {__list_iterator __t(*this); ++(*this); return __t;} + + _LIBCPP_INLINE_VISIBILITY + __list_iterator& operator--() + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), + "Attempted to decrement non-decrementable list::iterator"); +#endif + __ptr_ = __ptr_->__prev_; + return *this; + } + _LIBCPP_INLINE_VISIBILITY + __list_iterator operator--(int) {__list_iterator __t(*this); --(*this); return __t;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __list_iterator& __x, const __list_iterator& __y) + { + return __x.__ptr_ == __y.__ptr_; + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __list_iterator& __x, const __list_iterator& __y) + {return !(__x == __y);} +}; + +template +class _LIBCPP_TYPE_VIS_ONLY __list_const_iterator +{ + typedef typename __rebind_pointer<_VoidPtr, __list_node<_Tp, _VoidPtr> >::type + __node_pointer; + + __node_pointer __ptr_; + +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + explicit __list_const_iterator(__node_pointer __p, const void* __c) _NOEXCEPT + : __ptr_(__p) + { + __get_db()->__insert_ic(this, __c); + } +#else + _LIBCPP_INLINE_VISIBILITY + explicit __list_const_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} +#endif + + template friend class list; + template friend class __list_imp; +public: + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef const value_type& reference; + typedef typename __rebind_pointer<_VoidPtr, const value_type>::type pointer; + typedef typename pointer_traits::difference_type difference_type; + + _LIBCPP_INLINE_VISIBILITY + __list_const_iterator() _NOEXCEPT : __ptr_(nullptr) + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_i(this); +#endif + } + _LIBCPP_INLINE_VISIBILITY + __list_const_iterator(const __list_iterator<_Tp, _VoidPtr>& __p) _NOEXCEPT + : __ptr_(__p.__ptr_) + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__iterator_copy(this, &__p); +#endif + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + __list_const_iterator(const __list_const_iterator& __p) + : __ptr_(__p.__ptr_) + { + __get_db()->__iterator_copy(this, &__p); + } + + _LIBCPP_INLINE_VISIBILITY + ~__list_const_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __list_const_iterator& operator=(const __list_const_iterator& __p) + { + if (this != &__p) + { + __get_db()->__iterator_copy(this, &__p); + __ptr_ = __p.__ptr_; + } + return *this; + } + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + reference operator*() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable list::const_iterator"); +#endif + return __ptr_->__value_; + } + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable list::iterator"); +#endif + return pointer_traits::pointer_to(__ptr_->__value_); + } + + _LIBCPP_INLINE_VISIBILITY + __list_const_iterator& operator++() + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable list::const_iterator"); +#endif + __ptr_ = __ptr_->__next_; + return *this; + } + _LIBCPP_INLINE_VISIBILITY + __list_const_iterator operator++(int) {__list_const_iterator __t(*this); ++(*this); return __t;} + + _LIBCPP_INLINE_VISIBILITY + __list_const_iterator& operator--() + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), + "Attempted to decrement non-decrementable list::const_iterator"); +#endif + __ptr_ = __ptr_->__prev_; + return *this; + } + _LIBCPP_INLINE_VISIBILITY + __list_const_iterator operator--(int) {__list_const_iterator __t(*this); --(*this); return __t;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __list_const_iterator& __x, const __list_const_iterator& __y) + { + return __x.__ptr_ == __y.__ptr_; + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __list_const_iterator& __x, const __list_const_iterator& __y) + {return !(__x == __y);} +}; + +template +class __list_imp +{ + __list_imp(const __list_imp&); + __list_imp& operator=(const __list_imp&); +protected: + typedef _Tp value_type; + typedef _Alloc allocator_type; + typedef allocator_traits __alloc_traits; + typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::void_pointer __void_pointer; + typedef __list_iterator iterator; + typedef __list_const_iterator const_iterator; + typedef __list_node_base __node_base; + typedef __list_node __node; + typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; + typedef allocator_traits<__node_allocator> __node_alloc_traits; + typedef typename __node_alloc_traits::pointer __node_pointer; + typedef typename __node_alloc_traits::pointer __node_const_pointer; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; + typedef typename __alloc_traits::difference_type difference_type; + + typedef typename __rebind_alloc_helper<__alloc_traits, __node_base>::type __node_base_allocator; + typedef typename allocator_traits<__node_base_allocator>::pointer __node_base_pointer; + + __node_base __end_; + __compressed_pair __size_alloc_; + + _LIBCPP_INLINE_VISIBILITY + size_type& __sz() _NOEXCEPT {return __size_alloc_.first();} + _LIBCPP_INLINE_VISIBILITY + const size_type& __sz() const _NOEXCEPT + {return __size_alloc_.first();} + _LIBCPP_INLINE_VISIBILITY + __node_allocator& __node_alloc() _NOEXCEPT + {return __size_alloc_.second();} + _LIBCPP_INLINE_VISIBILITY + const __node_allocator& __node_alloc() const _NOEXCEPT + {return __size_alloc_.second();} + + static void __unlink_nodes(__node_pointer __f, __node_pointer __l) _NOEXCEPT; + + __list_imp() + _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value); + __list_imp(const allocator_type& __a); + ~__list_imp(); + void clear() _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + bool empty() const _NOEXCEPT {return __sz() == 0;} + + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__end_.__next_, this); +#else + return iterator(__end_.__next_); +#endif + } + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_iterator(__end_.__next_, this); +#else + return const_iterator(__end_.__next_); +#endif + } + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(static_cast<__node_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(__end_)), this); +#else + return iterator(static_cast<__node_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(__end_))); +#endif + } + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_iterator(static_cast<__node_const_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(__end_))), this); +#else + return const_iterator(static_cast<__node_const_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(__end_)))); +#endif + } + + void swap(__list_imp& __c) +#if _LIBCPP_STD_VER >= 14 + _NOEXCEPT; +#else + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + __is_nothrow_swappable::value); +#endif + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __list_imp& __c) + {__copy_assign_alloc(__c, integral_constant());} + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__list_imp& __c) + _NOEXCEPT_( + !__node_alloc_traits::propagate_on_container_move_assignment::value || + is_nothrow_move_assignable<__node_allocator>::value) + {__move_assign_alloc(__c, integral_constant());} + +private: + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __list_imp& __c, true_type) + { + if (__node_alloc() != __c.__node_alloc()) + clear(); + __node_alloc() = __c.__node_alloc(); + } + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const __list_imp& __c, false_type) + {} + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__list_imp& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) + { + __node_alloc() = _VSTD::move(__c.__node_alloc()); + } + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__list_imp& __c, false_type) + _NOEXCEPT + {} +}; + +// Unlink nodes [__f, __l] +template +inline _LIBCPP_INLINE_VISIBILITY +void +__list_imp<_Tp, _Alloc>::__unlink_nodes(__node_pointer __f, __node_pointer __l) + _NOEXCEPT +{ + __f->__prev_->__next_ = __l->__next_; + __l->__next_->__prev_ = __f->__prev_; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__list_imp<_Tp, _Alloc>::__list_imp() + _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) + : __size_alloc_(0) +{ +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__list_imp<_Tp, _Alloc>::__list_imp(const allocator_type& __a) + : __size_alloc_(0, __node_allocator(__a)) +{ +} + +template +__list_imp<_Tp, _Alloc>::~__list_imp() +{ + clear(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__erase_c(this); +#endif +} + +template +void +__list_imp<_Tp, _Alloc>::clear() _NOEXCEPT +{ + if (!empty()) + { + __node_allocator& __na = __node_alloc(); + __node_pointer __f = __end_.__next_; + __node_pointer __l = static_cast<__node_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(__end_)); + __unlink_nodes(__f, __l->__prev_); + __sz() = 0; + while (__f != __l) + { + __node_pointer __n = __f; + __f = __f->__next_; + __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_)); + __node_alloc_traits::deallocate(__na, __n, 1); + } +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + const_iterator* __i = static_cast((*__p)->__i_); + if (__i->__ptr_ != __l) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif + } +} + +template +void +__list_imp<_Tp, _Alloc>::swap(__list_imp& __c) +#if _LIBCPP_STD_VER >= 14 + _NOEXCEPT +#else + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + __is_nothrow_swappable::value) +#endif +{ + _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value || + this->__node_alloc() == __c.__node_alloc(), + "list::swap: Either propagate_on_container_swap must be true" + " or the allocators must compare equal"); + using _VSTD::swap; + __swap_allocator(__node_alloc(), __c.__node_alloc()); + swap(__sz(), __c.__sz()); + swap(__end_, __c.__end_); + if (__sz() == 0) + __end_.__next_ = __end_.__prev_ = __end_.__self(); + else + __end_.__prev_->__next_ = __end_.__next_->__prev_ = __end_.__self(); + if (__c.__sz() == 0) + __c.__end_.__next_ = __c.__end_.__prev_ = __c.__end_.__self(); + else + __c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = __c.__end_.__self(); + +#if _LIBCPP_DEBUG_LEVEL >= 2 + __libcpp_db* __db = __get_db(); + __c_node* __cn1 = __db->__find_c_and_lock(this); + __c_node* __cn2 = __db->__find_c(&__c); + std::swap(__cn1->beg_, __cn2->beg_); + std::swap(__cn1->end_, __cn2->end_); + std::swap(__cn1->cap_, __cn2->cap_); + for (__i_node** __p = __cn1->end_; __p != __cn1->beg_;) + { + --__p; + const_iterator* __i = static_cast((*__p)->__i_); + if (__i->__ptr_ == static_cast<__node_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(__c.__end_))) + { + __cn2->__add(*__p); + if (--__cn1->end_ != __p) + memmove(__p, __p+1, (__cn1->end_ - __p)*sizeof(__i_node*)); + } + else + (*__p)->__c_ = __cn1; + } + for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) + { + --__p; + const_iterator* __i = static_cast((*__p)->__i_); + if (__i->__ptr_ == static_cast<__node_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(__end_))) + { + __cn1->__add(*__p); + if (--__cn2->end_ != __p) + memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); + } + else + (*__p)->__c_ = __cn2; + } + __db->unlock(); +#endif +} + +template */> +class _LIBCPP_TYPE_VIS_ONLY list + : private __list_imp<_Tp, _Alloc> +{ + typedef __list_imp<_Tp, _Alloc> base; + typedef typename base::__node __node; + typedef typename base::__node_allocator __node_allocator; + typedef typename base::__node_pointer __node_pointer; + typedef typename base::__node_alloc_traits __node_alloc_traits; + typedef typename base::__node_base __node_base; + typedef typename base::__node_base_pointer __node_base_pointer; + +public: + typedef _Tp value_type; + typedef _Alloc allocator_type; + static_assert((is_same::value), + "Invalid allocator::value_type"); + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename base::pointer pointer; + typedef typename base::const_pointer const_pointer; + typedef typename base::size_type size_type; + typedef typename base::difference_type difference_type; + typedef typename base::iterator iterator; + typedef typename base::const_iterator const_iterator; + typedef _VSTD::reverse_iterator reverse_iterator; + typedef _VSTD::reverse_iterator const_reverse_iterator; + + _LIBCPP_INLINE_VISIBILITY + list() + _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + } + _LIBCPP_INLINE_VISIBILITY + explicit list(const allocator_type& __a) : base(__a) + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + } + explicit list(size_type __n); +#if _LIBCPP_STD_VER > 11 + explicit list(size_type __n, const allocator_type& __a); +#endif + list(size_type __n, const value_type& __x); + list(size_type __n, const value_type& __x, const allocator_type& __a); + template + list(_InpIter __f, _InpIter __l, + typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0); + template + list(_InpIter __f, _InpIter __l, const allocator_type& __a, + typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0); + + list(const list& __c); + list(const list& __c, const allocator_type& __a); + list& operator=(const list& __c); +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + list(initializer_list __il); + list(initializer_list __il, const allocator_type& __a); +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + list(list&& __c) + _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value); + list(list&& __c, const allocator_type& __a); + list& operator=(list&& __c) + _NOEXCEPT_( + __node_alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable<__node_allocator>::value); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY + list& operator=(initializer_list __il) + {assign(__il.begin(), __il.end()); return *this;} +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + template + void assign(_InpIter __f, _InpIter __l, + typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0); + void assign(size_type __n, const value_type& __x); +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY + void assign(initializer_list __il) + {assign(__il.begin(), __il.end());} +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + allocator_type get_allocator() const _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT {return base::__sz();} + _LIBCPP_INLINE_VISIBILITY + bool empty() const _NOEXCEPT {return base::empty();} + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT + {return numeric_limits::max();} + + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT {return base::begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT {return base::begin();} + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT {return base::end();} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT {return base::end();} + _LIBCPP_INLINE_VISIBILITY + const_iterator cbegin() const _NOEXCEPT {return base::begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator cend() const _NOEXCEPT {return base::end();} + + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rbegin() _NOEXCEPT + {return reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rbegin() const _NOEXCEPT + {return const_reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rend() _NOEXCEPT + {return reverse_iterator(begin());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rend() const _NOEXCEPT + {return const_reverse_iterator(begin());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crbegin() const _NOEXCEPT + {return const_reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crend() const _NOEXCEPT + {return const_reverse_iterator(begin());} + + _LIBCPP_INLINE_VISIBILITY + reference front() + { + _LIBCPP_ASSERT(!empty(), "list::front called on empty list"); + return base::__end_.__next_->__value_; + } + _LIBCPP_INLINE_VISIBILITY + const_reference front() const + { + _LIBCPP_ASSERT(!empty(), "list::front called on empty list"); + return base::__end_.__next_->__value_; + } + _LIBCPP_INLINE_VISIBILITY + reference back() + { + _LIBCPP_ASSERT(!empty(), "list::back called on empty list"); + return base::__end_.__prev_->__value_; + } + _LIBCPP_INLINE_VISIBILITY + const_reference back() const + { + _LIBCPP_ASSERT(!empty(), "list::back called on empty list"); + return base::__end_.__prev_->__value_; + } + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + void push_front(value_type&& __x); + void push_back(value_type&& __x); +#ifndef _LIBCPP_HAS_NO_VARIADICS + template + void emplace_front(_Args&&... __args); + template + void emplace_back(_Args&&... __args); + template + iterator emplace(const_iterator __p, _Args&&... __args); +#endif // _LIBCPP_HAS_NO_VARIADICS + iterator insert(const_iterator __p, value_type&& __x); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + void push_front(const value_type& __x); + void push_back(const value_type& __x); + + iterator insert(const_iterator __p, const value_type& __x); + iterator insert(const_iterator __p, size_type __n, const value_type& __x); + template + iterator insert(const_iterator __p, _InpIter __f, _InpIter __l, + typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0); +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __p, initializer_list __il) + {return insert(__p, __il.begin(), __il.end());} +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + _LIBCPP_INLINE_VISIBILITY + void swap(list& __c) +#if _LIBCPP_STD_VER >= 14 + _NOEXCEPT +#else + _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value || + __is_nothrow_swappable<__node_allocator>::value) +#endif + {base::swap(__c);} + _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT {base::clear();} + + void pop_front(); + void pop_back(); + + iterator erase(const_iterator __p); + iterator erase(const_iterator __f, const_iterator __l); + + void resize(size_type __n); + void resize(size_type __n, const value_type& __x); + + void splice(const_iterator __p, list& __c); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + void splice(const_iterator __p, list&& __c) {splice(__p, __c);} +#endif + void splice(const_iterator __p, list& __c, const_iterator __i); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + void splice(const_iterator __p, list&& __c, const_iterator __i) + {splice(__p, __c, __i);} +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + void splice(const_iterator __p, list&& __c, const_iterator __f, const_iterator __l) + {splice(__p, __c, __f, __l);} +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + void remove(const value_type& __x); + template void remove_if(_Pred __pred); + void unique(); + template + void unique(_BinaryPred __binary_pred); + void merge(list& __c); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + void merge(list&& __c) {merge(__c);} +#endif + template + void merge(list& __c, _Comp __comp); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + template + _LIBCPP_INLINE_VISIBILITY + void merge(list&& __c, _Comp __comp) {merge(__c, __comp);} +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + void sort(); + template + void sort(_Comp __comp); + + void reverse() _NOEXCEPT; + + bool __invariants() const; + +#if _LIBCPP_DEBUG_LEVEL >= 2 + + bool __dereferenceable(const const_iterator* __i) const; + bool __decrementable(const const_iterator* __i) const; + bool __addable(const const_iterator* __i, ptrdiff_t __n) const; + bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + +private: + static void __link_nodes (__node_pointer __p, __node_pointer __f, __node_pointer __l); + void __link_nodes_at_front(__node_pointer __f, __node_pointer __l); + void __link_nodes_at_back (__node_pointer __f, __node_pointer __l); + iterator __iterator(size_type __n); + template + static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp); + + void __move_assign(list& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value); + void __move_assign(list& __c, false_type); +}; + +// Link in nodes [__f, __l] just prior to __p +template +inline _LIBCPP_INLINE_VISIBILITY +void +list<_Tp, _Alloc>::__link_nodes(__node_pointer __p, __node_pointer __f, __node_pointer __l) +{ + __p->__prev_->__next_ = __f; + __f->__prev_ = __p->__prev_; + __p->__prev_ = __l; + __l->__next_ = __p; +} + +// Link in nodes [__f, __l] at the front of the list +template +inline _LIBCPP_INLINE_VISIBILITY +void +list<_Tp, _Alloc>::__link_nodes_at_front(__node_pointer __f, __node_pointer __l) +{ + __f->__prev_ = base::__end_.__self(); + __l->__next_ = base::__end_.__next_; + __l->__next_->__prev_ = __l; + base::__end_.__next_ = __f; +} + +// Link in nodes [__f, __l] at the front of the list +template +inline _LIBCPP_INLINE_VISIBILITY +void +list<_Tp, _Alloc>::__link_nodes_at_back(__node_pointer __f, __node_pointer __l) +{ + __l->__next_ = base::__end_.__self(); + __f->__prev_ = base::__end_.__prev_; + __f->__prev_->__next_ = __f; + base::__end_.__prev_ = __l; +} + + +template +inline _LIBCPP_INLINE_VISIBILITY +typename list<_Tp, _Alloc>::iterator +list<_Tp, _Alloc>::__iterator(size_type __n) +{ + return __n <= base::__sz() / 2 ? _VSTD::next(begin(), __n) + : _VSTD::prev(end(), base::__sz() - __n); +} + +template +list<_Tp, _Alloc>::list(size_type __n) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + for (; __n > 0; --__n) +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + emplace_back(); +#else + push_back(value_type()); +#endif +} + +#if _LIBCPP_STD_VER > 11 +template +list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + for (; __n > 0; --__n) +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + emplace_back(); +#else + push_back(value_type()); +#endif +} +#endif + +template +list<_Tp, _Alloc>::list(size_type __n, const value_type& __x) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + for (; __n > 0; --__n) + push_back(__x); +} + +template +list<_Tp, _Alloc>::list(size_type __n, const value_type& __x, const allocator_type& __a) + : base(__a) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + for (; __n > 0; --__n) + push_back(__x); +} + +template +template +list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, + typename enable_if<__is_input_iterator<_InpIter>::value>::type*) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + for (; __f != __l; ++__f) + push_back(*__f); +} + +template +template +list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a, + typename enable_if<__is_input_iterator<_InpIter>::value>::type*) + : base(__a) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + for (; __f != __l; ++__f) + push_back(*__f); +} + +template +list<_Tp, _Alloc>::list(const list& __c) + : base(allocator_type( + __node_alloc_traits::select_on_container_copy_construction( + __c.__node_alloc()))) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) + push_back(*__i); +} + +template +list<_Tp, _Alloc>::list(const list& __c, const allocator_type& __a) + : base(__a) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) + push_back(*__i); +} + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +template +list<_Tp, _Alloc>::list(initializer_list __il, const allocator_type& __a) + : base(__a) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + for (typename initializer_list::const_iterator __i = __il.begin(), + __e = __il.end(); __i != __e; ++__i) + push_back(*__i); +} + +template +list<_Tp, _Alloc>::list(initializer_list __il) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + for (typename initializer_list::const_iterator __i = __il.begin(), + __e = __il.end(); __i != __e; ++__i) + push_back(*__i); +} + +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +template +inline _LIBCPP_INLINE_VISIBILITY +list<_Tp, _Alloc>& +list<_Tp, _Alloc>::operator=(const list& __c) +{ + if (this != &__c) + { + base::__copy_assign_alloc(__c); + assign(__c.begin(), __c.end()); + } + return *this; +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline _LIBCPP_INLINE_VISIBILITY +list<_Tp, _Alloc>::list(list&& __c) + _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) + : base(allocator_type(_VSTD::move(__c.__node_alloc()))) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + splice(end(), __c); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +list<_Tp, _Alloc>::list(list&& __c, const allocator_type& __a) + : base(__a) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + if (__a == __c.get_allocator()) + splice(end(), __c); + else + { + typedef move_iterator _Ip; + assign(_Ip(__c.begin()), _Ip(__c.end())); + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +list<_Tp, _Alloc>& +list<_Tp, _Alloc>::operator=(list&& __c) + _NOEXCEPT_( + __node_alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable<__node_allocator>::value) +{ + __move_assign(__c, integral_constant()); + return *this; +} + +template +void +list<_Tp, _Alloc>::__move_assign(list& __c, false_type) +{ + if (base::__node_alloc() != __c.__node_alloc()) + { + typedef move_iterator _Ip; + assign(_Ip(__c.begin()), _Ip(__c.end())); + } + else + __move_assign(__c, true_type()); +} + +template +void +list<_Tp, _Alloc>::__move_assign(list& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) +{ + clear(); + base::__move_assign_alloc(__c); + splice(end(), __c); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +template +void +list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l, + typename enable_if<__is_input_iterator<_InpIter>::value>::type*) +{ + iterator __i = begin(); + iterator __e = end(); + for (; __f != __l && __i != __e; ++__f, ++__i) + *__i = *__f; + if (__i == __e) + insert(__e, __f, __l); + else + erase(__i, __e); +} + +template +void +list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x) +{ + iterator __i = begin(); + iterator __e = end(); + for (; __n > 0 && __i != __e; --__n, ++__i) + *__i = __x; + if (__i == __e) + insert(__e, __n, __x); + else + erase(__i, __e); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Alloc +list<_Tp, _Alloc>::get_allocator() const _NOEXCEPT +{ + return allocator_type(base::__node_alloc()); +} + +template +typename list<_Tp, _Alloc>::iterator +list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "list::insert(iterator, x) called with an iterator not" + " referring to this list"); +#endif + __node_allocator& __na = base::__node_alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __hold->__prev_ = 0; + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); + __link_nodes(__p.__ptr_, __hold.get(), __hold.get()); + ++base::__sz(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__hold.release(), this); +#else + return iterator(__hold.release()); +#endif +} + +template +typename list<_Tp, _Alloc>::iterator +list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& __x) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "list::insert(iterator, n, x) called with an iterator not" + " referring to this list"); + iterator __r(__p.__ptr_, this); +#else + iterator __r(__p.__ptr_); +#endif + if (__n > 0) + { + size_type __ds = 0; + __node_allocator& __na = base::__node_alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __hold->__prev_ = 0; + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); + ++__ds; +#if _LIBCPP_DEBUG_LEVEL >= 2 + __r = iterator(__hold.get(), this); +#else + __r = iterator(__hold.get()); +#endif + __hold.release(); + iterator __e = __r; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (--__n; __n != 0; --__n, ++__e, ++__ds) + { + __hold.reset(__node_alloc_traits::allocate(__na, 1)); + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); + __e.__ptr_->__next_ = __hold.get(); + __hold->__prev_ = __e.__ptr_; + __hold.release(); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + while (true) + { + __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); + __node_pointer __prev = __e.__ptr_->__prev_; + __node_alloc_traits::deallocate(__na, __e.__ptr_, 1); + if (__prev == 0) + break; +#if _LIBCPP_DEBUG_LEVEL >= 2 + __e = iterator(__prev, this); +#else + __e = iterator(__prev); +#endif + } + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_); + base::__sz() += __ds; + } + return __r; +} + +template +template +typename list<_Tp, _Alloc>::iterator +list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l, + typename enable_if<__is_input_iterator<_InpIter>::value>::type*) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "list::insert(iterator, range) called with an iterator not" + " referring to this list"); + iterator __r(__p.__ptr_, this); +#else + iterator __r(__p.__ptr_); +#endif + if (__f != __l) + { + size_type __ds = 0; + __node_allocator& __na = base::__node_alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __hold->__prev_ = 0; + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f); + ++__ds; +#if _LIBCPP_DEBUG_LEVEL >= 2 + __r = iterator(__hold.get(), this); +#else + __r = iterator(__hold.get()); +#endif + __hold.release(); + iterator __e = __r; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (++__f; __f != __l; ++__f, (void) ++__e, (void) ++__ds) + { + __hold.reset(__node_alloc_traits::allocate(__na, 1)); + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f); + __e.__ptr_->__next_ = __hold.get(); + __hold->__prev_ = __e.__ptr_; + __hold.release(); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + while (true) + { + __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); + __node_pointer __prev = __e.__ptr_->__prev_; + __node_alloc_traits::deallocate(__na, __e.__ptr_, 1); + if (__prev == 0) + break; +#if _LIBCPP_DEBUG_LEVEL >= 2 + __e = iterator(__prev, this); +#else + __e = iterator(__prev); +#endif + } + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_); + base::__sz() += __ds; + } + return __r; +} + +template +void +list<_Tp, _Alloc>::push_front(const value_type& __x) +{ + __node_allocator& __na = base::__node_alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); + __link_nodes_at_front(__hold.get(), __hold.get()); + ++base::__sz(); + __hold.release(); +} + +template +void +list<_Tp, _Alloc>::push_back(const value_type& __x) +{ + __node_allocator& __na = base::__node_alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); + __link_nodes_at_back(__hold.get(), __hold.get()); + ++base::__sz(); + __hold.release(); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +list<_Tp, _Alloc>::push_front(value_type&& __x) +{ + __node_allocator& __na = base::__node_alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); + __link_nodes_at_front(__hold.get(), __hold.get()); + ++base::__sz(); + __hold.release(); +} + +template +void +list<_Tp, _Alloc>::push_back(value_type&& __x) +{ + __node_allocator& __na = base::__node_alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); + __link_nodes_at_back(__hold.get(), __hold.get()); + ++base::__sz(); + __hold.release(); +} + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +template +template +void +list<_Tp, _Alloc>::emplace_front(_Args&&... __args) +{ + __node_allocator& __na = base::__node_alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); + __link_nodes_at_front(__hold.get(), __hold.get()); + ++base::__sz(); + __hold.release(); +} + +template +template +void +list<_Tp, _Alloc>::emplace_back(_Args&&... __args) +{ + __node_allocator& __na = base::__node_alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); + __link_nodes_at_back(__hold.get(), __hold.get()); + ++base::__sz(); + __hold.release(); +} + +template +template +typename list<_Tp, _Alloc>::iterator +list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "list::emplace(iterator, args...) called with an iterator not" + " referring to this list"); +#endif + __node_allocator& __na = base::__node_alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __hold->__prev_ = 0; + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); + __link_nodes(__p.__ptr_, __hold.get(), __hold.get()); + ++base::__sz(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__hold.release(), this); +#else + return iterator(__hold.release()); +#endif +} + +#endif // _LIBCPP_HAS_NO_VARIADICS + +template +typename list<_Tp, _Alloc>::iterator +list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "list::insert(iterator, x) called with an iterator not" + " referring to this list"); +#endif + __node_allocator& __na = base::__node_alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __hold->__prev_ = 0; + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); + __link_nodes(__p.__ptr_, __hold.get(), __hold.get()); + ++base::__sz(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__hold.release(), this); +#else + return iterator(__hold.release()); +#endif +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +void +list<_Tp, _Alloc>::pop_front() +{ + _LIBCPP_ASSERT(!empty(), "list::pop_front() called with empty list"); + __node_allocator& __na = base::__node_alloc(); + __node_pointer __n = base::__end_.__next_; + base::__unlink_nodes(__n, __n); + --base::__sz(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + iterator* __i = static_cast((*__p)->__i_); + if (__i->__ptr_ == __n) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif + __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_)); + __node_alloc_traits::deallocate(__na, __n, 1); +} + +template +void +list<_Tp, _Alloc>::pop_back() +{ + _LIBCPP_ASSERT(!empty(), "list::pop_back() called with empty list"); + __node_allocator& __na = base::__node_alloc(); + __node_pointer __n = base::__end_.__prev_; + base::__unlink_nodes(__n, __n); + --base::__sz(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + iterator* __i = static_cast((*__p)->__i_); + if (__i->__ptr_ == __n) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif + __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_)); + __node_alloc_traits::deallocate(__na, __n, 1); +} + +template +typename list<_Tp, _Alloc>::iterator +list<_Tp, _Alloc>::erase(const_iterator __p) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "list::erase(iterator) called with an iterator not" + " referring to this list"); +#endif + _LIBCPP_ASSERT(__p != end(), + "list::erase(iterator) called with a non-dereferenceable iterator"); + __node_allocator& __na = base::__node_alloc(); + __node_pointer __n = __p.__ptr_; + __node_pointer __r = __n->__next_; + base::__unlink_nodes(__n, __n); + --base::__sz(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + iterator* __i = static_cast((*__p)->__i_); + if (__i->__ptr_ == __n) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif + __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_)); + __node_alloc_traits::deallocate(__na, __n, 1); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__r, this); +#else + return iterator(__r); +#endif +} + +template +typename list<_Tp, _Alloc>::iterator +list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__f) == this, + "list::erase(iterator, iterator) called with an iterator not" + " referring to this list"); +#endif + if (__f != __l) + { + __node_allocator& __na = base::__node_alloc(); + base::__unlink_nodes(__f.__ptr_, __l.__ptr_->__prev_); + while (__f != __l) + { + __node_pointer __n = __f.__ptr_; + ++__f; + --base::__sz(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + iterator* __i = static_cast((*__p)->__i_); + if (__i->__ptr_ == __n) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif + __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_)); + __node_alloc_traits::deallocate(__na, __n, 1); + } + } +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__l.__ptr_, this); +#else + return iterator(__l.__ptr_); +#endif +} + +template +void +list<_Tp, _Alloc>::resize(size_type __n) +{ + if (__n < base::__sz()) + erase(__iterator(__n), end()); + else if (__n > base::__sz()) + { + __n -= base::__sz(); + size_type __ds = 0; + __node_allocator& __na = base::__node_alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __hold->__prev_ = 0; + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_)); + ++__ds; +#if _LIBCPP_DEBUG_LEVEL >= 2 + iterator __r = iterator(__hold.release(), this); +#else + iterator __r = iterator(__hold.release()); +#endif + iterator __e = __r; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (--__n; __n != 0; --__n, ++__e, ++__ds) + { + __hold.reset(__node_alloc_traits::allocate(__na, 1)); + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_)); + __e.__ptr_->__next_ = __hold.get(); + __hold->__prev_ = __e.__ptr_; + __hold.release(); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + while (true) + { + __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); + __node_pointer __prev = __e.__ptr_->__prev_; + __node_alloc_traits::deallocate(__na, __e.__ptr_, 1); + if (__prev == 0) + break; +#if _LIBCPP_DEBUG_LEVEL >= 2 + __e = iterator(__prev, this); +#else + __e = iterator(__prev); +#endif + } + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __link_nodes_at_back(__r.__ptr_, __e.__ptr_); + base::__sz() += __ds; + } +} + +template +void +list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x) +{ + if (__n < base::__sz()) + erase(__iterator(__n), end()); + else if (__n > base::__sz()) + { + __n -= base::__sz(); + size_type __ds = 0; + __node_allocator& __na = base::__node_alloc(); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __hold->__prev_ = 0; + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); + ++__ds; +#if _LIBCPP_DEBUG_LEVEL >= 2 + iterator __r = iterator(__hold.release(), this); +#else + iterator __r = iterator(__hold.release()); +#endif + iterator __e = __r; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (--__n; __n != 0; --__n, ++__e, ++__ds) + { + __hold.reset(__node_alloc_traits::allocate(__na, 1)); + __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); + __e.__ptr_->__next_ = __hold.get(); + __hold->__prev_ = __e.__ptr_; + __hold.release(); + } +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + while (true) + { + __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); + __node_pointer __prev = __e.__ptr_->__prev_; + __node_alloc_traits::deallocate(__na, __e.__ptr_, 1); + if (__prev == 0) + break; +#if _LIBCPP_DEBUG_LEVEL >= 2 + __e = iterator(__prev, this); +#else + __e = iterator(__prev); +#endif + } + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + __link_nodes(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>:: + pointer_to(base::__end_)), __r.__ptr_, __e.__ptr_); + base::__sz() += __ds; + } +} + +template +void +list<_Tp, _Alloc>::splice(const_iterator __p, list& __c) +{ + _LIBCPP_ASSERT(this != &__c, + "list::splice(iterator, list) called with this == &list"); +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "list::splice(iterator, list) called with an iterator not" + " referring to this list"); +#endif + if (!__c.empty()) + { + __node_pointer __f = __c.__end_.__next_; + __node_pointer __l = __c.__end_.__prev_; + base::__unlink_nodes(__f, __l); + __link_nodes(__p.__ptr_, __f, __l); + base::__sz() += __c.__sz(); + __c.__sz() = 0; +#if _LIBCPP_DEBUG_LEVEL >= 2 + __libcpp_db* __db = __get_db(); + __c_node* __cn1 = __db->__find_c_and_lock(this); + __c_node* __cn2 = __db->__find_c(&__c); + for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) + { + --__p; + iterator* __i = static_cast((*__p)->__i_); + if (__i->__ptr_ != static_cast<__node_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(__c.__end_))) + { + __cn1->__add(*__p); + (*__p)->__c_ = __cn1; + if (--__cn2->end_ != __p) + memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); + } + } + __db->unlock(); +#endif + } +} + +template +void +list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "list::splice(iterator, list, iterator) called with first iterator not" + " referring to this list"); + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__i) == &__c, + "list::splice(iterator, list, iterator) called with second iterator not" + " referring to list argument"); + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(&__i), + "list::splice(iterator, list, iterator) called with second iterator not" + " derefereceable"); +#endif + if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_) + { + __node_pointer __f = __i.__ptr_; + base::__unlink_nodes(__f, __f); + __link_nodes(__p.__ptr_, __f, __f); + --__c.__sz(); + ++base::__sz(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __libcpp_db* __db = __get_db(); + __c_node* __cn1 = __db->__find_c_and_lock(this); + __c_node* __cn2 = __db->__find_c(&__c); + for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) + { + --__p; + iterator* __j = static_cast((*__p)->__i_); + if (__j->__ptr_ == __f) + { + __cn1->__add(*__p); + (*__p)->__c_ = __cn1; + if (--__cn2->end_ != __p) + memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); + } + } + __db->unlock(); +#endif + } +} + +template +void +list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "list::splice(iterator, list, iterator, iterator) called with first iterator not" + " referring to this list"); + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__f) == &__c, + "list::splice(iterator, list, iterator, iterator) called with second iterator not" + " referring to list argument"); + if (this == &__c) + { + for (const_iterator __i = __f; __i != __l; ++__i) + _LIBCPP_ASSERT(__i != __p, + "list::splice(iterator, list, iterator, iterator)" + " called with the first iterator within the range" + " of the second and third iterators"); + } +#endif + if (__f != __l) + { + if (this != &__c) + { + size_type __s = _VSTD::distance(__f, __l); + __c.__sz() -= __s; + base::__sz() += __s; + } + __node_pointer __first = __f.__ptr_; + --__l; + __node_pointer __last = __l.__ptr_; + base::__unlink_nodes(__first, __last); + __link_nodes(__p.__ptr_, __first, __last); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __libcpp_db* __db = __get_db(); + __c_node* __cn1 = __db->__find_c_and_lock(this); + __c_node* __cn2 = __db->__find_c(&__c); + for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) + { + --__p; + iterator* __j = static_cast((*__p)->__i_); + for (__node_pointer __k = __f.__ptr_; + __k != __l.__ptr_; __k = __k->__next_) + { + if (__j->__ptr_ == __k) + { + __cn1->__add(*__p); + (*__p)->__c_ = __cn1; + if (--__cn2->end_ != __p) + memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); + } + } + } + __db->unlock(); +#endif + } +} + +template +void +list<_Tp, _Alloc>::remove(const value_type& __x) +{ + list<_Tp, _Alloc> __deleted_nodes; // collect the nodes we're removing + for (const_iterator __i = begin(), __e = end(); __i != __e;) + { + if (*__i == __x) + { + const_iterator __j = _VSTD::next(__i); + for (; __j != __e && *__j == __x; ++__j) + ; + __deleted_nodes.splice(__deleted_nodes.end(), *this, __i, __j); + __i = __j; + if (__i != __e) + ++__i; + } + else + ++__i; + } +} + +template +template +void +list<_Tp, _Alloc>::remove_if(_Pred __pred) +{ + for (iterator __i = begin(), __e = end(); __i != __e;) + { + if (__pred(*__i)) + { + iterator __j = _VSTD::next(__i); + for (; __j != __e && __pred(*__j); ++__j) + ; + __i = erase(__i, __j); + if (__i != __e) + ++__i; + } + else + ++__i; + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +list<_Tp, _Alloc>::unique() +{ + unique(__equal_to()); +} + +template +template +void +list<_Tp, _Alloc>::unique(_BinaryPred __binary_pred) +{ + for (iterator __i = begin(), __e = end(); __i != __e;) + { + iterator __j = _VSTD::next(__i); + for (; __j != __e && __binary_pred(*__i, *__j); ++__j) + ; + if (++__i != __j) + __i = erase(__i, __j); + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +list<_Tp, _Alloc>::merge(list& __c) +{ + merge(__c, __less()); +} + +template +template +void +list<_Tp, _Alloc>::merge(list& __c, _Comp __comp) +{ + if (this != &__c) + { + iterator __f1 = begin(); + iterator __e1 = end(); + iterator __f2 = __c.begin(); + iterator __e2 = __c.end(); + while (__f1 != __e1 && __f2 != __e2) + { + if (__comp(*__f2, *__f1)) + { + size_type __ds = 1; + iterator __m2 = _VSTD::next(__f2); + for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2, ++__ds) + ; + base::__sz() += __ds; + __c.__sz() -= __ds; + __node_pointer __f = __f2.__ptr_; + __node_pointer __l = __m2.__ptr_->__prev_; + __f2 = __m2; + base::__unlink_nodes(__f, __l); + __m2 = _VSTD::next(__f1); + __link_nodes(__f1.__ptr_, __f, __l); + __f1 = __m2; + } + else + ++__f1; + } + splice(__e1, __c); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __libcpp_db* __db = __get_db(); + __c_node* __cn1 = __db->__find_c_and_lock(this); + __c_node* __cn2 = __db->__find_c(&__c); + for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) + { + --__p; + iterator* __i = static_cast((*__p)->__i_); + if (__i->__ptr_ != static_cast<__node_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(__c.__end_))) + { + __cn1->__add(*__p); + (*__p)->__c_ = __cn1; + if (--__cn2->end_ != __p) + memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); + } + } + __db->unlock(); +#endif + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +list<_Tp, _Alloc>::sort() +{ + sort(__less()); +} + +template +template +inline _LIBCPP_INLINE_VISIBILITY +void +list<_Tp, _Alloc>::sort(_Comp __comp) +{ + __sort(begin(), end(), base::__sz(), __comp); +} + +template +template +typename list<_Tp, _Alloc>::iterator +list<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp) +{ + switch (__n) + { + case 0: + case 1: + return __f1; + case 2: + if (__comp(*--__e2, *__f1)) + { + __node_pointer __f = __e2.__ptr_; + base::__unlink_nodes(__f, __f); + __link_nodes(__f1.__ptr_, __f, __f); + return __e2; + } + return __f1; + } + size_type __n2 = __n / 2; + iterator __e1 = _VSTD::next(__f1, __n2); + iterator __r = __f1 = __sort(__f1, __e1, __n2, __comp); + iterator __f2 = __e1 = __sort(__e1, __e2, __n - __n2, __comp); + if (__comp(*__f2, *__f1)) + { + iterator __m2 = _VSTD::next(__f2); + for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2) + ; + __node_pointer __f = __f2.__ptr_; + __node_pointer __l = __m2.__ptr_->__prev_; + __r = __f2; + __e1 = __f2 = __m2; + base::__unlink_nodes(__f, __l); + __m2 = _VSTD::next(__f1); + __link_nodes(__f1.__ptr_, __f, __l); + __f1 = __m2; + } + else + ++__f1; + while (__f1 != __e1 && __f2 != __e2) + { + if (__comp(*__f2, *__f1)) + { + iterator __m2 = _VSTD::next(__f2); + for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2) + ; + __node_pointer __f = __f2.__ptr_; + __node_pointer __l = __m2.__ptr_->__prev_; + if (__e1 == __f2) + __e1 = __m2; + __f2 = __m2; + base::__unlink_nodes(__f, __l); + __m2 = _VSTD::next(__f1); + __link_nodes(__f1.__ptr_, __f, __l); + __f1 = __m2; + } + else + ++__f1; + } + return __r; +} + +template +void +list<_Tp, _Alloc>::reverse() _NOEXCEPT +{ + if (base::__sz() > 1) + { + iterator __e = end(); + for (iterator __i = begin(); __i.__ptr_ != __e.__ptr_;) + { + _VSTD::swap(__i.__ptr_->__prev_, __i.__ptr_->__next_); + __i.__ptr_ = __i.__ptr_->__prev_; + } + _VSTD::swap(__e.__ptr_->__prev_, __e.__ptr_->__next_); + } +} + +template +bool +list<_Tp, _Alloc>::__invariants() const +{ + return size() == _VSTD::distance(begin(), end()); +} + +#if _LIBCPP_DEBUG_LEVEL >= 2 + +template +bool +list<_Tp, _Alloc>::__dereferenceable(const const_iterator* __i) const +{ + return __i->__ptr_ != static_cast<__node_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(this->__end_))); +} + +template +bool +list<_Tp, _Alloc>::__decrementable(const const_iterator* __i) const +{ + return !empty() && __i->__ptr_ != base::__end_.__next_; +} + +template +bool +list<_Tp, _Alloc>::__addable(const const_iterator* __i, ptrdiff_t __n) const +{ + return false; +} + +template +bool +list<_Tp, _Alloc>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const +{ + return false; +} + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) +{ + return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator< (const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) +{ + return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator> (const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_LIST diff --git a/headers/libs/libc++/locale b/headers/libs/libc++/locale new file mode 100644 index 0000000000..84cb5a5ef6 --- /dev/null +++ b/headers/libs/libc++/locale @@ -0,0 +1,4469 @@ +// -*- C++ -*- +//===-------------------------- locale ------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_LOCALE +#define _LIBCPP_LOCALE + +/* + locale synopsis + +namespace std +{ + +class locale +{ +public: + // types: + class facet; + class id; + + typedef int category; + static const category // values assigned here are for exposition only + none = 0x000, + collate = 0x010, + ctype = 0x020, + monetary = 0x040, + numeric = 0x080, + time = 0x100, + messages = 0x200, + all = collate | ctype | monetary | numeric | time | messages; + + // construct/copy/destroy: + locale() noexcept; + locale(const locale& other) noexcept; + explicit locale(const char* std_name); + explicit locale(const string& std_name); + locale(const locale& other, const char* std_name, category); + locale(const locale& other, const string& std_name, category); + template locale(const locale& other, Facet* f); + locale(const locale& other, const locale& one, category); + + ~locale(); // not virtual + + const locale& operator=(const locale& other) noexcept; + + template locale combine(const locale& other) const; + + // locale operations: + basic_string name() const; + bool operator==(const locale& other) const; + bool operator!=(const locale& other) const; + template + bool operator()(const basic_string& s1, + const basic_string& s2) const; + + // global locale objects: + static locale global(const locale&); + static const locale& classic(); +}; + +template const Facet& use_facet(const locale&); +template bool has_facet(const locale&) noexcept; + +// 22.3.3, convenience interfaces: +template bool isspace (charT c, const locale& loc); +template bool isprint (charT c, const locale& loc); +template bool iscntrl (charT c, const locale& loc); +template bool isupper (charT c, const locale& loc); +template bool islower (charT c, const locale& loc); +template bool isalpha (charT c, const locale& loc); +template bool isdigit (charT c, const locale& loc); +template bool ispunct (charT c, const locale& loc); +template bool isxdigit(charT c, const locale& loc); +template bool isalnum (charT c, const locale& loc); +template bool isgraph (charT c, const locale& loc); +template charT toupper(charT c, const locale& loc); +template charT tolower(charT c, const locale& loc); + +template, + class Byte_alloc = allocator> +class wstring_convert +{ +public: + typedef basic_string, Byte_alloc> byte_string; + typedef basic_string, Wide_alloc> wide_string; + typedef typename Codecvt::state_type state_type; + typedef typename wide_string::traits_type::int_type int_type; + + explicit wstring_convert(Codecvt* pcvt = new Codecvt); // explicit in C++14 + wstring_convert(Codecvt* pcvt, state_type state); + explicit wstring_convert(const byte_string& byte_err, // explicit in C++14 + const wide_string& wide_err = wide_string()); + wstring_convert(const wstring_convert&) = delete; // C++14 + wstring_convert & operator=(const wstring_convert &) = delete; // C++14 + ~wstring_convert(); + + wide_string from_bytes(char byte); + wide_string from_bytes(const char* ptr); + wide_string from_bytes(const byte_string& str); + wide_string from_bytes(const char* first, const char* last); + + byte_string to_bytes(Elem wchar); + byte_string to_bytes(const Elem* wptr); + byte_string to_bytes(const wide_string& wstr); + byte_string to_bytes(const Elem* first, const Elem* last); + + size_t converted() const; // noexcept in C++14 + state_type state() const; +}; + +template > +class wbuffer_convert + : public basic_streambuf +{ +public: + typedef typename Tr::state_type state_type; + + explicit wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt, + state_type state = state_type()); // explicit in C++14 + wbuffer_convert(const wbuffer_convert&) = delete; // C++14 + wbuffer_convert & operator=(const wbuffer_convert &) = delete; // C++14 + ~wbuffer_convert(); // C++14 + + streambuf* rdbuf() const; + streambuf* rdbuf(streambuf* bytebuf); + + state_type state() const; +}; + +// 22.4.1 and 22.4.1.3, ctype: +class ctype_base; +template class ctype; +template <> class ctype; // specialization +template class ctype_byname; +template <> class ctype_byname; // specialization + +class codecvt_base; +template class codecvt; +template class codecvt_byname; + +// 22.4.2 and 22.4.3, numeric: +template class num_get; +template class num_put; +template class numpunct; +template class numpunct_byname; + +// 22.4.4, col lation: +template class collate; +template class collate_byname; + +// 22.4.5, date and time: +class time_base; +template class time_get; +template class time_get_byname; +template class time_put; +template class time_put_byname; + +// 22.4.6, money: +class money_base; +template class money_get; +template class money_put; +template class moneypunct; +template class moneypunct_byname; + +// 22.4.7, message retrieval: +class messages_base; +template class messages; +template class messages_byname; + +} // std + +*/ + +#include <__config> +#include <__locale> +#include +#include +#include +#include +#include +#include +#ifndef __APPLE__ +#include +#endif +#include +#include +#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) +#include +#elif defined(_NEWLIB_VERSION) +// FIXME: replace all the uses of _NEWLIB_VERSION with __NEWLIB__ preceded by an +// include of once https://sourceware.org/ml/newlib-cvs/2014-q3/msg00038.html +// has had a chance to bake for a bit +#include +#endif +#ifdef _LIBCPP_HAS_CATOPEN +#include +#endif + +#ifdef __APPLE__ +#include +#endif + +#include <__undef_min_max> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if defined(__APPLE__) || defined(__FreeBSD__) +# define _LIBCPP_GET_C_LOCALE 0 +#elif defined(__CloudABI__) || defined(__NetBSD__) +# define _LIBCPP_GET_C_LOCALE LC_C_LOCALE +#else +# define _LIBCPP_GET_C_LOCALE __cloc() + // Get the C locale object + _LIBCPP_FUNC_VIS locale_t __cloc(); +#define __cloc_defined +#endif + +typedef _VSTD::remove_pointer::type __locale_struct; +typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr; +#ifndef _LIBCPP_LOCALE__L_EXTENSIONS +typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii; +#endif + +// OSX has nice foo_l() functions that let you turn off use of the global +// locale. Linux, not so much. The following functions avoid the locale when +// that's possible and otherwise do the wrong thing. FIXME. +#if defined(__linux__) || defined(__EMSCRIPTEN__) || defined(_AIX) || \ + defined(_NEWLIB_VERSION) || defined(__GLIBC__) + +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS +decltype(MB_CUR_MAX_L(_VSTD::declval())) +inline _LIBCPP_INLINE_VISIBILITY +__mb_cur_max_l(locale_t __l) +{ + return MB_CUR_MAX_L(__l); +} +#else // _LIBCPP_LOCALE__L_EXTENSIONS +inline _LIBCPP_ALWAYS_INLINE +decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l) +{ + __locale_raii __current(uselocale(__l), uselocale); + return MB_CUR_MAX; +} +#endif // _LIBCPP_LOCALE__L_EXTENSIONS + +inline _LIBCPP_ALWAYS_INLINE +wint_t __btowc_l(int __c, locale_t __l) +{ +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + return btowc_l(__c, __l); +#else + __locale_raii __current(uselocale(__l), uselocale); + return btowc(__c); +#endif +} + +inline _LIBCPP_ALWAYS_INLINE +int __wctob_l(wint_t __c, locale_t __l) +{ +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + return wctob_l(__c, __l); +#else + __locale_raii __current(uselocale(__l), uselocale); + return wctob(__c); +#endif +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, + size_t __len, mbstate_t *__ps, locale_t __l) +{ +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l); +#else + __locale_raii __current(uselocale(__l), uselocale); + return wcsnrtombs(__dest, __src, __nwc, __len, __ps); +#endif +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) +{ +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + return wcrtomb_l(__s, __wc, __ps, __l); +#else + __locale_raii __current(uselocale(__l), uselocale); + return wcrtomb(__s, __wc, __ps); +#endif +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, + size_t __len, mbstate_t *__ps, locale_t __l) +{ +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l); +#else + __locale_raii __current(uselocale(__l), uselocale); + return mbsnrtowcs(__dest, __src, __nms, __len, __ps); +#endif +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, + mbstate_t *__ps, locale_t __l) +{ +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + return mbrtowc_l(__pwc, __s, __n, __ps, __l); +#else + __locale_raii __current(uselocale(__l), uselocale); + return mbrtowc(__pwc, __s, __n, __ps); +#endif +} + +inline _LIBCPP_ALWAYS_INLINE +int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) +{ +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + return mbtowc_l(__pwc, __pmb, __max, __l); +#else + __locale_raii __current(uselocale(__l), uselocale); + return mbtowc(__pwc, __pmb, __max); +#endif +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) +{ +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + return mbrlen_l(__s, __n, __ps, __l); +#else + __locale_raii __current(uselocale(__l), uselocale); + return mbrlen(__s, __n, __ps); +#endif +} + +inline _LIBCPP_ALWAYS_INLINE +lconv *__localeconv_l(locale_t __l) +{ +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + return localeconv_l(__l); +#else + __locale_raii __current(uselocale(__l), uselocale); + return localeconv(); +#endif +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, + mbstate_t *__ps, locale_t __l) +{ +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + return mbsrtowcs_l(__dest, __src, __len, __ps, __l); +#else + __locale_raii __current(uselocale(__l), uselocale); + return mbsrtowcs(__dest, __src, __len, __ps); +#endif +} + +inline +int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + int __res = vsnprintf_l(__s, __n, __l, __format, __va); +#else + __locale_raii __current(uselocale(__l), uselocale); + int __res = vsnprintf(__s, __n, __format, __va); +#endif + va_end(__va); + return __res; +} + +inline +int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + int __res = vasprintf_l(__s, __l, __format, __va); +#else + __locale_raii __current(uselocale(__l), uselocale); + int __res = vasprintf(__s, __format, __va); +#endif + va_end(__va); + return __res; +} + +inline +int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + int __res = vsscanf_l(__s, __l, __format, __va); +#else + __locale_raii __current(uselocale(__l), uselocale); + int __res = vsscanf(__s, __format, __va); +#endif + va_end(__va); + return __res; +} + +#endif // __linux__ + +// __scan_keyword +// Scans [__b, __e) until a match is found in the basic_strings range +// [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke). +// __b will be incremented (visibly), consuming CharT until a match is found +// or proved to not exist. A keyword may be "", in which will match anything. +// If one keyword is a prefix of another, and the next CharT in the input +// might match another keyword, the algorithm will attempt to find the longest +// matching keyword. If the longer matching keyword ends up not matching, then +// no keyword match is found. If no keyword match is found, __ke is returned +// and failbit is set in __err. +// Else an iterator pointing to the matching keyword is found. If more than +// one keyword matches, an iterator to the first matching keyword is returned. +// If on exit __b == __e, eofbit is set in __err. If __case_sensitive is false, +// __ct is used to force to lower case before comparing characters. +// Examples: +// Keywords: "a", "abb" +// If the input is "a", the first keyword matches and eofbit is set. +// If the input is "abc", no match is found and "ab" are consumed. +template +_LIBCPP_HIDDEN +_ForwardIterator +__scan_keyword(_InputIterator& __b, _InputIterator __e, + _ForwardIterator __kb, _ForwardIterator __ke, + const _Ctype& __ct, ios_base::iostate& __err, + bool __case_sensitive = true) +{ + typedef typename iterator_traits<_InputIterator>::value_type _CharT; + size_t __nkw = static_cast(_VSTD::distance(__kb, __ke)); + const unsigned char __doesnt_match = '\0'; + const unsigned char __might_match = '\1'; + const unsigned char __does_match = '\2'; + unsigned char __statbuf[100]; + unsigned char* __status = __statbuf; + unique_ptr __stat_hold(0, free); + if (__nkw > sizeof(__statbuf)) + { + __status = (unsigned char*)malloc(__nkw); + if (__status == 0) + __throw_bad_alloc(); + __stat_hold.reset(__status); + } + size_t __n_might_match = __nkw; // At this point, any keyword might match + size_t __n_does_match = 0; // but none of them definitely do + // Initialize all statuses to __might_match, except for "" keywords are __does_match + unsigned char* __st = __status; + for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st) + { + if (!__ky->empty()) + *__st = __might_match; + else + { + *__st = __does_match; + --__n_might_match; + ++__n_does_match; + } + } + // While there might be a match, test keywords against the next CharT + for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx) + { + // Peek at the next CharT but don't consume it + _CharT __c = *__b; + if (!__case_sensitive) + __c = __ct.toupper(__c); + bool __consume = false; + // For each keyword which might match, see if the __indx character is __c + // If a match if found, consume __c + // If a match is found, and that is the last character in the keyword, + // then that keyword matches. + // If the keyword doesn't match this character, then change the keyword + // to doesn't match + __st = __status; + for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st) + { + if (*__st == __might_match) + { + _CharT __kc = (*__ky)[__indx]; + if (!__case_sensitive) + __kc = __ct.toupper(__kc); + if (__c == __kc) + { + __consume = true; + if (__ky->size() == __indx+1) + { + *__st = __does_match; + --__n_might_match; + ++__n_does_match; + } + } + else + { + *__st = __doesnt_match; + --__n_might_match; + } + } + } + // consume if we matched a character + if (__consume) + { + ++__b; + // If we consumed a character and there might be a matched keyword that + // was marked matched on a previous iteration, then such keywords + // which are now marked as not matching. + if (__n_might_match + __n_does_match > 1) + { + __st = __status; + for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st) + { + if (*__st == __does_match && __ky->size() != __indx+1) + { + *__st = __doesnt_match; + --__n_does_match; + } + } + } + } + } + // We've exited the loop because we hit eof and/or we have no more "might matches". + if (__b == __e) + __err |= ios_base::eofbit; + // Return the first matching result + for (__st = __status; __kb != __ke; ++__kb, (void) ++__st) + if (*__st == __does_match) + break; + if (__kb == __ke) + __err |= ios_base::failbit; + return __kb; +} + +struct _LIBCPP_TYPE_VIS __num_get_base +{ + static const int __num_get_buf_sz = 40; + + static int __get_base(ios_base&); + static const char __src[33]; +}; + +_LIBCPP_FUNC_VIS +void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, + ios_base::iostate& __err); + +template +struct __num_get + : protected __num_get_base +{ + static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep); + static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, + _CharT& __thousands_sep); + static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, + unsigned& __dc, _CharT __thousands_sep, const string& __grouping, + unsigned* __g, unsigned*& __g_end, _CharT* __atoms); + static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, + char* __a, char*& __a_end, + _CharT __decimal_point, _CharT __thousands_sep, + const string& __grouping, unsigned* __g, + unsigned*& __g_end, unsigned& __dc, _CharT* __atoms); +}; + +template +string +__num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep) +{ + locale __loc = __iob.getloc(); + use_facet >(__loc).widen(__src, __src + 26, __atoms); + const numpunct<_CharT>& __np = use_facet >(__loc); + __thousands_sep = __np.thousands_sep(); + return __np.grouping(); +} + +template +string +__num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, + _CharT& __thousands_sep) +{ + locale __loc = __iob.getloc(); + use_facet >(__loc).widen(__src, __src + 32, __atoms); + const numpunct<_CharT>& __np = use_facet >(__loc); + __decimal_point = __np.decimal_point(); + __thousands_sep = __np.thousands_sep(); + return __np.grouping(); +} + +template +int +__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, + unsigned& __dc, _CharT __thousands_sep, const string& __grouping, + unsigned* __g, unsigned*& __g_end, _CharT* __atoms) +{ + if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) + { + *__a_end++ = __ct == __atoms[24] ? '+' : '-'; + __dc = 0; + return 0; + } + if (__grouping.size() != 0 && __ct == __thousands_sep) + { + if (__g_end-__g < __num_get_buf_sz) + { + *__g_end++ = __dc; + __dc = 0; + } + return 0; + } + ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms; + if (__f >= 24) + return -1; + switch (__base) + { + case 8: + case 10: + if (__f >= __base) + return -1; + break; + case 16: + if (__f < 22) + break; + if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') + { + __dc = 0; + *__a_end++ = __src[__f]; + return 0; + } + return -1; + } + *__a_end++ = __src[__f]; + ++__dc; + return 0; +} + +template +int +__num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end, + _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping, + unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms) +{ + if (__ct == __decimal_point) + { + if (!__in_units) + return -1; + __in_units = false; + *__a_end++ = '.'; + if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz) + *__g_end++ = __dc; + return 0; + } + if (__ct == __thousands_sep && __grouping.size() != 0) + { + if (!__in_units) + return -1; + if (__g_end-__g < __num_get_buf_sz) + { + *__g_end++ = __dc; + __dc = 0; + } + return 0; + } + ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms; + if (__f >= 32) + return -1; + char __x = __src[__f]; + if (__x == '-' || __x == '+') + { + if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F)) + { + *__a_end++ = __x; + return 0; + } + return -1; + } + if (__x == 'x' || __x == 'X') + __exp = 'P'; + else if ((__x & 0x5F) == __exp) + { + __exp |= 0x80; + if (__in_units) + { + __in_units = false; + if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz) + *__g_end++ = __dc; + } + } + *__a_end++ = __x; + if (__f >= 22) + return 0; + ++__dc; + return 0; +} + +_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get) +_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get) + +template > +class _LIBCPP_TYPE_VIS_ONLY num_get + : public locale::facet, + private __num_get<_CharT> +{ +public: + typedef _CharT char_type; + typedef _InputIterator iter_type; + + _LIBCPP_ALWAYS_INLINE + explicit num_get(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_ALWAYS_INLINE + iter_type get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, bool& __v) const + { + return do_get(__b, __e, __iob, __err, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, long& __v) const + { + return do_get(__b, __e, __iob, __err, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, long long& __v) const + { + return do_get(__b, __e, __iob, __err, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, unsigned short& __v) const + { + return do_get(__b, __e, __iob, __err, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, unsigned int& __v) const + { + return do_get(__b, __e, __iob, __err, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, unsigned long& __v) const + { + return do_get(__b, __e, __iob, __err, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, unsigned long long& __v) const + { + return do_get(__b, __e, __iob, __err, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, float& __v) const + { + return do_get(__b, __e, __iob, __err, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, double& __v) const + { + return do_get(__b, __e, __iob, __err, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, long double& __v) const + { + return do_get(__b, __e, __iob, __err, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, void*& __v) const + { + return do_get(__b, __e, __iob, __err, __v); + } + + static locale::id id; + +protected: + _LIBCPP_ALWAYS_INLINE + ~num_get() {} + + template + iter_type __do_get_floating_point + (iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, _Fp& __v) const; + + template + iter_type __do_get_signed + (iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, _Signed& __v) const; + + template + iter_type __do_get_unsigned + (iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, _Unsigned& __v) const; + + + virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, bool& __v) const; + + virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, long& __v) const + { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); } + + virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, long long& __v) const + { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); } + + virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, unsigned short& __v) const + { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); } + + virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, unsigned int& __v) const + { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); } + + virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, unsigned long& __v) const + { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); } + + virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, unsigned long long& __v) const + { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); } + + virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, float& __v) const + { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); } + + virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, double& __v) const + { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); } + + virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, long double& __v) const + { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); } + + virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, void*& __v) const; +}; + +template +locale::id +num_get<_CharT, _InputIterator>::id; + +template +_Tp +__num_get_signed_integral(const char* __a, const char* __a_end, + ios_base::iostate& __err, int __base) +{ + if (__a != __a_end) + { + typename remove_reference::type __save_errno = errno; + errno = 0; + char *__p2; + long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); + typename remove_reference::type __current_errno = errno; + if (__current_errno == 0) + errno = __save_errno; + if (__p2 != __a_end) + { + __err = ios_base::failbit; + return 0; + } + else if (__current_errno == ERANGE || + __ll < numeric_limits<_Tp>::min() || + numeric_limits<_Tp>::max() < __ll) + { + __err = ios_base::failbit; + if (__ll > 0) + return numeric_limits<_Tp>::max(); + else + return numeric_limits<_Tp>::min(); + } + return static_cast<_Tp>(__ll); + } + __err = ios_base::failbit; + return 0; +} + +template +_Tp +__num_get_unsigned_integral(const char* __a, const char* __a_end, + ios_base::iostate& __err, int __base) +{ + if (__a != __a_end) + { + if (*__a == '-') + { + __err = ios_base::failbit; + return 0; + } + typename remove_reference::type __save_errno = errno; + errno = 0; + char *__p2; + unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); + typename remove_reference::type __current_errno = errno; + if (__current_errno == 0) + errno = __save_errno; + if (__p2 != __a_end) + { + __err = ios_base::failbit; + return 0; + } + else if (__current_errno == ERANGE || + numeric_limits<_Tp>::max() < __ll) + { + __err = ios_base::failbit; + return numeric_limits<_Tp>::max(); + } + return static_cast<_Tp>(__ll); + } + __err = ios_base::failbit; + return 0; +} + +template +_Tp +__num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) +{ + if (__a != __a_end) + { + typename remove_reference::type __save_errno = errno; + errno = 0; + char *__p2; + long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE); + typename remove_reference::type __current_errno = errno; + if (__current_errno == 0) + errno = __save_errno; + if (__p2 != __a_end) + { + __err = ios_base::failbit; + return 0; + } + else if (__current_errno == ERANGE) + __err = ios_base::failbit; + return static_cast<_Tp>(__ld); + } + __err = ios_base::failbit; + return 0; +} + +template +_InputIterator +num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, + ios_base& __iob, + ios_base::iostate& __err, + bool& __v) const +{ + if ((__iob.flags() & ios_base::boolalpha) == 0) + { + long __lv = -1; + __b = do_get(__b, __e, __iob, __err, __lv); + switch (__lv) + { + case 0: + __v = false; + break; + case 1: + __v = true; + break; + default: + __v = true; + __err = ios_base::failbit; + break; + } + return __b; + } + const ctype<_CharT>& __ct = use_facet >(__iob.getloc()); + const numpunct<_CharT>& __np = use_facet >(__iob.getloc()); + typedef typename numpunct<_CharT>::string_type string_type; + const string_type __names[2] = {__np.truename(), __np.falsename()}; + const string_type* __i = __scan_keyword(__b, __e, __names, __names+2, + __ct, __err); + __v = __i == __names; + return __b; +} + +// signed + +template +template +_InputIterator +num_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e, + ios_base& __iob, + ios_base::iostate& __err, + _Signed& __v) const +{ + // Stage 1 + int __base = this->__get_base(__iob); + // Stage 2 + char_type __atoms[26]; + char_type __thousands_sep; + string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); + string __buf; + __buf.resize(__buf.capacity()); + char* __a = &__buf[0]; + char* __a_end = __a; + unsigned __g[__num_get_base::__num_get_buf_sz]; + unsigned* __g_end = __g; + unsigned __dc = 0; + for (; __b != __e; ++__b) + { + if (__a_end == __a + __buf.size()) + { + size_t __tmp = __buf.size(); + __buf.resize(2*__buf.size()); + __buf.resize(__buf.capacity()); + __a = &__buf[0]; + __a_end = __a + __tmp; + } + if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, + __thousands_sep, __grouping, __g, __g_end, + __atoms)) + break; + } + if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) + *__g_end++ = __dc; + // Stage 3 + __v = __num_get_signed_integral<_Signed>(__a, __a_end, __err, __base); + // Digit grouping checked + __check_grouping(__grouping, __g, __g_end, __err); + // EOF checked + if (__b == __e) + __err |= ios_base::eofbit; + return __b; +} + +// unsigned + +template +template +_InputIterator +num_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e, + ios_base& __iob, + ios_base::iostate& __err, + _Unsigned& __v) const +{ + // Stage 1 + int __base = this->__get_base(__iob); + // Stage 2 + char_type __atoms[26]; + char_type __thousands_sep; + string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); + string __buf; + __buf.resize(__buf.capacity()); + char* __a = &__buf[0]; + char* __a_end = __a; + unsigned __g[__num_get_base::__num_get_buf_sz]; + unsigned* __g_end = __g; + unsigned __dc = 0; + for (; __b != __e; ++__b) + { + if (__a_end == __a + __buf.size()) + { + size_t __tmp = __buf.size(); + __buf.resize(2*__buf.size()); + __buf.resize(__buf.capacity()); + __a = &__buf[0]; + __a_end = __a + __tmp; + } + if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, + __thousands_sep, __grouping, __g, __g_end, + __atoms)) + break; + } + if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) + *__g_end++ = __dc; + // Stage 3 + __v = __num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base); + // Digit grouping checked + __check_grouping(__grouping, __g, __g_end, __err); + // EOF checked + if (__b == __e) + __err |= ios_base::eofbit; + return __b; +} + +// floating point + +template +template +_InputIterator +num_get<_CharT, _InputIterator>::__do_get_floating_point(iter_type __b, iter_type __e, + ios_base& __iob, + ios_base::iostate& __err, + _Fp& __v) const +{ + // Stage 1, nothing to do + // Stage 2 + char_type __atoms[32]; + char_type __decimal_point; + char_type __thousands_sep; + string __grouping = this->__stage2_float_prep(__iob, __atoms, + __decimal_point, + __thousands_sep); + string __buf; + __buf.resize(__buf.capacity()); + char* __a = &__buf[0]; + char* __a_end = __a; + unsigned __g[__num_get_base::__num_get_buf_sz]; + unsigned* __g_end = __g; + unsigned __dc = 0; + bool __in_units = true; + char __exp = 'E'; + for (; __b != __e; ++__b) + { + if (__a_end == __a + __buf.size()) + { + size_t __tmp = __buf.size(); + __buf.resize(2*__buf.size()); + __buf.resize(__buf.capacity()); + __a = &__buf[0]; + __a_end = __a + __tmp; + } + if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end, + __decimal_point, __thousands_sep, + __grouping, __g, __g_end, + __dc, __atoms)) + break; + } + if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz) + *__g_end++ = __dc; + // Stage 3 + __v = __num_get_float<_Fp>(__a, __a_end, __err); + // Digit grouping checked + __check_grouping(__grouping, __g, __g_end, __err); + // EOF checked + if (__b == __e) + __err |= ios_base::eofbit; + return __b; +} + +template +_InputIterator +num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, + ios_base& __iob, + ios_base::iostate& __err, + void*& __v) const +{ + // Stage 1 + int __base = 16; + // Stage 2 + char_type __atoms[26]; + char_type __thousands_sep = 0; + string __grouping; + use_facet >(__iob.getloc()).widen(__num_get_base::__src, + __num_get_base::__src + 26, __atoms); + string __buf; + __buf.resize(__buf.capacity()); + char* __a = &__buf[0]; + char* __a_end = __a; + unsigned __g[__num_get_base::__num_get_buf_sz]; + unsigned* __g_end = __g; + unsigned __dc = 0; + for (; __b != __e; ++__b) + { + if (__a_end == __a + __buf.size()) + { + size_t __tmp = __buf.size(); + __buf.resize(2*__buf.size()); + __buf.resize(__buf.capacity()); + __a = &__buf[0]; + __a_end = __a + __tmp; + } + if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, + __thousands_sep, __grouping, + __g, __g_end, __atoms)) + break; + } + // Stage 3 + __buf.resize(__a_end - __a); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + if (sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) +#else + if (__sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) +#endif + __err = ios_base::failbit; + // EOF checked + if (__b == __e) + __err |= ios_base::eofbit; + return __b; +} + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get) + +struct _LIBCPP_TYPE_VIS __num_put_base +{ +protected: + static void __format_int(char* __fmt, const char* __len, bool __signd, + ios_base::fmtflags __flags); + static bool __format_float(char* __fmt, const char* __len, + ios_base::fmtflags __flags); + static char* __identify_padding(char* __nb, char* __ne, + const ios_base& __iob); +}; + +template +struct __num_put + : protected __num_put_base +{ + static void __widen_and_group_int(char* __nb, char* __np, char* __ne, + _CharT* __ob, _CharT*& __op, _CharT*& __oe, + const locale& __loc); + static void __widen_and_group_float(char* __nb, char* __np, char* __ne, + _CharT* __ob, _CharT*& __op, _CharT*& __oe, + const locale& __loc); +}; + +template +void +__num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne, + _CharT* __ob, _CharT*& __op, _CharT*& __oe, + const locale& __loc) +{ + const ctype<_CharT>& __ct = use_facet > (__loc); + const numpunct<_CharT>& __npt = use_facet >(__loc); + string __grouping = __npt.grouping(); + if (__grouping.empty()) + { + __ct.widen(__nb, __ne, __ob); + __oe = __ob + (__ne - __nb); + } + else + { + __oe = __ob; + char* __nf = __nb; + if (*__nf == '-' || *__nf == '+') + *__oe++ = __ct.widen(*__nf++); + if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' || + __nf[1] == 'X')) + { + *__oe++ = __ct.widen(*__nf++); + *__oe++ = __ct.widen(*__nf++); + } + reverse(__nf, __ne); + _CharT __thousands_sep = __npt.thousands_sep(); + unsigned __dc = 0; + unsigned __dg = 0; + for (char* __p = __nf; __p < __ne; ++__p) + { + if (static_cast(__grouping[__dg]) > 0 && + __dc == static_cast(__grouping[__dg])) + { + *__oe++ = __thousands_sep; + __dc = 0; + if (__dg < __grouping.size()-1) + ++__dg; + } + *__oe++ = __ct.widen(*__p); + ++__dc; + } + reverse(__ob + (__nf - __nb), __oe); + } + if (__np == __ne) + __op = __oe; + else + __op = __ob + (__np - __nb); +} + +template +void +__num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne, + _CharT* __ob, _CharT*& __op, _CharT*& __oe, + const locale& __loc) +{ + const ctype<_CharT>& __ct = use_facet > (__loc); + const numpunct<_CharT>& __npt = use_facet >(__loc); + string __grouping = __npt.grouping(); + __oe = __ob; + char* __nf = __nb; + if (*__nf == '-' || *__nf == '+') + *__oe++ = __ct.widen(*__nf++); + char* __ns; + if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' || + __nf[1] == 'X')) + { + *__oe++ = __ct.widen(*__nf++); + *__oe++ = __ct.widen(*__nf++); + for (__ns = __nf; __ns < __ne; ++__ns) + if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) + break; + } + else + { + for (__ns = __nf; __ns < __ne; ++__ns) + if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) + break; + } + if (__grouping.empty()) + { + __ct.widen(__nf, __ns, __oe); + __oe += __ns - __nf; + } + else + { + reverse(__nf, __ns); + _CharT __thousands_sep = __npt.thousands_sep(); + unsigned __dc = 0; + unsigned __dg = 0; + for (char* __p = __nf; __p < __ns; ++__p) + { + if (__grouping[__dg] > 0 && __dc == static_cast(__grouping[__dg])) + { + *__oe++ = __thousands_sep; + __dc = 0; + if (__dg < __grouping.size()-1) + ++__dg; + } + *__oe++ = __ct.widen(*__p); + ++__dc; + } + reverse(__ob + (__nf - __nb), __oe); + } + for (__nf = __ns; __nf < __ne; ++__nf) + { + if (*__nf == '.') + { + *__oe++ = __npt.decimal_point(); + ++__nf; + break; + } + else + *__oe++ = __ct.widen(*__nf); + } + __ct.widen(__nf, __ne, __oe); + __oe += __ne - __nf; + if (__np == __ne) + __op = __oe; + else + __op = __ob + (__np - __nb); +} + +_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put) +_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put) + +template > +class _LIBCPP_TYPE_VIS_ONLY num_put + : public locale::facet, + private __num_put<_CharT> +{ +public: + typedef _CharT char_type; + typedef _OutputIterator iter_type; + + _LIBCPP_ALWAYS_INLINE + explicit num_put(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_ALWAYS_INLINE + iter_type put(iter_type __s, ios_base& __iob, char_type __fl, + bool __v) const + { + return do_put(__s, __iob, __fl, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type put(iter_type __s, ios_base& __iob, char_type __fl, + long __v) const + { + return do_put(__s, __iob, __fl, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type put(iter_type __s, ios_base& __iob, char_type __fl, + long long __v) const + { + return do_put(__s, __iob, __fl, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type put(iter_type __s, ios_base& __iob, char_type __fl, + unsigned long __v) const + { + return do_put(__s, __iob, __fl, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type put(iter_type __s, ios_base& __iob, char_type __fl, + unsigned long long __v) const + { + return do_put(__s, __iob, __fl, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type put(iter_type __s, ios_base& __iob, char_type __fl, + double __v) const + { + return do_put(__s, __iob, __fl, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type put(iter_type __s, ios_base& __iob, char_type __fl, + long double __v) const + { + return do_put(__s, __iob, __fl, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type put(iter_type __s, ios_base& __iob, char_type __fl, + const void* __v) const + { + return do_put(__s, __iob, __fl, __v); + } + + static locale::id id; + +protected: + _LIBCPP_ALWAYS_INLINE + ~num_put() {} + + virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, + bool __v) const; + virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, + long __v) const; + virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, + long long __v) const; + virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, + unsigned long) const; + virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, + unsigned long long) const; + virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, + double __v) const; + virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, + long double __v) const; + virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, + const void* __v) const; +}; + +template +locale::id +num_put<_CharT, _OutputIterator>::id; + +template +_LIBCPP_HIDDEN +_OutputIterator +__pad_and_output(_OutputIterator __s, + const _CharT* __ob, const _CharT* __op, const _CharT* __oe, + ios_base& __iob, _CharT __fl) +{ + streamsize __sz = __oe - __ob; + streamsize __ns = __iob.width(); + if (__ns > __sz) + __ns -= __sz; + else + __ns = 0; + for (;__ob < __op; ++__ob, ++__s) + *__s = *__ob; + for (; __ns; --__ns, ++__s) + *__s = __fl; + for (; __ob < __oe; ++__ob, ++__s) + *__s = *__ob; + __iob.width(0); + return __s; +} + +#if !defined(__APPLE__) || \ + (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \ + (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0) + +template +_LIBCPP_HIDDEN +ostreambuf_iterator<_CharT, _Traits> +__pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s, + const _CharT* __ob, const _CharT* __op, const _CharT* __oe, + ios_base& __iob, _CharT __fl) +{ + if (__s.__sbuf_ == nullptr) + return __s; + streamsize __sz = __oe - __ob; + streamsize __ns = __iob.width(); + if (__ns > __sz) + __ns -= __sz; + else + __ns = 0; + streamsize __np = __op - __ob; + if (__np > 0) + { + if (__s.__sbuf_->sputn(__ob, __np) != __np) + { + __s.__sbuf_ = nullptr; + return __s; + } + } + if (__ns > 0) + { + basic_string<_CharT, _Traits> __sp(__ns, __fl); + if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns) + { + __s.__sbuf_ = nullptr; + return __s; + } + } + __np = __oe - __op; + if (__np > 0) + { + if (__s.__sbuf_->sputn(__op, __np) != __np) + { + __s.__sbuf_ = nullptr; + return __s; + } + } + __iob.width(0); + return __s; +} + +#endif + +template +_OutputIterator +num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + char_type __fl, bool __v) const +{ + if ((__iob.flags() & ios_base::boolalpha) == 0) + return do_put(__s, __iob, __fl, (unsigned long)__v); + const numpunct& __np = use_facet >(__iob.getloc()); + typedef typename numpunct::string_type string_type; +#if _LIBCPP_DEBUG_LEVEL >= 2 + string_type __tmp(__v ? __np.truename() : __np.falsename()); + string_type __nm = _VSTD::move(__tmp); +#else + string_type __nm = __v ? __np.truename() : __np.falsename(); +#endif + for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s) + *__s = *__i; + return __s; +} + +template +_OutputIterator +num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + char_type __fl, long __v) const +{ + // Stage 1 - Get number in narrow char + char __fmt[6] = {'%', 0}; + const char* __len = "l"; + this->__format_int(__fmt+1, __len, true, __iob.flags()); + const unsigned __nbuf = (numeric_limits::digits / 3) + + ((numeric_limits::digits % 3) != 0) + + 1; + char __nar[__nbuf]; +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); +#else + int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); +#endif + char* __ne = __nar + __nc; + char* __np = this->__identify_padding(__nar, __ne, __iob); + // Stage 2 - Widen __nar while adding thousands separators + char_type __o[2*(__nbuf-1) - 1]; + char_type* __op; // pad here + char_type* __oe; // end of output + this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); + // [__o, __oe) contains thousands_sep'd wide number + // Stage 3 & 4 + return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); +} + +template +_OutputIterator +num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + char_type __fl, long long __v) const +{ + // Stage 1 - Get number in narrow char + char __fmt[8] = {'%', 0}; + const char* __len = "ll"; + this->__format_int(__fmt+1, __len, true, __iob.flags()); + const unsigned __nbuf = (numeric_limits::digits / 3) + + ((numeric_limits::digits % 3) != 0) + + 2; + char __nar[__nbuf]; +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); +#else + int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); +#endif + char* __ne = __nar + __nc; + char* __np = this->__identify_padding(__nar, __ne, __iob); + // Stage 2 - Widen __nar while adding thousands separators + char_type __o[2*(__nbuf-1) - 1]; + char_type* __op; // pad here + char_type* __oe; // end of output + this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); + // [__o, __oe) contains thousands_sep'd wide number + // Stage 3 & 4 + return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); +} + +template +_OutputIterator +num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + char_type __fl, unsigned long __v) const +{ + // Stage 1 - Get number in narrow char + char __fmt[6] = {'%', 0}; + const char* __len = "l"; + this->__format_int(__fmt+1, __len, false, __iob.flags()); + const unsigned __nbuf = (numeric_limits::digits / 3) + + ((numeric_limits::digits % 3) != 0) + + 1; + char __nar[__nbuf]; +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); +#else + int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); +#endif + char* __ne = __nar + __nc; + char* __np = this->__identify_padding(__nar, __ne, __iob); + // Stage 2 - Widen __nar while adding thousands separators + char_type __o[2*(__nbuf-1) - 1]; + char_type* __op; // pad here + char_type* __oe; // end of output + this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); + // [__o, __oe) contains thousands_sep'd wide number + // Stage 3 & 4 + return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); +} + +template +_OutputIterator +num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + char_type __fl, unsigned long long __v) const +{ + // Stage 1 - Get number in narrow char + char __fmt[8] = {'%', 0}; + const char* __len = "ll"; + this->__format_int(__fmt+1, __len, false, __iob.flags()); + const unsigned __nbuf = (numeric_limits::digits / 3) + + ((numeric_limits::digits % 3) != 0) + + 1; + char __nar[__nbuf]; +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); +#else + int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); +#endif + char* __ne = __nar + __nc; + char* __np = this->__identify_padding(__nar, __ne, __iob); + // Stage 2 - Widen __nar while adding thousands separators + char_type __o[2*(__nbuf-1) - 1]; + char_type* __op; // pad here + char_type* __oe; // end of output + this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); + // [__o, __oe) contains thousands_sep'd wide number + // Stage 3 & 4 + return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); +} + +template +_OutputIterator +num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + char_type __fl, double __v) const +{ + // Stage 1 - Get number in narrow char + char __fmt[8] = {'%', 0}; + const char* __len = ""; + bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags()); + const unsigned __nbuf = 30; + char __nar[__nbuf]; + char* __nb = __nar; + int __nc; + if (__specify_precision) +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, + (int)__iob.precision(), __v); +#else + __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, + (int)__iob.precision(), __v); +#endif + else +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); +#else + __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); +#endif + unique_ptr __nbh(0, free); + if (__nc > static_cast(__nbuf-1)) + { + if (__specify_precision) +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); +#else + __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); +#endif + else +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); +#else + __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); +#endif + if (__nb == 0) + __throw_bad_alloc(); + __nbh.reset(__nb); + } + char* __ne = __nb + __nc; + char* __np = this->__identify_padding(__nb, __ne, __iob); + // Stage 2 - Widen __nar while adding thousands separators + char_type __o[2*(__nbuf-1) - 1]; + char_type* __ob = __o; + unique_ptr __obh(0, free); + if (__nb != __nar) + { + __ob = (char_type*)malloc(2*static_cast(__nc)*sizeof(char_type)); + if (__ob == 0) + __throw_bad_alloc(); + __obh.reset(__ob); + } + char_type* __op; // pad here + char_type* __oe; // end of output + this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc()); + // [__o, __oe) contains thousands_sep'd wide number + // Stage 3 & 4 + __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl); + return __s; +} + +template +_OutputIterator +num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + char_type __fl, long double __v) const +{ + // Stage 1 - Get number in narrow char + char __fmt[8] = {'%', 0}; + const char* __len = "L"; + bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags()); + const unsigned __nbuf = 30; + char __nar[__nbuf]; + char* __nb = __nar; + int __nc; + if (__specify_precision) +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, + (int)__iob.precision(), __v); +#else + __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, + (int)__iob.precision(), __v); +#endif + else +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); +#else + __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); +#endif + unique_ptr __nbh(0, free); + if (__nc > static_cast(__nbuf-1)) + { + if (__specify_precision) +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); +#else + __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); +#endif + else +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); +#else + __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); +#endif + if (__nb == 0) + __throw_bad_alloc(); + __nbh.reset(__nb); + } + char* __ne = __nb + __nc; + char* __np = this->__identify_padding(__nb, __ne, __iob); + // Stage 2 - Widen __nar while adding thousands separators + char_type __o[2*(__nbuf-1) - 1]; + char_type* __ob = __o; + unique_ptr __obh(0, free); + if (__nb != __nar) + { + __ob = (char_type*)malloc(2*static_cast(__nc)*sizeof(char_type)); + if (__ob == 0) + __throw_bad_alloc(); + __obh.reset(__ob); + } + char_type* __op; // pad here + char_type* __oe; // end of output + this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc()); + // [__o, __oe) contains thousands_sep'd wide number + // Stage 3 & 4 + __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl); + return __s; +} + +template +_OutputIterator +num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + char_type __fl, const void* __v) const +{ + // Stage 1 - Get pointer in narrow char + char __fmt[6] = "%p"; + const unsigned __nbuf = 20; + char __nar[__nbuf]; +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); +#else + int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); +#endif + char* __ne = __nar + __nc; + char* __np = this->__identify_padding(__nar, __ne, __iob); + // Stage 2 - Widen __nar + char_type __o[2*(__nbuf-1) - 1]; + char_type* __op; // pad here + char_type* __oe; // end of output + const ctype& __ct = use_facet >(__iob.getloc()); + __ct.widen(__nar, __ne, __o); + __oe = __o + (__ne - __nar); + if (__np == __ne) + __op = __oe; + else + __op = __o + (__np - __nar); + // [__o, __oe) contains wide number + // Stage 3 & 4 + return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); +} + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put) + +template +_LIBCPP_HIDDEN +int +__get_up_to_n_digits(_InputIterator& __b, _InputIterator __e, + ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n) +{ + // Precondition: __n >= 1 + if (__b == __e) + { + __err |= ios_base::eofbit | ios_base::failbit; + return 0; + } + // get first digit + _CharT __c = *__b; + if (!__ct.is(ctype_base::digit, __c)) + { + __err |= ios_base::failbit; + return 0; + } + int __r = __ct.narrow(__c, 0) - '0'; + for (++__b, (void) --__n; __b != __e && __n > 0; ++__b, (void) --__n) + { + // get next digit + __c = *__b; + if (!__ct.is(ctype_base::digit, __c)) + return __r; + __r = __r * 10 + __ct.narrow(__c, 0) - '0'; + } + if (__b == __e) + __err |= ios_base::eofbit; + return __r; +} + +class _LIBCPP_TYPE_VIS time_base +{ +public: + enum dateorder {no_order, dmy, mdy, ymd, ydm}; +}; + +template +class _LIBCPP_TYPE_VIS_ONLY __time_get_c_storage +{ +protected: + typedef basic_string<_CharT> string_type; + + virtual const string_type* __weeks() const; + virtual const string_type* __months() const; + virtual const string_type* __am_pm() const; + virtual const string_type& __c() const; + virtual const string_type& __r() const; + virtual const string_type& __x() const; + virtual const string_type& __X() const; + + _LIBCPP_ALWAYS_INLINE + ~__time_get_c_storage() {} +}; + +template > +class _LIBCPP_TYPE_VIS_ONLY time_get + : public locale::facet, + public time_base, + private __time_get_c_storage<_CharT> +{ +public: + typedef _CharT char_type; + typedef _InputIterator iter_type; + typedef time_base::dateorder dateorder; + typedef basic_string string_type; + + _LIBCPP_ALWAYS_INLINE + explicit time_get(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_ALWAYS_INLINE + dateorder date_order() const + { + return this->do_date_order(); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, tm* __tm) const + { + return do_get_time(__b, __e, __iob, __err, __tm); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, tm* __tm) const + { + return do_get_date(__b, __e, __iob, __err, __tm); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, tm* __tm) const + { + return do_get_weekday(__b, __e, __iob, __err, __tm); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, tm* __tm) const + { + return do_get_monthname(__b, __e, __iob, __err, __tm); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, tm* __tm) const + { + return do_get_year(__b, __e, __iob, __err, __tm); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, tm *__tm, + char __fmt, char __mod = 0) const + { + return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod); + } + + iter_type get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, tm* __tm, + const char_type* __fmtb, const char_type* __fmte) const; + + static locale::id id; + +protected: + _LIBCPP_ALWAYS_INLINE + ~time_get() {} + + virtual dateorder do_date_order() const; + virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, tm* __tm) const; + virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, tm* __tm) const; + virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, tm* __tm) const; + virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, tm* __tm) const; + virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, tm* __tm) const; + virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, + ios_base::iostate& __err, tm* __tm, + char __fmt, char __mod) const; +private: + void __get_white_space(iter_type& __b, iter_type __e, + ios_base::iostate& __err, const ctype& __ct) const; + void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err, + const ctype& __ct) const; + + void __get_weekdayname(int& __m, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const; + void __get_monthname(int& __m, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const; + void __get_day(int& __d, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const; + void __get_month(int& __m, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const; + void __get_year(int& __y, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const; + void __get_year4(int& __y, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const; + void __get_hour(int& __d, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const; + void __get_12_hour(int& __h, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const; + void __get_am_pm(int& __h, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const; + void __get_minute(int& __m, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const; + void __get_second(int& __s, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const; + void __get_weekday(int& __w, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const; + void __get_day_year_num(int& __w, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const; +}; + +template +locale::id +time_get<_CharT, _InputIterator>::id; + +// time_get primitives + +template +void +time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + // Note: ignoring case comes from the POSIX strptime spec + const string_type* __wk = this->__weeks(); + ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk; + if (__i < 14) + __w = __i % 7; +} + +template +void +time_get<_CharT, _InputIterator>::__get_monthname(int& __m, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + // Note: ignoring case comes from the POSIX strptime spec + const string_type* __month = this->__months(); + ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month; + if (__i < 24) + __m = __i % 12; +} + +template +void +time_get<_CharT, _InputIterator>::__get_day(int& __d, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); + if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31) + __d = __t; + else + __err |= ios_base::failbit; +} + +template +void +time_get<_CharT, _InputIterator>::__get_month(int& __m, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1; + if (!(__err & ios_base::failbit) && __t <= 11) + __m = __t; + else + __err |= ios_base::failbit; +} + +template +void +time_get<_CharT, _InputIterator>::__get_year(int& __y, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4); + if (!(__err & ios_base::failbit)) + { + if (__t < 69) + __t += 2000; + else if (69 <= __t && __t <= 99) + __t += 1900; + __y = __t - 1900; + } +} + +template +void +time_get<_CharT, _InputIterator>::__get_year4(int& __y, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4); + if (!(__err & ios_base::failbit)) + __y = __t - 1900; +} + +template +void +time_get<_CharT, _InputIterator>::__get_hour(int& __h, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); + if (!(__err & ios_base::failbit) && __t <= 23) + __h = __t; + else + __err |= ios_base::failbit; +} + +template +void +time_get<_CharT, _InputIterator>::__get_12_hour(int& __h, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); + if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12) + __h = __t; + else + __err |= ios_base::failbit; +} + +template +void +time_get<_CharT, _InputIterator>::__get_minute(int& __m, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); + if (!(__err & ios_base::failbit) && __t <= 59) + __m = __t; + else + __err |= ios_base::failbit; +} + +template +void +time_get<_CharT, _InputIterator>::__get_second(int& __s, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); + if (!(__err & ios_base::failbit) && __t <= 60) + __s = __t; + else + __err |= ios_base::failbit; +} + +template +void +time_get<_CharT, _InputIterator>::__get_weekday(int& __w, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1); + if (!(__err & ios_base::failbit) && __t <= 6) + __w = __t; + else + __err |= ios_base::failbit; +} + +template +void +time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3); + if (!(__err & ios_base::failbit) && __t <= 365) + __d = __t; + else + __err |= ios_base::failbit; +} + +template +void +time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) + ; + if (__b == __e) + __err |= ios_base::eofbit; +} + +template +void +time_get<_CharT, _InputIterator>::__get_am_pm(int& __h, + iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + const string_type* __ap = this->__am_pm(); + if (__ap[0].size() + __ap[1].size() == 0) + { + __err |= ios_base::failbit; + return; + } + ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap; + if (__i == 0 && __h == 12) + __h = 0; + else if (__i == 1 && __h < 12) + __h += 12; +} + +template +void +time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e, + ios_base::iostate& __err, + const ctype& __ct) const +{ + if (__b == __e) + { + __err |= ios_base::eofbit | ios_base::failbit; + return; + } + if (__ct.narrow(*__b, 0) != '%') + __err |= ios_base::failbit; + else if(++__b == __e) + __err |= ios_base::eofbit; +} + +// time_get end primitives + +template +_InputIterator +time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e, + ios_base& __iob, + ios_base::iostate& __err, tm* __tm, + const char_type* __fmtb, const char_type* __fmte) const +{ + const ctype& __ct = use_facet >(__iob.getloc()); + __err = ios_base::goodbit; + while (__fmtb != __fmte && __err == ios_base::goodbit) + { + if (__b == __e) + { + __err = ios_base::failbit; + break; + } + if (__ct.narrow(*__fmtb, 0) == '%') + { + if (++__fmtb == __fmte) + { + __err = ios_base::failbit; + break; + } + char __cmd = __ct.narrow(*__fmtb, 0); + char __opt = '\0'; + if (__cmd == 'E' || __cmd == '0') + { + if (++__fmtb == __fmte) + { + __err = ios_base::failbit; + break; + } + __opt = __cmd; + __cmd = __ct.narrow(*__fmtb, 0); + } + __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt); + ++__fmtb; + } + else if (__ct.is(ctype_base::space, *__fmtb)) + { + for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb) + ; + for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) + ; + } + else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb)) + { + ++__b; + ++__fmtb; + } + else + __err = ios_base::failbit; + } + if (__b == __e) + __err |= ios_base::eofbit; + return __b; +} + +template +typename time_get<_CharT, _InputIterator>::dateorder +time_get<_CharT, _InputIterator>::do_date_order() const +{ + return mdy; +} + +template +_InputIterator +time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e, + ios_base& __iob, + ios_base::iostate& __err, + tm* __tm) const +{ + const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; + return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0])); +} + +template +_InputIterator +time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e, + ios_base& __iob, + ios_base::iostate& __err, + tm* __tm) const +{ + const string_type& __fmt = this->__x(); + return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size()); +} + +template +_InputIterator +time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e, + ios_base& __iob, + ios_base::iostate& __err, + tm* __tm) const +{ + const ctype& __ct = use_facet >(__iob.getloc()); + __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); + return __b; +} + +template +_InputIterator +time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e, + ios_base& __iob, + ios_base::iostate& __err, + tm* __tm) const +{ + const ctype& __ct = use_facet >(__iob.getloc()); + __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); + return __b; +} + +template +_InputIterator +time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e, + ios_base& __iob, + ios_base::iostate& __err, + tm* __tm) const +{ + const ctype& __ct = use_facet >(__iob.getloc()); + __get_year(__tm->tm_year, __b, __e, __err, __ct); + return __b; +} + +template +_InputIterator +time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, + ios_base& __iob, + ios_base::iostate& __err, tm* __tm, + char __fmt, char) const +{ + __err = ios_base::goodbit; + const ctype& __ct = use_facet >(__iob.getloc()); + switch (__fmt) + { + case 'a': + case 'A': + __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); + break; + case 'b': + case 'B': + case 'h': + __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); + break; + case 'c': + { + const string_type& __fm = this->__c(); + __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); + } + break; + case 'd': + case 'e': + __get_day(__tm->tm_mday, __b, __e, __err, __ct); + break; + case 'D': + { + const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'}; + __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); + } + break; + case 'F': + { + const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'}; + __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); + } + break; + case 'H': + __get_hour(__tm->tm_hour, __b, __e, __err, __ct); + break; + case 'I': + __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct); + break; + case 'j': + __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct); + break; + case 'm': + __get_month(__tm->tm_mon, __b, __e, __err, __ct); + break; + case 'M': + __get_minute(__tm->tm_min, __b, __e, __err, __ct); + break; + case 'n': + case 't': + __get_white_space(__b, __e, __err, __ct); + break; + case 'p': + __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct); + break; + case 'r': + { + const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'}; + __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); + } + break; + case 'R': + { + const char_type __fm[] = {'%', 'H', ':', '%', 'M'}; + __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); + } + break; + case 'S': + __get_second(__tm->tm_sec, __b, __e, __err, __ct); + break; + case 'T': + { + const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; + __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); + } + break; + case 'w': + __get_weekday(__tm->tm_wday, __b, __e, __err, __ct); + break; + case 'x': + return do_get_date(__b, __e, __iob, __err, __tm); + case 'X': + { + const string_type& __fm = this->__X(); + __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); + } + break; + case 'y': + __get_year(__tm->tm_year, __b, __e, __err, __ct); + break; + case 'Y': + __get_year4(__tm->tm_year, __b, __e, __err, __ct); + break; + case '%': + __get_percent(__b, __e, __err, __ct); + break; + default: + __err |= ios_base::failbit; + } + return __b; +} + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get) + +class _LIBCPP_TYPE_VIS __time_get +{ +protected: + locale_t __loc_; + + __time_get(const char* __nm); + __time_get(const string& __nm); + ~__time_get(); +}; + +template +class _LIBCPP_TYPE_VIS_ONLY __time_get_storage + : public __time_get +{ +protected: + typedef basic_string<_CharT> string_type; + + string_type __weeks_[14]; + string_type __months_[24]; + string_type __am_pm_[2]; + string_type __c_; + string_type __r_; + string_type __x_; + string_type __X_; + + explicit __time_get_storage(const char* __nm); + explicit __time_get_storage(const string& __nm); + + _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {} + + time_base::dateorder __do_date_order() const; + +private: + void init(const ctype<_CharT>&); + string_type __analyze(char __fmt, const ctype<_CharT>&); +}; + +template > +class _LIBCPP_TYPE_VIS_ONLY time_get_byname + : public time_get<_CharT, _InputIterator>, + private __time_get_storage<_CharT> +{ +public: + typedef time_base::dateorder dateorder; + typedef _InputIterator iter_type; + typedef _CharT char_type; + typedef basic_string string_type; + + _LIBCPP_INLINE_VISIBILITY + explicit time_get_byname(const char* __nm, size_t __refs = 0) + : time_get<_CharT, _InputIterator>(__refs), + __time_get_storage<_CharT>(__nm) {} + _LIBCPP_INLINE_VISIBILITY + explicit time_get_byname(const string& __nm, size_t __refs = 0) + : time_get<_CharT, _InputIterator>(__refs), + __time_get_storage<_CharT>(__nm) {} + +protected: + _LIBCPP_INLINE_VISIBILITY + ~time_get_byname() {} + + _LIBCPP_INLINE_VISIBILITY + virtual dateorder do_date_order() const {return this->__do_date_order();} +private: + _LIBCPP_INLINE_VISIBILITY + virtual const string_type* __weeks() const {return this->__weeks_;} + _LIBCPP_INLINE_VISIBILITY + virtual const string_type* __months() const {return this->__months_;} + _LIBCPP_INLINE_VISIBILITY + virtual const string_type* __am_pm() const {return this->__am_pm_;} + _LIBCPP_INLINE_VISIBILITY + virtual const string_type& __c() const {return this->__c_;} + _LIBCPP_INLINE_VISIBILITY + virtual const string_type& __r() const {return this->__r_;} + _LIBCPP_INLINE_VISIBILITY + virtual const string_type& __x() const {return this->__x_;} + _LIBCPP_INLINE_VISIBILITY + virtual const string_type& __X() const {return this->__X_;} +}; + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname) + +class _LIBCPP_TYPE_VIS __time_put +{ + locale_t __loc_; +protected: + _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {} + __time_put(const char* __nm); + __time_put(const string& __nm); + ~__time_put(); + void __do_put(char* __nb, char*& __ne, const tm* __tm, + char __fmt, char __mod) const; + void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, + char __fmt, char __mod) const; +}; + +template > +class _LIBCPP_TYPE_VIS_ONLY time_put + : public locale::facet, + private __time_put +{ +public: + typedef _CharT char_type; + typedef _OutputIterator iter_type; + + _LIBCPP_ALWAYS_INLINE + explicit time_put(size_t __refs = 0) + : locale::facet(__refs) {} + + iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, + const char_type* __pb, const char_type* __pe) const; + + _LIBCPP_ALWAYS_INLINE + iter_type put(iter_type __s, ios_base& __iob, char_type __fl, + const tm* __tm, char __fmt, char __mod = 0) const + { + return do_put(__s, __iob, __fl, __tm, __fmt, __mod); + } + + static locale::id id; + +protected: + _LIBCPP_ALWAYS_INLINE + ~time_put() {} + virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm, + char __fmt, char __mod) const; + + _LIBCPP_ALWAYS_INLINE + explicit time_put(const char* __nm, size_t __refs) + : locale::facet(__refs), + __time_put(__nm) {} + _LIBCPP_ALWAYS_INLINE + explicit time_put(const string& __nm, size_t __refs) + : locale::facet(__refs), + __time_put(__nm) {} +}; + +template +locale::id +time_put<_CharT, _OutputIterator>::id; + +template +_OutputIterator +time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob, + char_type __fl, const tm* __tm, + const char_type* __pb, + const char_type* __pe) const +{ + const ctype& __ct = use_facet >(__iob.getloc()); + for (; __pb != __pe; ++__pb) + { + if (__ct.narrow(*__pb, 0) == '%') + { + if (++__pb == __pe) + { + *__s++ = __pb[-1]; + break; + } + char __mod = 0; + char __fmt = __ct.narrow(*__pb, 0); + if (__fmt == 'E' || __fmt == 'O') + { + if (++__pb == __pe) + { + *__s++ = __pb[-2]; + *__s++ = __pb[-1]; + break; + } + __mod = __fmt; + __fmt = __ct.narrow(*__pb, 0); + } + __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod); + } + else + *__s++ = *__pb; + } + return __s; +} + +template +_OutputIterator +time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&, + char_type, const tm* __tm, + char __fmt, char __mod) const +{ + char_type __nar[100]; + char_type* __nb = __nar; + char_type* __ne = __nb + 100; + __do_put(__nb, __ne, __tm, __fmt, __mod); + return _VSTD::copy(__nb, __ne, __s); +} + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put) + +template > +class _LIBCPP_TYPE_VIS_ONLY time_put_byname + : public time_put<_CharT, _OutputIterator> +{ +public: + _LIBCPP_ALWAYS_INLINE + explicit time_put_byname(const char* __nm, size_t __refs = 0) + : time_put<_CharT, _OutputIterator>(__nm, __refs) {} + + _LIBCPP_ALWAYS_INLINE + explicit time_put_byname(const string& __nm, size_t __refs = 0) + : time_put<_CharT, _OutputIterator>(__nm, __refs) {} + +protected: + _LIBCPP_ALWAYS_INLINE + ~time_put_byname() {} +}; + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname) + +// money_base + +class _LIBCPP_TYPE_VIS money_base +{ +public: + enum part {none, space, symbol, sign, value}; + struct pattern {char field[4];}; + + _LIBCPP_ALWAYS_INLINE money_base() {} +}; + +// moneypunct + +template +class _LIBCPP_TYPE_VIS_ONLY moneypunct + : public locale::facet, + public money_base +{ +public: + typedef _CharT char_type; + typedef basic_string string_type; + + _LIBCPP_ALWAYS_INLINE + explicit moneypunct(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();} + _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();} + _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();} + _LIBCPP_ALWAYS_INLINE string_type curr_symbol() const {return do_curr_symbol();} + _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();} + _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();} + _LIBCPP_ALWAYS_INLINE int frac_digits() const {return do_frac_digits();} + _LIBCPP_ALWAYS_INLINE pattern pos_format() const {return do_pos_format();} + _LIBCPP_ALWAYS_INLINE pattern neg_format() const {return do_neg_format();} + + static locale::id id; + static const bool intl = _International; + +protected: + _LIBCPP_ALWAYS_INLINE + ~moneypunct() {} + + virtual char_type do_decimal_point() const {return numeric_limits::max();} + virtual char_type do_thousands_sep() const {return numeric_limits::max();} + virtual string do_grouping() const {return string();} + virtual string_type do_curr_symbol() const {return string_type();} + virtual string_type do_positive_sign() const {return string_type();} + virtual string_type do_negative_sign() const {return string_type(1, '-');} + virtual int do_frac_digits() const {return 0;} + virtual pattern do_pos_format() const + {pattern __p = {{symbol, sign, none, value}}; return __p;} + virtual pattern do_neg_format() const + {pattern __p = {{symbol, sign, none, value}}; return __p;} +}; + +template +locale::id +moneypunct<_CharT, _International>::id; + +template +const bool +moneypunct<_CharT, _International>::intl; + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct) + +// moneypunct_byname + +template +class _LIBCPP_TYPE_VIS_ONLY moneypunct_byname + : public moneypunct<_CharT, _International> +{ +public: + typedef money_base::pattern pattern; + typedef _CharT char_type; + typedef basic_string string_type; + + _LIBCPP_ALWAYS_INLINE + explicit moneypunct_byname(const char* __nm, size_t __refs = 0) + : moneypunct<_CharT, _International>(__refs) {init(__nm);} + + _LIBCPP_ALWAYS_INLINE + explicit moneypunct_byname(const string& __nm, size_t __refs = 0) + : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());} + +protected: + _LIBCPP_ALWAYS_INLINE + ~moneypunct_byname() {} + + virtual char_type do_decimal_point() const {return __decimal_point_;} + virtual char_type do_thousands_sep() const {return __thousands_sep_;} + virtual string do_grouping() const {return __grouping_;} + virtual string_type do_curr_symbol() const {return __curr_symbol_;} + virtual string_type do_positive_sign() const {return __positive_sign_;} + virtual string_type do_negative_sign() const {return __negative_sign_;} + virtual int do_frac_digits() const {return __frac_digits_;} + virtual pattern do_pos_format() const {return __pos_format_;} + virtual pattern do_neg_format() const {return __neg_format_;} + +private: + char_type __decimal_point_; + char_type __thousands_sep_; + string __grouping_; + string_type __curr_symbol_; + string_type __positive_sign_; + string_type __negative_sign_; + int __frac_digits_; + pattern __pos_format_; + pattern __neg_format_; + + void init(const char*); +}; + +template<> void moneypunct_byname::init(const char*); +template<> void moneypunct_byname::init(const char*); +template<> void moneypunct_byname::init(const char*); +template<> void moneypunct_byname::init(const char*); + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname) + +// money_get + +template +class __money_get +{ +protected: + typedef _CharT char_type; + typedef basic_string string_type; + + _LIBCPP_ALWAYS_INLINE __money_get() {} + + static void __gather_info(bool __intl, const locale& __loc, + money_base::pattern& __pat, char_type& __dp, + char_type& __ts, string& __grp, + string_type& __sym, string_type& __psn, + string_type& __nsn, int& __fd); +}; + +template +void +__money_get<_CharT>::__gather_info(bool __intl, const locale& __loc, + money_base::pattern& __pat, char_type& __dp, + char_type& __ts, string& __grp, + string_type& __sym, string_type& __psn, + string_type& __nsn, int& __fd) +{ + if (__intl) + { + const moneypunct& __mp = + use_facet >(__loc); + __pat = __mp.neg_format(); + __nsn = __mp.negative_sign(); + __psn = __mp.positive_sign(); + __dp = __mp.decimal_point(); + __ts = __mp.thousands_sep(); + __grp = __mp.grouping(); + __sym = __mp.curr_symbol(); + __fd = __mp.frac_digits(); + } + else + { + const moneypunct& __mp = + use_facet >(__loc); + __pat = __mp.neg_format(); + __nsn = __mp.negative_sign(); + __psn = __mp.positive_sign(); + __dp = __mp.decimal_point(); + __ts = __mp.thousands_sep(); + __grp = __mp.grouping(); + __sym = __mp.curr_symbol(); + __fd = __mp.frac_digits(); + } +} + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get) + +template > +class _LIBCPP_TYPE_VIS_ONLY money_get + : public locale::facet, + private __money_get<_CharT> +{ +public: + typedef _CharT char_type; + typedef _InputIterator iter_type; + typedef basic_string string_type; + + _LIBCPP_ALWAYS_INLINE + explicit money_get(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_ALWAYS_INLINE + iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, + ios_base::iostate& __err, long double& __v) const + { + return do_get(__b, __e, __intl, __iob, __err, __v); + } + + _LIBCPP_ALWAYS_INLINE + iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, + ios_base::iostate& __err, string_type& __v) const + { + return do_get(__b, __e, __intl, __iob, __err, __v); + } + + static locale::id id; + +protected: + + _LIBCPP_ALWAYS_INLINE + ~money_get() {} + + virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl, + ios_base& __iob, ios_base::iostate& __err, + long double& __v) const; + virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl, + ios_base& __iob, ios_base::iostate& __err, + string_type& __v) const; + +private: + static bool __do_get(iter_type& __b, iter_type __e, + bool __intl, const locale& __loc, + ios_base::fmtflags __flags, ios_base::iostate& __err, + bool& __neg, const ctype& __ct, + unique_ptr& __wb, + char_type*& __wn, char_type* __we); +}; + +template +locale::id +money_get<_CharT, _InputIterator>::id; + +_LIBCPP_FUNC_VIS void __do_nothing(void*); + +template +_LIBCPP_HIDDEN +void +__double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e) +{ + bool __owns = __b.get_deleter() != __do_nothing; + size_t __cur_cap = static_cast(__e-__b.get()) * sizeof(_Tp); + size_t __new_cap = __cur_cap < numeric_limits::max() / 2 ? + 2 * __cur_cap : numeric_limits::max(); + if (__new_cap == 0) + __new_cap = sizeof(_Tp); + size_t __n_off = static_cast(__n - __b.get()); + _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap); + if (__t == 0) + __throw_bad_alloc(); + if (__owns) + __b.release(); + __b = unique_ptr<_Tp, void(*)(void*)>(__t, free); + __new_cap /= sizeof(_Tp); + __n = __b.get() + __n_off; + __e = __b.get() + __new_cap; +} + +// true == success +template +bool +money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e, + bool __intl, const locale& __loc, + ios_base::fmtflags __flags, + ios_base::iostate& __err, + bool& __neg, + const ctype& __ct, + unique_ptr& __wb, + char_type*& __wn, char_type* __we) +{ + const unsigned __bz = 100; + unsigned __gbuf[__bz]; + unique_ptr __gb(__gbuf, __do_nothing); + unsigned* __gn = __gb.get(); + unsigned* __ge = __gn + __bz; + money_base::pattern __pat; + char_type __dp; + char_type __ts; + string __grp; + string_type __sym; + string_type __psn; + string_type __nsn; + // Capture the spaces read into money_base::{space,none} so they + // can be compared to initial spaces in __sym. + string_type __spaces; + int __fd; + __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp, + __sym, __psn, __nsn, __fd); + const string_type* __trailing_sign = 0; + __wn = __wb.get(); + for (unsigned __p = 0; __p < 4 && __b != __e; ++__p) + { + switch (__pat.field[__p]) + { + case money_base::space: + if (__p != 3) + { + if (__ct.is(ctype_base::space, *__b)) + __spaces.push_back(*__b++); + else + { + __err |= ios_base::failbit; + return false; + } + } + // drop through + case money_base::none: + if (__p != 3) + { + while (__b != __e && __ct.is(ctype_base::space, *__b)) + __spaces.push_back(*__b++); + } + break; + case money_base::sign: + if (__psn.size() + __nsn.size() > 0) + { + if (__psn.size() == 0 || __nsn.size() == 0) + { // sign is optional + if (__psn.size() > 0) + { // __nsn.size() == 0 + if (*__b == __psn[0]) + { + ++__b; + if (__psn.size() > 1) + __trailing_sign = &__psn; + } + else + __neg = true; + } + else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0 + { + ++__b; + __neg = true; + if (__nsn.size() > 1) + __trailing_sign = &__nsn; + } + } + else // sign is required + { + if (*__b == __psn[0]) + { + ++__b; + if (__psn.size() > 1) + __trailing_sign = &__psn; + } + else if (*__b == __nsn[0]) + { + ++__b; + __neg = true; + if (__nsn.size() > 1) + __trailing_sign = &__nsn; + } + else + { + __err |= ios_base::failbit; + return false; + } + } + } + break; + case money_base::symbol: + { + bool __more_needed = __trailing_sign || + (__p < 2) || + (__p == 2 && __pat.field[3] != static_cast(money_base::none)); + bool __sb = (__flags & ios_base::showbase) != 0; + if (__sb || __more_needed) + { + typename string_type::const_iterator __sym_space_end = __sym.begin(); + if (__p > 0 && (__pat.field[__p - 1] == money_base::none || + __pat.field[__p - 1] == money_base::space)) { + // Match spaces we've already read against spaces at + // the beginning of __sym. + while (__sym_space_end != __sym.end() && + __ct.is(ctype_base::space, *__sym_space_end)) + ++__sym_space_end; + const size_t __num_spaces = __sym_space_end - __sym.begin(); + if (__num_spaces > __spaces.size() || + !equal(__spaces.end() - __num_spaces, __spaces.end(), + __sym.begin())) { + // No match. Put __sym_space_end back at the + // beginning of __sym, which will prevent a + // match in the next loop. + __sym_space_end = __sym.begin(); + } + } + typename string_type::const_iterator __sym_curr_char = __sym_space_end; + while (__sym_curr_char != __sym.end() && __b != __e && + *__b == *__sym_curr_char) { + ++__b; + ++__sym_curr_char; + } + if (__sb && __sym_curr_char != __sym.end()) + { + __err |= ios_base::failbit; + return false; + } + } + } + break; + case money_base::value: + { + unsigned __ng = 0; + for (; __b != __e; ++__b) + { + char_type __c = *__b; + if (__ct.is(ctype_base::digit, __c)) + { + if (__wn == __we) + __double_or_nothing(__wb, __wn, __we); + *__wn++ = __c; + ++__ng; + } + else if (__grp.size() > 0 && __ng > 0 && __c == __ts) + { + if (__gn == __ge) + __double_or_nothing(__gb, __gn, __ge); + *__gn++ = __ng; + __ng = 0; + } + else + break; + } + if (__gb.get() != __gn && __ng > 0) + { + if (__gn == __ge) + __double_or_nothing(__gb, __gn, __ge); + *__gn++ = __ng; + } + if (__fd > 0) + { + if (__b == __e || *__b != __dp) + { + __err |= ios_base::failbit; + return false; + } + for (++__b; __fd > 0; --__fd, ++__b) + { + if (__b == __e || !__ct.is(ctype_base::digit, *__b)) + { + __err |= ios_base::failbit; + return false; + } + if (__wn == __we) + __double_or_nothing(__wb, __wn, __we); + *__wn++ = *__b; + } + } + if (__wn == __wb.get()) + { + __err |= ios_base::failbit; + return false; + } + } + break; + } + } + if (__trailing_sign) + { + for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b) + { + if (__b == __e || *__b != (*__trailing_sign)[__i]) + { + __err |= ios_base::failbit; + return false; + } + } + } + if (__gb.get() != __gn) + { + ios_base::iostate __et = ios_base::goodbit; + __check_grouping(__grp, __gb.get(), __gn, __et); + if (__et) + { + __err |= ios_base::failbit; + return false; + } + } + return true; +} + +template +_InputIterator +money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, + bool __intl, ios_base& __iob, + ios_base::iostate& __err, + long double& __v) const +{ + const int __bz = 100; + char_type __wbuf[__bz]; + unique_ptr __wb(__wbuf, __do_nothing); + char_type* __wn; + char_type* __we = __wbuf + __bz; + locale __loc = __iob.getloc(); + const ctype& __ct = use_facet >(__loc); + bool __neg = false; + if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, + __wb, __wn, __we)) + { + const char __src[] = "0123456789"; + char_type __atoms[sizeof(__src)-1]; + __ct.widen(__src, __src + (sizeof(__src)-1), __atoms); + char __nbuf[__bz]; + char* __nc = __nbuf; + unique_ptr __h(0, free); + if (__wn - __wb.get() > __bz-2) + { + __h.reset((char*)malloc(static_cast(__wn - __wb.get() + 2))); + if (__h.get() == 0) + __throw_bad_alloc(); + __nc = __h.get(); + } + if (__neg) + *__nc++ = '-'; + for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc) + *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms]; + *__nc = char(); + if (sscanf(__nbuf, "%Lf", &__v) != 1) + __throw_runtime_error("money_get error"); + } + if (__b == __e) + __err |= ios_base::eofbit; + return __b; +} + +template +_InputIterator +money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, + bool __intl, ios_base& __iob, + ios_base::iostate& __err, + string_type& __v) const +{ + const int __bz = 100; + char_type __wbuf[__bz]; + unique_ptr __wb(__wbuf, __do_nothing); + char_type* __wn; + char_type* __we = __wbuf + __bz; + locale __loc = __iob.getloc(); + const ctype& __ct = use_facet >(__loc); + bool __neg = false; + if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, + __wb, __wn, __we)) + { + __v.clear(); + if (__neg) + __v.push_back(__ct.widen('-')); + char_type __z = __ct.widen('0'); + char_type* __w; + for (__w = __wb.get(); __w < __wn-1; ++__w) + if (*__w != __z) + break; + __v.append(__w, __wn); + } + if (__b == __e) + __err |= ios_base::eofbit; + return __b; +} + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get) + +// money_put + +template +class __money_put +{ +protected: + typedef _CharT char_type; + typedef basic_string string_type; + + _LIBCPP_ALWAYS_INLINE __money_put() {} + + static void __gather_info(bool __intl, bool __neg, const locale& __loc, + money_base::pattern& __pat, char_type& __dp, + char_type& __ts, string& __grp, + string_type& __sym, string_type& __sn, + int& __fd); + static void __format(char_type* __mb, char_type*& __mi, char_type*& __me, + ios_base::fmtflags __flags, + const char_type* __db, const char_type* __de, + const ctype& __ct, bool __neg, + const money_base::pattern& __pat, char_type __dp, + char_type __ts, const string& __grp, + const string_type& __sym, const string_type& __sn, + int __fd); +}; + +template +void +__money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc, + money_base::pattern& __pat, char_type& __dp, + char_type& __ts, string& __grp, + string_type& __sym, string_type& __sn, + int& __fd) +{ + if (__intl) + { + const moneypunct& __mp = + use_facet >(__loc); + if (__neg) + { + __pat = __mp.neg_format(); + __sn = __mp.negative_sign(); + } + else + { + __pat = __mp.pos_format(); + __sn = __mp.positive_sign(); + } + __dp = __mp.decimal_point(); + __ts = __mp.thousands_sep(); + __grp = __mp.grouping(); + __sym = __mp.curr_symbol(); + __fd = __mp.frac_digits(); + } + else + { + const moneypunct& __mp = + use_facet >(__loc); + if (__neg) + { + __pat = __mp.neg_format(); + __sn = __mp.negative_sign(); + } + else + { + __pat = __mp.pos_format(); + __sn = __mp.positive_sign(); + } + __dp = __mp.decimal_point(); + __ts = __mp.thousands_sep(); + __grp = __mp.grouping(); + __sym = __mp.curr_symbol(); + __fd = __mp.frac_digits(); + } +} + +template +void +__money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me, + ios_base::fmtflags __flags, + const char_type* __db, const char_type* __de, + const ctype& __ct, bool __neg, + const money_base::pattern& __pat, char_type __dp, + char_type __ts, const string& __grp, + const string_type& __sym, const string_type& __sn, + int __fd) +{ + __me = __mb; + for (unsigned __p = 0; __p < 4; ++__p) + { + switch (__pat.field[__p]) + { + case money_base::none: + __mi = __me; + break; + case money_base::space: + __mi = __me; + *__me++ = __ct.widen(' '); + break; + case money_base::sign: + if (!__sn.empty()) + *__me++ = __sn[0]; + break; + case money_base::symbol: + if (!__sym.empty() && (__flags & ios_base::showbase)) + __me = _VSTD::copy(__sym.begin(), __sym.end(), __me); + break; + case money_base::value: + { + // remember start of value so we can reverse it + char_type* __t = __me; + // find beginning of digits + if (__neg) + ++__db; + // find end of digits + const char_type* __d; + for (__d = __db; __d < __de; ++__d) + if (!__ct.is(ctype_base::digit, *__d)) + break; + // print fractional part + if (__fd > 0) + { + int __f; + for (__f = __fd; __d > __db && __f > 0; --__f) + *__me++ = *--__d; + char_type __z = __f > 0 ? __ct.widen('0') : char_type(); + for (; __f > 0; --__f) + *__me++ = __z; + *__me++ = __dp; + } + // print units part + if (__d == __db) + { + *__me++ = __ct.widen('0'); + } + else + { + unsigned __ng = 0; + unsigned __ig = 0; + unsigned __gl = __grp.empty() ? numeric_limits::max() + : static_cast(__grp[__ig]); + while (__d != __db) + { + if (__ng == __gl) + { + *__me++ = __ts; + __ng = 0; + if (++__ig < __grp.size()) + __gl = __grp[__ig] == numeric_limits::max() ? + numeric_limits::max() : + static_cast(__grp[__ig]); + } + *__me++ = *--__d; + ++__ng; + } + } + // reverse it + reverse(__t, __me); + } + break; + } + } + // print rest of sign, if any + if (__sn.size() > 1) + __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me); + // set alignment + if ((__flags & ios_base::adjustfield) == ios_base::left) + __mi = __me; + else if ((__flags & ios_base::adjustfield) != ios_base::internal) + __mi = __mb; +} + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put) + +template > +class _LIBCPP_TYPE_VIS_ONLY money_put + : public locale::facet, + private __money_put<_CharT> +{ +public: + typedef _CharT char_type; + typedef _OutputIterator iter_type; + typedef basic_string string_type; + + _LIBCPP_ALWAYS_INLINE + explicit money_put(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_ALWAYS_INLINE + iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, + long double __units) const + { + return do_put(__s, __intl, __iob, __fl, __units); + } + + _LIBCPP_ALWAYS_INLINE + iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, + const string_type& __digits) const + { + return do_put(__s, __intl, __iob, __fl, __digits); + } + + static locale::id id; + +protected: + _LIBCPP_ALWAYS_INLINE + ~money_put() {} + + virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, + char_type __fl, long double __units) const; + virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, + char_type __fl, const string_type& __digits) const; +}; + +template +locale::id +money_put<_CharT, _OutputIterator>::id; + +template +_OutputIterator +money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, + ios_base& __iob, char_type __fl, + long double __units) const +{ + // convert to char + const size_t __bs = 100; + char __buf[__bs]; + char* __bb = __buf; + char_type __digits[__bs]; + char_type* __db = __digits; + size_t __n = static_cast(snprintf(__bb, __bs, "%.0Lf", __units)); + unique_ptr __hn(0, free); + unique_ptr __hd(0, free); + // secure memory for digit storage + if (__n > __bs-1) + { +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __n = static_cast(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units)); +#else + __n = __asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units); +#endif + if (__bb == 0) + __throw_bad_alloc(); + __hn.reset(__bb); + __hd.reset((char_type*)malloc(__n * sizeof(char_type))); + if (__hd == nullptr) + __throw_bad_alloc(); + __db = __hd.get(); + } + // gather info + locale __loc = __iob.getloc(); + const ctype& __ct = use_facet >(__loc); + __ct.widen(__bb, __bb + __n, __db); + bool __neg = __n > 0 && __bb[0] == '-'; + money_base::pattern __pat; + char_type __dp; + char_type __ts; + string __grp; + string_type __sym; + string_type __sn; + int __fd; + this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd); + // secure memory for formatting + char_type __mbuf[__bs]; + char_type* __mb = __mbuf; + unique_ptr __hw(0, free); + size_t __exn = static_cast(__n) > __fd ? + (__n - static_cast(__fd)) * 2 + __sn.size() + + __sym.size() + static_cast(__fd) + 1 + : __sn.size() + __sym.size() + static_cast(__fd) + 2; + if (__exn > __bs) + { + __hw.reset((char_type*)malloc(__exn * sizeof(char_type))); + __mb = __hw.get(); + if (__mb == 0) + __throw_bad_alloc(); + } + // format + char_type* __mi; + char_type* __me; + this->__format(__mb, __mi, __me, __iob.flags(), + __db, __db + __n, __ct, + __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd); + return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl); +} + +template +_OutputIterator +money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, + ios_base& __iob, char_type __fl, + const string_type& __digits) const +{ + // gather info + locale __loc = __iob.getloc(); + const ctype& __ct = use_facet >(__loc); + bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-'); + money_base::pattern __pat; + char_type __dp; + char_type __ts; + string __grp; + string_type __sym; + string_type __sn; + int __fd; + this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd); + // secure memory for formatting + char_type __mbuf[100]; + char_type* __mb = __mbuf; + unique_ptr __h(0, free); + size_t __exn = static_cast(__digits.size()) > __fd ? + (__digits.size() - static_cast(__fd)) * 2 + + __sn.size() + __sym.size() + static_cast(__fd) + 1 + : __sn.size() + __sym.size() + static_cast(__fd) + 2; + if (__exn > 100) + { + __h.reset((char_type*)malloc(__exn * sizeof(char_type))); + __mb = __h.get(); + if (__mb == 0) + __throw_bad_alloc(); + } + // format + char_type* __mi; + char_type* __me; + this->__format(__mb, __mi, __me, __iob.flags(), + __digits.data(), __digits.data() + __digits.size(), __ct, + __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd); + return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl); +} + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put) + +// messages + +class _LIBCPP_TYPE_VIS messages_base +{ +public: + typedef ptrdiff_t catalog; + + _LIBCPP_ALWAYS_INLINE messages_base() {} +}; + +template +class _LIBCPP_TYPE_VIS_ONLY messages + : public locale::facet, + public messages_base +{ +public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + _LIBCPP_ALWAYS_INLINE + explicit messages(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_ALWAYS_INLINE + catalog open(const basic_string& __nm, const locale& __loc) const + { + return do_open(__nm, __loc); + } + + _LIBCPP_ALWAYS_INLINE + string_type get(catalog __c, int __set, int __msgid, + const string_type& __dflt) const + { + return do_get(__c, __set, __msgid, __dflt); + } + + _LIBCPP_ALWAYS_INLINE + void close(catalog __c) const + { + do_close(__c); + } + + static locale::id id; + +protected: + _LIBCPP_ALWAYS_INLINE + ~messages() {} + + virtual catalog do_open(const basic_string&, const locale&) const; + virtual string_type do_get(catalog, int __set, int __msgid, + const string_type& __dflt) const; + virtual void do_close(catalog) const; +}; + +template +locale::id +messages<_CharT>::id; + +template +typename messages<_CharT>::catalog +messages<_CharT>::do_open(const basic_string& __nm, const locale&) const +{ +#ifdef _LIBCPP_HAS_CATOPEN + catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE); + if (__cat != -1) + __cat = static_cast((static_cast(__cat) >> 1)); + return __cat; +#else // !_LIBCPP_HAS_CATOPEN + return -1; +#endif // _LIBCPP_HAS_CATOPEN +} + +template +typename messages<_CharT>::string_type +messages<_CharT>::do_get(catalog __c, int __set, int __msgid, + const string_type& __dflt) const +{ +#ifdef _LIBCPP_HAS_CATOPEN + string __ndflt; + __narrow_to_utf8()(back_inserter(__ndflt), + __dflt.c_str(), + __dflt.c_str() + __dflt.size()); + if (__c != -1) + __c <<= 1; + nl_catd __cat = (nl_catd)__c; + char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str()); + string_type __w; + __widen_from_utf8()(back_inserter(__w), + __n, __n + strlen(__n)); + return __w; +#else // !_LIBCPP_HAS_CATOPEN + return __dflt; +#endif // _LIBCPP_HAS_CATOPEN +} + +template +void +messages<_CharT>::do_close(catalog __c) const +{ +#ifdef _LIBCPP_HAS_CATOPEN + if (__c != -1) + __c <<= 1; + nl_catd __cat = (nl_catd)__c; + catclose(__cat); +#endif // _LIBCPP_HAS_CATOPEN +} + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages) + +template +class _LIBCPP_TYPE_VIS_ONLY messages_byname + : public messages<_CharT> +{ +public: + typedef messages_base::catalog catalog; + typedef basic_string<_CharT> string_type; + + _LIBCPP_ALWAYS_INLINE + explicit messages_byname(const char*, size_t __refs = 0) + : messages<_CharT>(__refs) {} + + _LIBCPP_ALWAYS_INLINE + explicit messages_byname(const string&, size_t __refs = 0) + : messages<_CharT>(__refs) {} + +protected: + _LIBCPP_ALWAYS_INLINE + ~messages_byname() {} +}; + +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname) + +template, + class _Byte_alloc = allocator > +class _LIBCPP_TYPE_VIS_ONLY wstring_convert +{ +public: + typedef basic_string, _Byte_alloc> byte_string; + typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string; + typedef typename _Codecvt::state_type state_type; + typedef typename wide_string::traits_type::int_type int_type; + +private: + byte_string __byte_err_string_; + wide_string __wide_err_string_; + _Codecvt* __cvtptr_; + state_type __cvtstate_; + size_t __cvtcount_; + + wstring_convert(const wstring_convert& __wc); + wstring_convert& operator=(const wstring_convert& __wc); +public: + _LIBCPP_ALWAYS_INLINE + _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt); + _LIBCPP_ALWAYS_INLINE + wstring_convert(_Codecvt* __pcvt, state_type __state); + _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err, + const wide_string& __wide_err = wide_string()); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_ALWAYS_INLINE + wstring_convert(wstring_convert&& __wc); +#endif + ~wstring_convert(); + + _LIBCPP_ALWAYS_INLINE + wide_string from_bytes(char __byte) + {return from_bytes(&__byte, &__byte+1);} + _LIBCPP_ALWAYS_INLINE + wide_string from_bytes(const char* __ptr) + {return from_bytes(__ptr, __ptr + char_traits::length(__ptr));} + _LIBCPP_ALWAYS_INLINE + wide_string from_bytes(const byte_string& __str) + {return from_bytes(__str.data(), __str.data() + __str.size());} + wide_string from_bytes(const char* __first, const char* __last); + + _LIBCPP_ALWAYS_INLINE + byte_string to_bytes(_Elem __wchar) + {return to_bytes(&__wchar, &__wchar+1);} + _LIBCPP_ALWAYS_INLINE + byte_string to_bytes(const _Elem* __wptr) + {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));} + _LIBCPP_ALWAYS_INLINE + byte_string to_bytes(const wide_string& __wstr) + {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());} + byte_string to_bytes(const _Elem* __first, const _Elem* __last); + + _LIBCPP_ALWAYS_INLINE + size_t converted() const _NOEXCEPT {return __cvtcount_;} + _LIBCPP_ALWAYS_INLINE + state_type state() const {return __cvtstate_;} +}; + +template +inline +wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: + wstring_convert(_Codecvt* __pcvt) + : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0) +{ +} + +template +inline +wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: + wstring_convert(_Codecvt* __pcvt, state_type __state) + : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0) +{ +} + +template +wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: + wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err) + : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err), + __cvtstate_(), __cvtcount_(0) +{ + __cvtptr_ = new _Codecvt; +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +inline +wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: + wstring_convert(wstring_convert&& __wc) + : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)), + __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)), + __cvtptr_(__wc.__cvtptr_), + __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_) +{ + __wc.__cvtptr_ = nullptr; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert() +{ + delete __cvtptr_; +} + +template +typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string +wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: + from_bytes(const char* __frm, const char* __frm_end) +{ + __cvtcount_ = 0; + if (__cvtptr_ != nullptr) + { + wide_string __ws(2*(__frm_end - __frm), _Elem()); + if (__frm != __frm_end) + __ws.resize(__ws.capacity()); + codecvt_base::result __r = codecvt_base::ok; + state_type __st = __cvtstate_; + if (__frm != __frm_end) + { + _Elem* __to = &__ws[0]; + _Elem* __to_end = __to + __ws.size(); + const char* __frm_nxt; + do + { + _Elem* __to_nxt; + __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt, + __to, __to_end, __to_nxt); + __cvtcount_ += __frm_nxt - __frm; + if (__frm_nxt == __frm) + { + __r = codecvt_base::error; + } + else if (__r == codecvt_base::noconv) + { + __ws.resize(__to - &__ws[0]); + // This only gets executed if _Elem is char + __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end); + __frm = __frm_nxt; + __r = codecvt_base::ok; + } + else if (__r == codecvt_base::ok) + { + __ws.resize(__to_nxt - &__ws[0]); + __frm = __frm_nxt; + } + else if (__r == codecvt_base::partial) + { + ptrdiff_t __s = __to_nxt - &__ws[0]; + __ws.resize(2 * __s); + __to = &__ws[0] + __s; + __to_end = &__ws[0] + __ws.size(); + __frm = __frm_nxt; + } + } while (__r == codecvt_base::partial && __frm_nxt < __frm_end); + } + if (__r == codecvt_base::ok) + return __ws; + } +#ifndef _LIBCPP_NO_EXCEPTIONS + if (__wide_err_string_.empty()) + throw range_error("wstring_convert: from_bytes error"); +#endif // _LIBCPP_NO_EXCEPTIONS + return __wide_err_string_; +} + +template +typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string +wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: + to_bytes(const _Elem* __frm, const _Elem* __frm_end) +{ + __cvtcount_ = 0; + if (__cvtptr_ != nullptr) + { + byte_string __bs(2*(__frm_end - __frm), char()); + if (__frm != __frm_end) + __bs.resize(__bs.capacity()); + codecvt_base::result __r = codecvt_base::ok; + state_type __st = __cvtstate_; + if (__frm != __frm_end) + { + char* __to = &__bs[0]; + char* __to_end = __to + __bs.size(); + const _Elem* __frm_nxt; + do + { + char* __to_nxt; + __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt, + __to, __to_end, __to_nxt); + __cvtcount_ += __frm_nxt - __frm; + if (__frm_nxt == __frm) + { + __r = codecvt_base::error; + } + else if (__r == codecvt_base::noconv) + { + __bs.resize(__to - &__bs[0]); + // This only gets executed if _Elem is char + __bs.append((const char*)__frm, (const char*)__frm_end); + __frm = __frm_nxt; + __r = codecvt_base::ok; + } + else if (__r == codecvt_base::ok) + { + __bs.resize(__to_nxt - &__bs[0]); + __frm = __frm_nxt; + } + else if (__r == codecvt_base::partial) + { + ptrdiff_t __s = __to_nxt - &__bs[0]; + __bs.resize(2 * __s); + __to = &__bs[0] + __s; + __to_end = &__bs[0] + __bs.size(); + __frm = __frm_nxt; + } + } while (__r == codecvt_base::partial && __frm_nxt < __frm_end); + } + if (__r == codecvt_base::ok) + { + size_t __s = __bs.size(); + __bs.resize(__bs.capacity()); + char* __to = &__bs[0] + __s; + char* __to_end = __to + __bs.size(); + do + { + char* __to_nxt; + __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt); + if (__r == codecvt_base::noconv) + { + __bs.resize(__to - &__bs[0]); + __r = codecvt_base::ok; + } + else if (__r == codecvt_base::ok) + { + __bs.resize(__to_nxt - &__bs[0]); + } + else if (__r == codecvt_base::partial) + { + ptrdiff_t __sp = __to_nxt - &__bs[0]; + __bs.resize(2 * __sp); + __to = &__bs[0] + __sp; + __to_end = &__bs[0] + __bs.size(); + } + } while (__r == codecvt_base::partial); + if (__r == codecvt_base::ok) + return __bs; + } + } +#ifndef _LIBCPP_NO_EXCEPTIONS + if (__byte_err_string_.empty()) + throw range_error("wstring_convert: to_bytes error"); +#endif // _LIBCPP_NO_EXCEPTIONS + return __byte_err_string_; +} + +template > +class _LIBCPP_TYPE_VIS_ONLY wbuffer_convert + : public basic_streambuf<_Elem, _Tr> +{ +public: + // types: + typedef _Elem char_type; + typedef _Tr traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + typedef typename _Codecvt::state_type state_type; + +private: + char* __extbuf_; + const char* __extbufnext_; + const char* __extbufend_; + char __extbuf_min_[8]; + size_t __ebs_; + char_type* __intbuf_; + size_t __ibs_; + streambuf* __bufptr_; + _Codecvt* __cv_; + state_type __st_; + ios_base::openmode __cm_; + bool __owns_eb_; + bool __owns_ib_; + bool __always_noconv_; + + wbuffer_convert(const wbuffer_convert&); + wbuffer_convert& operator=(const wbuffer_convert&); +public: + _LIBCPP_EXPLICIT_AFTER_CXX11 wbuffer_convert(streambuf* __bytebuf = 0, + _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type()); + ~wbuffer_convert(); + + _LIBCPP_INLINE_VISIBILITY + streambuf* rdbuf() const {return __bufptr_;} + _LIBCPP_INLINE_VISIBILITY + streambuf* rdbuf(streambuf* __bytebuf) + { + streambuf* __r = __bufptr_; + __bufptr_ = __bytebuf; + return __r; + } + + _LIBCPP_INLINE_VISIBILITY + state_type state() const {return __st_;} + +protected: + virtual int_type underflow(); + virtual int_type pbackfail(int_type __c = traits_type::eof()); + virtual int_type overflow (int_type __c = traits_type::eof()); + virtual basic_streambuf* setbuf(char_type* __s, + streamsize __n); + virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __wch = ios_base::in | ios_base::out); + virtual pos_type seekpos(pos_type __sp, + ios_base::openmode __wch = ios_base::in | ios_base::out); + virtual int sync(); + +private: + bool __read_mode(); + void __write_mode(); + wbuffer_convert* __close(); +}; + +template +wbuffer_convert<_Codecvt, _Elem, _Tr>:: + wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state) + : __extbuf_(0), + __extbufnext_(0), + __extbufend_(0), + __ebs_(0), + __intbuf_(0), + __ibs_(0), + __bufptr_(__bytebuf), + __cv_(__pcvt), + __st_(__state), + __cm_(0), + __owns_eb_(false), + __owns_ib_(false), + __always_noconv_(__cv_ ? __cv_->always_noconv() : false) +{ + setbuf(0, 4096); +} + +template +wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert() +{ + __close(); + delete __cv_; + if (__owns_eb_) + delete [] __extbuf_; + if (__owns_ib_) + delete [] __intbuf_; +} + +template +typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type +wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow() +{ + if (__cv_ == 0 || __bufptr_ == 0) + return traits_type::eof(); + bool __initial = __read_mode(); + char_type __1buf; + if (this->gptr() == 0) + this->setg(&__1buf, &__1buf+1, &__1buf+1); + const size_t __unget_sz = __initial ? 0 : min((this->egptr() - this->eback()) / 2, 4); + int_type __c = traits_type::eof(); + if (this->gptr() == this->egptr()) + { + memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type)); + if (__always_noconv_) + { + streamsize __nmemb = static_cast(this->egptr() - this->eback() - __unget_sz); + __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb); + if (__nmemb != 0) + { + this->setg(this->eback(), + this->eback() + __unget_sz, + this->eback() + __unget_sz + __nmemb); + __c = *this->gptr(); + } + } + else + { + memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); + __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); + __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_); + streamsize __nmemb = _VSTD::min(static_cast(this->egptr() - this->eback() - __unget_sz), + static_cast(__extbufend_ - __extbufnext_)); + codecvt_base::result __r; + state_type __svs = __st_; + streamsize __nr = __bufptr_->sgetn(const_cast(__extbufnext_), __nmemb); + if (__nr != 0) + { + __extbufend_ = __extbufnext_ + __nr; + char_type* __inext; + __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_, + this->eback() + __unget_sz, + this->egptr(), __inext); + if (__r == codecvt_base::noconv) + { + this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_); + __c = *this->gptr(); + } + else if (__inext != this->eback() + __unget_sz) + { + this->setg(this->eback(), this->eback() + __unget_sz, __inext); + __c = *this->gptr(); + } + } + } + } + else + __c = *this->gptr(); + if (this->eback() == &__1buf) + this->setg(0, 0, 0); + return __c; +} + +template +typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type +wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c) +{ + if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr()) + { + if (traits_type::eq_int_type(__c, traits_type::eof())) + { + this->gbump(-1); + return traits_type::not_eof(__c); + } + if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) + { + this->gbump(-1); + *this->gptr() = traits_type::to_char_type(__c); + return __c; + } + } + return traits_type::eof(); +} + +template +typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type +wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c) +{ + if (__cv_ == 0 || __bufptr_ == 0) + return traits_type::eof(); + __write_mode(); + char_type __1buf; + char_type* __pb_save = this->pbase(); + char_type* __epb_save = this->epptr(); + if (!traits_type::eq_int_type(__c, traits_type::eof())) + { + if (this->pptr() == 0) + this->setp(&__1buf, &__1buf+1); + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } + if (this->pptr() != this->pbase()) + { + if (__always_noconv_) + { + streamsize __nmemb = static_cast(this->pptr() - this->pbase()); + if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb) + return traits_type::eof(); + } + else + { + char* __extbe = __extbuf_; + codecvt_base::result __r; + do + { + const char_type* __e; + __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, + __extbuf_, __extbuf_ + __ebs_, __extbe); + if (__e == this->pbase()) + return traits_type::eof(); + if (__r == codecvt_base::noconv) + { + streamsize __nmemb = static_cast(this->pptr() - this->pbase()); + if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb) + return traits_type::eof(); + } + else if (__r == codecvt_base::ok || __r == codecvt_base::partial) + { + streamsize __nmemb = static_cast(__extbe - __extbuf_); + if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb) + return traits_type::eof(); + if (__r == codecvt_base::partial) + { + this->setp((char_type*)__e, this->pptr()); + this->pbump(this->epptr() - this->pbase()); + } + } + else + return traits_type::eof(); + } while (__r == codecvt_base::partial); + } + this->setp(__pb_save, __epb_save); + } + return traits_type::not_eof(__c); +} + +template +basic_streambuf<_Elem, _Tr>* +wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n) +{ + this->setg(0, 0, 0); + this->setp(0, 0); + if (__owns_eb_) + delete [] __extbuf_; + if (__owns_ib_) + delete [] __intbuf_; + __ebs_ = __n; + if (__ebs_ > sizeof(__extbuf_min_)) + { + if (__always_noconv_ && __s) + { + __extbuf_ = (char*)__s; + __owns_eb_ = false; + } + else + { + __extbuf_ = new char[__ebs_]; + __owns_eb_ = true; + } + } + else + { + __extbuf_ = __extbuf_min_; + __ebs_ = sizeof(__extbuf_min_); + __owns_eb_ = false; + } + if (!__always_noconv_) + { + __ibs_ = max(__n, sizeof(__extbuf_min_)); + if (__s && __ibs_ >= sizeof(__extbuf_min_)) + { + __intbuf_ = __s; + __owns_ib_ = false; + } + else + { + __intbuf_ = new char_type[__ibs_]; + __owns_ib_ = true; + } + } + else + { + __ibs_ = 0; + __intbuf_ = 0; + __owns_ib_ = false; + } + return this; +} + +template +typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type +wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __om) +{ + int __width = __cv_->encoding(); + if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync()) + return pos_type(off_type(-1)); + // __width > 0 || __off == 0, now check __way + if (__way != ios_base::beg && __way != ios_base::cur && __way != ios_base::end) + return pos_type(off_type(-1)); + pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om); + __r.state(__st_); + return __r; +} + +template +typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type +wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch) +{ + if (__cv_ == 0 || __bufptr_ == 0 || sync()) + return pos_type(off_type(-1)); + if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1))) + return pos_type(off_type(-1)); + return __sp; +} + +template +int +wbuffer_convert<_Codecvt, _Elem, _Tr>::sync() +{ + if (__cv_ == 0 || __bufptr_ == 0) + return 0; + if (__cm_ & ios_base::out) + { + if (this->pptr() != this->pbase()) + if (overflow() == traits_type::eof()) + return -1; + codecvt_base::result __r; + do + { + char* __extbe; + __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe); + streamsize __nmemb = static_cast(__extbe - __extbuf_); + if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb) + return -1; + } while (__r == codecvt_base::partial); + if (__r == codecvt_base::error) + return -1; + if (__bufptr_->pubsync()) + return -1; + } + else if (__cm_ & ios_base::in) + { + off_type __c; + if (__always_noconv_) + __c = this->egptr() - this->gptr(); + else + { + int __width = __cv_->encoding(); + __c = __extbufend_ - __extbufnext_; + if (__width > 0) + __c += __width * (this->egptr() - this->gptr()); + else + { + if (this->gptr() != this->egptr()) + { + reverse(this->gptr(), this->egptr()); + codecvt_base::result __r; + const char_type* __e = this->gptr(); + char* __extbe; + do + { + __r = __cv_->out(__st_, __e, this->egptr(), __e, + __extbuf_, __extbuf_ + __ebs_, __extbe); + switch (__r) + { + case codecvt_base::noconv: + __c += this->egptr() - this->gptr(); + break; + case codecvt_base::ok: + case codecvt_base::partial: + __c += __extbe - __extbuf_; + break; + default: + return -1; + } + } while (__r == codecvt_base::partial); + } + } + } + if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1))) + return -1; + this->setg(0, 0, 0); + __cm_ = 0; + } + return 0; +} + +template +bool +wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode() +{ + if (!(__cm_ & ios_base::in)) + { + this->setp(0, 0); + if (__always_noconv_) + this->setg((char_type*)__extbuf_, + (char_type*)__extbuf_ + __ebs_, + (char_type*)__extbuf_ + __ebs_); + else + this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_); + __cm_ = ios_base::in; + return true; + } + return false; +} + +template +void +wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode() +{ + if (!(__cm_ & ios_base::out)) + { + this->setg(0, 0, 0); + if (__ebs_ > sizeof(__extbuf_min_)) + { + if (__always_noconv_) + this->setp((char_type*)__extbuf_, + (char_type*)__extbuf_ + (__ebs_ - 1)); + else + this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1)); + } + else + this->setp(0, 0); + __cm_ = ios_base::out; + } +} + +template +wbuffer_convert<_Codecvt, _Elem, _Tr>* +wbuffer_convert<_Codecvt, _Elem, _Tr>::__close() +{ + wbuffer_convert* __rt = 0; + if (__cv_ != 0 && __bufptr_ != 0) + { + __rt = this; + if ((__cm_ & ios_base::out) && sync()) + __rt = 0; + } + return __rt; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_LOCALE diff --git a/headers/libs/libc++/map b/headers/libs/libc++/map new file mode 100644 index 0000000000..561c3ddc93 --- /dev/null +++ b/headers/libs/libc++/map @@ -0,0 +1,2230 @@ +// -*- C++ -*- +//===----------------------------- map ------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_MAP +#define _LIBCPP_MAP + +/* + + map synopsis + +namespace std +{ + +template , + class Allocator = allocator>> +class map +{ +public: + // types: + typedef Key key_type; + typedef T mapped_type; + typedef pair value_type; + typedef Compare key_compare; + typedef Allocator allocator_type; + typedef typename allocator_type::reference reference; + typedef typename allocator_type::const_reference const_reference; + typedef typename allocator_type::pointer pointer; + typedef typename allocator_type::const_pointer const_pointer; + typedef typename allocator_type::size_type size_type; + typedef typename allocator_type::difference_type difference_type; + + typedef implementation-defined iterator; + typedef implementation-defined const_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + class value_compare + : public binary_function + { + friend class map; + protected: + key_compare comp; + + value_compare(key_compare c); + public: + bool operator()(const value_type& x, const value_type& y) const; + }; + + // construct/copy/destroy: + map() + noexcept( + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value && + is_nothrow_copy_constructible::value); + explicit map(const key_compare& comp); + map(const key_compare& comp, const allocator_type& a); + template + map(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()); + template + map(InputIterator first, InputIterator last, + const key_compare& comp, const allocator_type& a); + map(const map& m); + map(map&& m) + noexcept( + is_nothrow_move_constructible::value && + is_nothrow_move_constructible::value); + explicit map(const allocator_type& a); + map(const map& m, const allocator_type& a); + map(map&& m, const allocator_type& a); + map(initializer_list il, const key_compare& comp = key_compare()); + map(initializer_list il, const key_compare& comp, const allocator_type& a); + template + map(InputIterator first, InputIterator last, const allocator_type& a) + : map(first, last, Compare(), a) {} // C++14 + map(initializer_list il, const allocator_type& a) + : map(il, Compare(), a) {} // C++14 + ~map(); + + map& operator=(const map& m); + map& operator=(map&& m) + noexcept( + allocator_type::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value); + map& operator=(initializer_list il); + + // iterators: + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + // capacity: + bool empty() const noexcept; + size_type size() const noexcept; + size_type max_size() const noexcept; + + // element access: + mapped_type& operator[](const key_type& k); + mapped_type& operator[](key_type&& k); + + mapped_type& at(const key_type& k); + const mapped_type& at(const key_type& k) const; + + // modifiers: + template + pair emplace(Args&&... args); + template + iterator emplace_hint(const_iterator position, Args&&... args); + pair insert(const value_type& v); + template + pair insert(P&& p); + iterator insert(const_iterator position, const value_type& v); + template + iterator insert(const_iterator position, P&& p); + template + void insert(InputIterator first, InputIterator last); + void insert(initializer_list il); + + template + pair try_emplace(const key_type& k, Args&&... args); // C++17 + template + pair try_emplace(key_type&& k, Args&&... args); // C++17 + template + iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17 + template + iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17 + template + pair insert_or_assign(const key_type& k, M&& obj); // C++17 + template + pair insert_or_assign(key_type&& k, M&& obj); // C++17 + template + iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17 + template + iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17 + + iterator erase(const_iterator position); + iterator erase(iterator position); // C++14 + size_type erase(const key_type& k); + iterator erase(const_iterator first, const_iterator last); + void clear() noexcept; + + void swap(map& m) + noexcept(allocator_traits::is_always_equal::value && + __is_nothrow_swappable::value); // C++17 + + // observers: + allocator_type get_allocator() const noexcept; + key_compare key_comp() const; + value_compare value_comp() const; + + // map operations: + iterator find(const key_type& k); + const_iterator find(const key_type& k) const; + template + iterator find(const K& x); // C++14 + template + const_iterator find(const K& x) const; // C++14 + template + size_type count(const K& x) const; // C++14 + + size_type count(const key_type& k) const; + iterator lower_bound(const key_type& k); + const_iterator lower_bound(const key_type& k) const; + template + iterator lower_bound(const K& x); // C++14 + template + const_iterator lower_bound(const K& x) const; // C++14 + + iterator upper_bound(const key_type& k); + const_iterator upper_bound(const key_type& k) const; + template + iterator upper_bound(const K& x); // C++14 + template + const_iterator upper_bound(const K& x) const; // C++14 + + pair equal_range(const key_type& k); + pair equal_range(const key_type& k) const; + template + pair equal_range(const K& x); // C++14 + template + pair equal_range(const K& x) const; // C++14 +}; + +template +bool +operator==(const map& x, + const map& y); + +template +bool +operator< (const map& x, + const map& y); + +template +bool +operator!=(const map& x, + const map& y); + +template +bool +operator> (const map& x, + const map& y); + +template +bool +operator>=(const map& x, + const map& y); + +template +bool +operator<=(const map& x, + const map& y); + +// specialized algorithms: +template +void +swap(map& x, map& y) + noexcept(noexcept(x.swap(y))); + +template , + class Allocator = allocator>> +class multimap +{ +public: + // types: + typedef Key key_type; + typedef T mapped_type; + typedef pair value_type; + typedef Compare key_compare; + typedef Allocator allocator_type; + typedef typename allocator_type::reference reference; + typedef typename allocator_type::const_reference const_reference; + typedef typename allocator_type::size_type size_type; + typedef typename allocator_type::difference_type difference_type; + typedef typename allocator_type::pointer pointer; + typedef typename allocator_type::const_pointer const_pointer; + + typedef implementation-defined iterator; + typedef implementation-defined const_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + class value_compare + : public binary_function + { + friend class multimap; + protected: + key_compare comp; + value_compare(key_compare c); + public: + bool operator()(const value_type& x, const value_type& y) const; + }; + + // construct/copy/destroy: + multimap() + noexcept( + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value && + is_nothrow_copy_constructible::value); + explicit multimap(const key_compare& comp); + multimap(const key_compare& comp, const allocator_type& a); + template + multimap(InputIterator first, InputIterator last, const key_compare& comp); + template + multimap(InputIterator first, InputIterator last, const key_compare& comp, + const allocator_type& a); + multimap(const multimap& m); + multimap(multimap&& m) + noexcept( + is_nothrow_move_constructible::value && + is_nothrow_move_constructible::value); + explicit multimap(const allocator_type& a); + multimap(const multimap& m, const allocator_type& a); + multimap(multimap&& m, const allocator_type& a); + multimap(initializer_list il, const key_compare& comp = key_compare()); + multimap(initializer_list il, const key_compare& comp, + const allocator_type& a); + template + multimap(InputIterator first, InputIterator last, const allocator_type& a) + : multimap(first, last, Compare(), a) {} // C++14 + multimap(initializer_list il, const allocator_type& a) + : multimap(il, Compare(), a) {} // C++14 + ~multimap(); + + multimap& operator=(const multimap& m); + multimap& operator=(multimap&& m) + noexcept( + allocator_type::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value); + multimap& operator=(initializer_list il); + + // iterators: + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + // capacity: + bool empty() const noexcept; + size_type size() const noexcept; + size_type max_size() const noexcept; + + // modifiers: + template + iterator emplace(Args&&... args); + template + iterator emplace_hint(const_iterator position, Args&&... args); + iterator insert(const value_type& v); + template + iterator insert(P&& p); + iterator insert(const_iterator position, const value_type& v); + template + iterator insert(const_iterator position, P&& p); + template + void insert(InputIterator first, InputIterator last); + void insert(initializer_list il); + + iterator erase(const_iterator position); + iterator erase(iterator position); // C++14 + size_type erase(const key_type& k); + iterator erase(const_iterator first, const_iterator last); + void clear() noexcept; + + void swap(multimap& m) + noexcept(allocator_traits::is_always_equal::value && + __is_nothrow_swappable::value); // C++17 + + // observers: + allocator_type get_allocator() const noexcept; + key_compare key_comp() const; + value_compare value_comp() const; + + // map operations: + iterator find(const key_type& k); + const_iterator find(const key_type& k) const; + template + iterator find(const K& x); // C++14 + template + const_iterator find(const K& x) const; // C++14 + template + size_type count(const K& x) const; // C++14 + + size_type count(const key_type& k) const; + iterator lower_bound(const key_type& k); + const_iterator lower_bound(const key_type& k) const; + template + iterator lower_bound(const K& x); // C++14 + template + const_iterator lower_bound(const K& x) const; // C++14 + + iterator upper_bound(const key_type& k); + const_iterator upper_bound(const key_type& k) const; + template + iterator upper_bound(const K& x); // C++14 + template + const_iterator upper_bound(const K& x) const; // C++14 + + pair equal_range(const key_type& k); + pair equal_range(const key_type& k) const; + template + pair equal_range(const K& x); // C++14 + template + pair equal_range(const K& x) const; // C++14 +}; + +template +bool +operator==(const multimap& x, + const multimap& y); + +template +bool +operator< (const multimap& x, + const multimap& y); + +template +bool +operator!=(const multimap& x, + const multimap& y); + +template +bool +operator> (const multimap& x, + const multimap& y); + +template +bool +operator>=(const multimap& x, + const multimap& y); + +template +bool +operator<=(const multimap& x, + const multimap& y); + +// specialized algorithms: +template +void +swap(multimap& x, + multimap& y) + noexcept(noexcept(x.swap(y))); + +} // std + +*/ + +#include <__config> +#include <__tree> +#include +#include +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template ::value && !__libcpp_is_final<_Compare>::value + > +class __map_value_compare + : private _Compare +{ +public: + _LIBCPP_INLINE_VISIBILITY + __map_value_compare() + _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value) + : _Compare() {} + _LIBCPP_INLINE_VISIBILITY + __map_value_compare(_Compare c) + _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value) + : _Compare(c) {} + _LIBCPP_INLINE_VISIBILITY + const _Compare& key_comp() const _NOEXCEPT {return *this;} + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _CP& __x, const _CP& __y) const + {return static_cast(*this)(__x.__cc.first, __y.__cc.first);} + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _CP& __x, const _Key& __y) const + {return static_cast(*this)(__x.__cc.first, __y);} + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Key& __x, const _CP& __y) const + {return static_cast(*this)(__x, __y.__cc.first);} + void swap(__map_value_compare&__y) + _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value) + { + using _VSTD::swap; + swap(static_cast(*this), static_cast(__y)); + } + +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type + operator () ( const _K2& __x, const _CP& __y ) const + {return static_cast(*this) (__x, __y.__cc.first);} + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type + operator () (const _CP& __x, const _K2& __y) const + {return static_cast(*this) (__x.__cc.first, __y);} +#endif +}; + +template +class __map_value_compare<_Key, _CP, _Compare, false> +{ + _Compare comp; + +public: + _LIBCPP_INLINE_VISIBILITY + __map_value_compare() + _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value) + : comp() {} + _LIBCPP_INLINE_VISIBILITY + __map_value_compare(_Compare c) + _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value) + : comp(c) {} + _LIBCPP_INLINE_VISIBILITY + const _Compare& key_comp() const _NOEXCEPT {return comp;} + + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _CP& __x, const _CP& __y) const + {return comp(__x.__cc.first, __y.__cc.first);} + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _CP& __x, const _Key& __y) const + {return comp(__x.__cc.first, __y);} + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Key& __x, const _CP& __y) const + {return comp(__x, __y.__cc.first);} + void swap(__map_value_compare&__y) + _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value) + { + using _VSTD::swap; + swap(comp, __y.comp); + } + +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type + operator () ( const _K2& __x, const _CP& __y ) const + {return comp (__x, __y.__cc.first);} + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type + operator () (const _CP& __x, const _K2& __y) const + {return comp (__x.__cc.first, __y);} +#endif +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__map_value_compare<_Key, _CP, _Compare, __b>& __x, + __map_value_compare<_Key, _CP, _Compare, __b>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + +template +class __map_node_destructor +{ + typedef _Allocator allocator_type; + typedef allocator_traits __alloc_traits; + typedef typename __alloc_traits::value_type::value_type value_type; +public: + typedef typename __alloc_traits::pointer pointer; +private: + typedef typename value_type::value_type::first_type first_type; + typedef typename value_type::value_type::second_type second_type; + + allocator_type& __na_; + + __map_node_destructor& operator=(const __map_node_destructor&); + +public: + bool __first_constructed; + bool __second_constructed; + + _LIBCPP_INLINE_VISIBILITY + explicit __map_node_destructor(allocator_type& __na) _NOEXCEPT + : __na_(__na), + __first_constructed(false), + __second_constructed(false) + {} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + __map_node_destructor(__tree_node_destructor&& __x) _NOEXCEPT + : __na_(__x.__na_), + __first_constructed(__x.__value_constructed), + __second_constructed(__x.__value_constructed) + { + __x.__value_constructed = false; + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + _LIBCPP_INLINE_VISIBILITY + void operator()(pointer __p) _NOEXCEPT + { + if (__second_constructed) + __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.second)); + if (__first_constructed) + __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.first)); + if (__p) + __alloc_traits::deallocate(__na_, __p, 1); + } +}; + +template + class map; +template + class multimap; +template class __map_const_iterator; + +#if __cplusplus >= 201103L + +template +union __value_type +{ + typedef _Key key_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef pair __nc_value_type; + + value_type __cc; + __nc_value_type __nc; + + template + _LIBCPP_INLINE_VISIBILITY + __value_type(_Args&& ...__args) + : __cc(std::forward<_Args>(__args)...) {} + + _LIBCPP_INLINE_VISIBILITY + __value_type(const __value_type& __v) + : __cc(__v.__cc) {} + + _LIBCPP_INLINE_VISIBILITY + __value_type(__value_type& __v) + : __cc(__v.__cc) {} + + _LIBCPP_INLINE_VISIBILITY + __value_type(__value_type&& __v) + : __nc(std::move(__v.__nc)) {} + + _LIBCPP_INLINE_VISIBILITY + __value_type& operator=(const __value_type& __v) + {__nc = __v.__cc; return *this;} + + _LIBCPP_INLINE_VISIBILITY + __value_type& operator=(__value_type&& __v) + {__nc = std::move(__v.__nc); return *this;} + + _LIBCPP_INLINE_VISIBILITY + ~__value_type() {__cc.~value_type();} +}; + +#else + +template +struct __value_type +{ + typedef _Key key_type; + typedef _Tp mapped_type; + typedef pair value_type; + + value_type __cc; + + _LIBCPP_INLINE_VISIBILITY + __value_type() {} + + template + _LIBCPP_INLINE_VISIBILITY + __value_type(const _A0& __a0) + : __cc(__a0) {} + + template + _LIBCPP_INLINE_VISIBILITY + __value_type(const _A0& __a0, const _A1& __a1) + : __cc(__a0, __a1) {} +}; + +#endif + +template +struct __extract_key_value_types; + +template +struct __extract_key_value_types<__value_type<_Key, _Tp> > +{ + typedef _Key const __key_type; + typedef _Tp __mapped_type; +}; + +template +class _LIBCPP_TYPE_VIS_ONLY __map_iterator +{ + _TreeIterator __i_; + + typedef typename _TreeIterator::__pointer_traits __pointer_traits; + typedef typename _TreeIterator::value_type __value_type; + typedef typename __extract_key_value_types<__value_type>::__key_type __key_type; + typedef typename __extract_key_value_types<__value_type>::__mapped_type __mapped_type; +public: + typedef bidirectional_iterator_tag iterator_category; + typedef pair<__key_type, __mapped_type> value_type; + typedef typename _TreeIterator::difference_type difference_type; + typedef value_type& reference; + typedef typename __pointer_traits::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + pointer; + + _LIBCPP_INLINE_VISIBILITY + __map_iterator() _NOEXCEPT {} + + _LIBCPP_INLINE_VISIBILITY + __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {} + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const {return __i_->__cc;} + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const {return pointer_traits::pointer_to(__i_->__cc);} + + _LIBCPP_INLINE_VISIBILITY + __map_iterator& operator++() {++__i_; return *this;} + _LIBCPP_INLINE_VISIBILITY + __map_iterator operator++(int) + { + __map_iterator __t(*this); + ++(*this); + return __t; + } + + _LIBCPP_INLINE_VISIBILITY + __map_iterator& operator--() {--__i_; return *this;} + _LIBCPP_INLINE_VISIBILITY + __map_iterator operator--(int) + { + __map_iterator __t(*this); + --(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __map_iterator& __x, const __map_iterator& __y) + {return __x.__i_ == __y.__i_;} + friend + _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __map_iterator& __x, const __map_iterator& __y) + {return __x.__i_ != __y.__i_;} + + template friend class _LIBCPP_TYPE_VIS_ONLY map; + template friend class _LIBCPP_TYPE_VIS_ONLY multimap; + template friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator; +}; + +template +class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator +{ + _TreeIterator __i_; + + typedef typename _TreeIterator::__pointer_traits __pointer_traits; + typedef typename _TreeIterator::value_type __value_type; + typedef typename __extract_key_value_types<__value_type>::__key_type __key_type; + typedef typename __extract_key_value_types<__value_type>::__mapped_type __mapped_type; +public: + typedef bidirectional_iterator_tag iterator_category; + typedef pair<__key_type, __mapped_type> value_type; + typedef typename _TreeIterator::difference_type difference_type; + typedef const value_type& reference; + typedef typename __pointer_traits::template +#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES + rebind +#else + rebind::other +#endif + pointer; + + _LIBCPP_INLINE_VISIBILITY + __map_const_iterator() _NOEXCEPT {} + + _LIBCPP_INLINE_VISIBILITY + __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {} + _LIBCPP_INLINE_VISIBILITY + __map_const_iterator(__map_iterator< + typename _TreeIterator::__non_const_iterator> __i) _NOEXCEPT + : __i_(__i.__i_) {} + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const {return __i_->__cc;} + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const {return pointer_traits::pointer_to(__i_->__cc);} + + _LIBCPP_INLINE_VISIBILITY + __map_const_iterator& operator++() {++__i_; return *this;} + _LIBCPP_INLINE_VISIBILITY + __map_const_iterator operator++(int) + { + __map_const_iterator __t(*this); + ++(*this); + return __t; + } + + _LIBCPP_INLINE_VISIBILITY + __map_const_iterator& operator--() {--__i_; return *this;} + _LIBCPP_INLINE_VISIBILITY + __map_const_iterator operator--(int) + { + __map_const_iterator __t(*this); + --(*this); + return __t; + } + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const __map_const_iterator& __x, const __map_const_iterator& __y) + {return __x.__i_ == __y.__i_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y) + {return __x.__i_ != __y.__i_;} + + template friend class _LIBCPP_TYPE_VIS_ONLY map; + template friend class _LIBCPP_TYPE_VIS_ONLY multimap; + template friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator; +}; + +template , + class _Allocator = allocator > > +class _LIBCPP_TYPE_VIS_ONLY map +{ +public: + // types: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef pair __nc_value_type; + typedef _Compare key_compare; + typedef _Allocator allocator_type; + typedef value_type& reference; + typedef const value_type& const_reference; + + class _LIBCPP_TYPE_VIS_ONLY value_compare + : public binary_function + { + friend class map; + protected: + key_compare comp; + + _LIBCPP_INLINE_VISIBILITY value_compare(key_compare c) : comp(c) {} + public: + _LIBCPP_INLINE_VISIBILITY + bool operator()(const value_type& __x, const value_type& __y) const + {return comp(__x.first, __y.first);} + }; + +private: + + typedef _VSTD::__value_type __value_type; + typedef __map_value_compare __vc; + typedef typename __rebind_alloc_helper, + __value_type>::type __allocator_type; + typedef __tree<__value_type, __vc, __allocator_type> __base; + typedef typename __base::__node_traits __node_traits; + typedef allocator_traits __alloc_traits; + + __base __tree_; + +public: + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; + typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::difference_type difference_type; + typedef __map_iterator iterator; + typedef __map_const_iterator const_iterator; + typedef _VSTD::reverse_iterator reverse_iterator; + typedef _VSTD::reverse_iterator const_reverse_iterator; + + _LIBCPP_INLINE_VISIBILITY + map() + _NOEXCEPT_( + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value && + is_nothrow_copy_constructible::value) + : __tree_(__vc(key_compare())) {} + + _LIBCPP_INLINE_VISIBILITY + explicit map(const key_compare& __comp) + _NOEXCEPT_( + is_nothrow_default_constructible::value && + is_nothrow_copy_constructible::value) + : __tree_(__vc(__comp)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit map(const key_compare& __comp, const allocator_type& __a) + : __tree_(__vc(__comp), __a) {} + + template + _LIBCPP_INLINE_VISIBILITY + map(_InputIterator __f, _InputIterator __l, + const key_compare& __comp = key_compare()) + : __tree_(__vc(__comp)) + { + insert(__f, __l); + } + + template + _LIBCPP_INLINE_VISIBILITY + map(_InputIterator __f, _InputIterator __l, + const key_compare& __comp, const allocator_type& __a) + : __tree_(__vc(__comp), __a) + { + insert(__f, __l); + } + +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + map(_InputIterator __f, _InputIterator __l, const allocator_type& __a) + : map(__f, __l, key_compare(), __a) {} +#endif + + _LIBCPP_INLINE_VISIBILITY + map(const map& __m) + : __tree_(__m.__tree_) + { + insert(__m.begin(), __m.end()); + } + + _LIBCPP_INLINE_VISIBILITY + map& operator=(const map& __m) + { +#if __cplusplus >= 201103L + __tree_ = __m.__tree_; +#else + if (this != &__m) { + __tree_.clear(); + __tree_.value_comp() = __m.__tree_.value_comp(); + __tree_.__copy_assign_alloc(__m.__tree_); + insert(__m.begin(), __m.end()); + } +#endif + return *this; + } + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + + _LIBCPP_INLINE_VISIBILITY + map(map&& __m) + _NOEXCEPT_(is_nothrow_move_constructible<__base>::value) + : __tree_(_VSTD::move(__m.__tree_)) + { + } + + map(map&& __m, const allocator_type& __a); + + _LIBCPP_INLINE_VISIBILITY + map& operator=(map&& __m) + _NOEXCEPT_(is_nothrow_move_assignable<__base>::value) + { + __tree_ = _VSTD::move(__m.__tree_); + return *this; + } + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + _LIBCPP_INLINE_VISIBILITY + map(initializer_list __il, const key_compare& __comp = key_compare()) + : __tree_(__vc(__comp)) + { + insert(__il.begin(), __il.end()); + } + + _LIBCPP_INLINE_VISIBILITY + map(initializer_list __il, const key_compare& __comp, const allocator_type& __a) + : __tree_(__vc(__comp), __a) + { + insert(__il.begin(), __il.end()); + } + +#if _LIBCPP_STD_VER > 11 + _LIBCPP_INLINE_VISIBILITY + map(initializer_list __il, const allocator_type& __a) + : map(__il, key_compare(), __a) {} +#endif + + _LIBCPP_INLINE_VISIBILITY + map& operator=(initializer_list __il) + { + __tree_.__assign_unique(__il.begin(), __il.end()); + return *this; + } + +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + _LIBCPP_INLINE_VISIBILITY + explicit map(const allocator_type& __a) + : __tree_(__a) + { + } + + _LIBCPP_INLINE_VISIBILITY + map(const map& __m, const allocator_type& __a) + : __tree_(__m.__tree_.value_comp(), __a) + { + insert(__m.begin(), __m.end()); + } + + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT {return __tree_.begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT {return __tree_.begin();} + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT {return __tree_.end();} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT {return __tree_.end();} + + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rbegin() const _NOEXCEPT + {return const_reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rend() _NOEXCEPT + {return reverse_iterator(begin());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rend() const _NOEXCEPT + {return const_reverse_iterator(begin());} + + _LIBCPP_INLINE_VISIBILITY + const_iterator cbegin() const _NOEXCEPT {return begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator cend() const _NOEXCEPT {return end();} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crend() const _NOEXCEPT {return rend();} + + _LIBCPP_INLINE_VISIBILITY + bool empty() const _NOEXCEPT {return __tree_.size() == 0;} + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT {return __tree_.size();} + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT {return __tree_.max_size();} + + mapped_type& operator[](const key_type& __k); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + mapped_type& operator[](key_type&& __k); +#endif + + mapped_type& at(const key_type& __k); + const mapped_type& at(const key_type& __k) const; + + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();} + _LIBCPP_INLINE_VISIBILITY + key_compare key_comp() const {return __tree_.value_comp().key_comp();} + _LIBCPP_INLINE_VISIBILITY + value_compare value_comp() const {return value_compare(__tree_.value_comp().key_comp());} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + + template + pair + emplace(_Args&& ...__args); + + template + iterator + emplace_hint(const_iterator __p, _Args&& ...__args); + +#endif // _LIBCPP_HAS_NO_VARIADICS + + template ::value>::type> + _LIBCPP_INLINE_VISIBILITY + pair insert(_Pp&& __p) + {return __tree_.__insert_unique(_VSTD::forward<_Pp>(__p));} + + template ::value>::type> + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __pos, _Pp&& __p) + {return __tree_.__insert_unique(__pos.__i_, _VSTD::forward<_Pp>(__p));} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + _LIBCPP_INLINE_VISIBILITY + pair + insert(const value_type& __v) {return __tree_.__insert_unique(__v);} + + _LIBCPP_INLINE_VISIBILITY + iterator + insert(const_iterator __p, const value_type& __v) + {return __tree_.__insert_unique(__p.__i_, __v);} + + template + _LIBCPP_INLINE_VISIBILITY + void insert(_InputIterator __f, _InputIterator __l) + { + for (const_iterator __e = cend(); __f != __l; ++__f) + insert(__e.__i_, *__f); + } + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + _LIBCPP_INLINE_VISIBILITY + void insert(initializer_list __il) + {insert(__il.begin(), __il.end());} + +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +#if _LIBCPP_STD_VER > 14 +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + template + _LIBCPP_INLINE_VISIBILITY + pair try_emplace(const key_type& __k, _Args&&... __args) + { + iterator __p = lower_bound(__k); + if ( __p != end() && !key_comp()(__k, __p->first)) + return _VSTD::make_pair(__p, false); + else + return _VSTD::make_pair( + emplace_hint(__p, + _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)), + true); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair try_emplace(key_type&& __k, _Args&&... __args) + { + iterator __p = lower_bound(__k); + if ( __p != end() && !key_comp()(__k, __p->first)) + return _VSTD::make_pair(__p, false); + else + return _VSTD::make_pair( + emplace_hint(__p, + _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)), + true); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) + { + iterator __p = lower_bound(__k); + if ( __p != end() && !key_comp()(__k, __p->first)) + return __p; + else + return emplace_hint(__p, + _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) + { + iterator __p = lower_bound(__k); + if ( __p != end() && !key_comp()(__k, __p->first)) + return __p; + else + return emplace_hint(__p, + _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair insert_or_assign(const key_type& __k, _Vp&& __v) + { + iterator __p = lower_bound(__k); + if ( __p != end() && !key_comp()(__k, __p->first)) + { + __p->second = _VSTD::forward<_Vp>(__v); + return _VSTD::make_pair(__p, false); + } + return _VSTD::make_pair(emplace_hint(__p, __k, _VSTD::forward<_Vp>(__v)), true); + } + + template + _LIBCPP_INLINE_VISIBILITY + pair insert_or_assign(key_type&& __k, _Vp&& __v) + { + iterator __p = lower_bound(__k); + if ( __p != end() && !key_comp()(__k, __p->first)) + { + __p->second = _VSTD::forward<_Vp>(__v); + return _VSTD::make_pair(__p, false); + } + return _VSTD::make_pair(emplace_hint(__p, _VSTD::move(__k), _VSTD::forward<_Vp>(__v)), true); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator insert_or_assign(const_iterator __h, const key_type& __k, _Vp&& __v) + { + iterator __p = lower_bound(__k); + if ( __p != end() && !key_comp()(__k, __p->first)) + { + __p->second = _VSTD::forward<_Vp>(__v); + return __p; + } + return emplace_hint(__h, __k, _VSTD::forward<_Vp>(__v)); + } + + template + _LIBCPP_INLINE_VISIBILITY + iterator insert_or_assign(const_iterator __h, key_type&& __k, _Vp&& __v) + { + iterator __p = lower_bound(__k); + if ( __p != end() && !key_comp()(__k, __p->first)) + { + __p->second = _VSTD::forward<_Vp>(__v); + return __p; + } + return emplace_hint(__h, _VSTD::move(__k), _VSTD::forward<_Vp>(__v)); + } +#endif +#endif +#endif + + _LIBCPP_INLINE_VISIBILITY + iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);} + _LIBCPP_INLINE_VISIBILITY + iterator erase(iterator __p) {return __tree_.erase(__p.__i_);} + _LIBCPP_INLINE_VISIBILITY + size_type erase(const key_type& __k) + {return __tree_.__erase_unique(__k);} + _LIBCPP_INLINE_VISIBILITY + iterator erase(const_iterator __f, const_iterator __l) + {return __tree_.erase(__f.__i_, __l.__i_);} + _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT {__tree_.clear();} + + _LIBCPP_INLINE_VISIBILITY + void swap(map& __m) + _NOEXCEPT_(__is_nothrow_swappable<__base>::value) + {__tree_.swap(__m.__tree_);} + + _LIBCPP_INLINE_VISIBILITY + iterator find(const key_type& __k) {return __tree_.find(__k);} + _LIBCPP_INLINE_VISIBILITY + const_iterator find(const key_type& __k) const {return __tree_.find(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type + find(const _K2& __k) {return __tree_.find(__k);} + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type + find(const _K2& __k) const {return __tree_.find(__k);} +#endif + + _LIBCPP_INLINE_VISIBILITY + size_type count(const key_type& __k) const + {return __tree_.__count_unique(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type + count(const _K2& __k) const {return __tree_.__count_unique(__k);} +#endif + _LIBCPP_INLINE_VISIBILITY + iterator lower_bound(const key_type& __k) + {return __tree_.lower_bound(__k);} + _LIBCPP_INLINE_VISIBILITY + const_iterator lower_bound(const key_type& __k) const + {return __tree_.lower_bound(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type + lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);} + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type + lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);} +#endif + + _LIBCPP_INLINE_VISIBILITY + iterator upper_bound(const key_type& __k) + {return __tree_.upper_bound(__k);} + _LIBCPP_INLINE_VISIBILITY + const_iterator upper_bound(const key_type& __k) const + {return __tree_.upper_bound(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type + upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);} + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type + upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);} +#endif + + _LIBCPP_INLINE_VISIBILITY + pair equal_range(const key_type& __k) + {return __tree_.__equal_range_unique(__k);} + _LIBCPP_INLINE_VISIBILITY + pair equal_range(const key_type& __k) const + {return __tree_.__equal_range_unique(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,pair>::type + equal_range(const _K2& __k) {return __tree_.__equal_range_unique(__k);} + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,pair>::type + equal_range(const _K2& __k) const {return __tree_.__equal_range_unique(__k);} +#endif + +private: + typedef typename __base::__node __node; + typedef typename __base::__node_allocator __node_allocator; + typedef typename __base::__node_pointer __node_pointer; + typedef typename __base::__node_const_pointer __node_const_pointer; + typedef typename __base::__node_base_pointer __node_base_pointer; + typedef typename __base::__node_base_const_pointer __node_base_const_pointer; + typedef __map_node_destructor<__node_allocator> _Dp; + typedef unique_ptr<__node, _Dp> __node_holder; + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + __node_holder __construct_node(); + template + __node_holder __construct_node(_A0&& __a0); + __node_holder __construct_node_with_key(key_type&& __k); +#ifndef _LIBCPP_HAS_NO_VARIADICS + template + __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args); +#endif // _LIBCPP_HAS_NO_VARIADICS +#endif + __node_holder __construct_node_with_key(const key_type& __k); + + __node_base_pointer& + __find_equal_key(__node_base_pointer& __parent, const key_type& __k); + __node_base_const_pointer + __find_equal_key(__node_base_const_pointer& __parent, const key_type& __k) const; +}; + +// Find place to insert if __k doesn't exist +// Set __parent to parent of null leaf +// Return reference to null leaf +// If __k exists, set parent to node of __k and return reference to node of __k +template +typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_pointer& +map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_pointer& __parent, + const key_type& __k) +{ + __node_pointer __nd = __tree_.__root(); + if (__nd != nullptr) + { + while (true) + { + if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first)) + { + if (__nd->__left_ != nullptr) + __nd = static_cast<__node_pointer>(__nd->__left_); + else + { + __parent = static_cast<__node_base_pointer>(__nd); + return __parent->__left_; + } + } + else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k)) + { + if (__nd->__right_ != nullptr) + __nd = static_cast<__node_pointer>(__nd->__right_); + else + { + __parent = static_cast<__node_base_pointer>(__nd); + return __parent->__right_; + } + } + else + { + __parent = static_cast<__node_base_pointer>(__nd); + return __parent; + } + } + } + __parent = static_cast<__node_base_pointer>(__tree_.__end_node()); + return __parent->__left_; +} + +// Find __k +// Set __parent to parent of null leaf and +// return reference to null leaf iv __k does not exist. +// If __k exists, set parent to node of __k and return reference to node of __k +template +typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_const_pointer +map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_const_pointer& __parent, + const key_type& __k) const +{ + __node_const_pointer __nd = __tree_.__root(); + if (__nd != nullptr) + { + while (true) + { + if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first)) + { + if (__nd->__left_ != nullptr) + __nd = static_cast<__node_pointer>(__nd->__left_); + else + { + __parent = static_cast<__node_base_pointer>(__nd); + return const_cast(__parent->__left_); + } + } + else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k)) + { + if (__nd->__right_ != nullptr) + __nd = static_cast<__node_pointer>(__nd->__right_); + else + { + __parent = static_cast<__node_base_pointer>(__nd); + return const_cast(__parent->__right_); + } + } + else + { + __parent = static_cast<__node_base_pointer>(__nd); + return __parent; + } + } + } + __parent = static_cast<__node_base_pointer>(__tree_.__end_node()); + return const_cast(__parent->__left_); +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a) + : __tree_(_VSTD::move(__m.__tree_), __a) +{ + if (__a != __m.get_allocator()) + { + const_iterator __e = cend(); + while (!__m.empty()) + __tree_.__insert_unique(__e.__i_, + _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_)); + } +} + +template +typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder +map<_Key, _Tp, _Compare, _Allocator>::__construct_node() +{ + __node_allocator& __na = __tree_.__node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first)); + __h.get_deleter().__first_constructed = true; + __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); + __h.get_deleter().__second_constructed = true; + return __h; +} + +template +template +typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder +map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0) +{ + __node_allocator& __na = __tree_.__node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_A0>(__a0)); + __h.get_deleter().__first_constructed = true; + __h.get_deleter().__second_constructed = true; + return __h; +} + +template +typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder +map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(key_type&& __k) +{ + __node_allocator& __na = __tree_.__node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), _VSTD::move(__k)); + __h.get_deleter().__first_constructed = true; + __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); + __h.get_deleter().__second_constructed = true; + return __h; +} + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +template +template +typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder +map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args) +{ + __node_allocator& __na = __tree_.__node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_), + _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1), + _VSTD::forward<_Args>(__args)...); + __h.get_deleter().__first_constructed = true; + __h.get_deleter().__second_constructed = true; + return __h; +} + +#endif // _LIBCPP_HAS_NO_VARIADICS + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder +map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k) +{ + __node_allocator& __na = __tree_.__node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), __k); + __h.get_deleter().__first_constructed = true; + __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); + __h.get_deleter().__second_constructed = true; + return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 +} + +template +_Tp& +map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) +{ + __node_base_pointer __parent; + __node_base_pointer& __child = __find_equal_key(__parent, __k); + __node_pointer __r = static_cast<__node_pointer>(__child); + if (__child == nullptr) + { + __node_holder __h = __construct_node_with_key(__k); + __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + __r = __h.release(); + } + return __r->__value_.__cc.second; +} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +_Tp& +map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k) +{ + __node_base_pointer __parent; + __node_base_pointer& __child = __find_equal_key(__parent, __k); + __node_pointer __r = static_cast<__node_pointer>(__child); + if (__child == nullptr) + { + __node_holder __h = __construct_node_with_key(_VSTD::move(__k)); + __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + __r = __h.release(); + } + return __r->__value_.__cc.second; +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +_Tp& +map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) +{ + __node_base_pointer __parent; + __node_base_pointer& __child = __find_equal_key(__parent, __k); +#ifndef _LIBCPP_NO_EXCEPTIONS + if (__child == nullptr) + throw out_of_range("map::at: key not found"); +#endif // _LIBCPP_NO_EXCEPTIONS + return static_cast<__node_pointer>(__child)->__value_.__cc.second; +} + +template +const _Tp& +map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const +{ + __node_base_const_pointer __parent; + __node_base_const_pointer __child = __find_equal_key(__parent, __k); +#ifndef _LIBCPP_NO_EXCEPTIONS + if (__child == nullptr) + throw out_of_range("map::at: key not found"); +#endif // _LIBCPP_NO_EXCEPTIONS + return static_cast<__node_const_pointer>(__child)->__value_.__cc.second; +} + +#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) + +template +template +pair::iterator, bool> +map<_Key, _Tp, _Compare, _Allocator>::emplace(_Args&& ...__args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + pair __r = __tree_.__node_insert_unique(__h.get()); + if (__r.second) + __h.release(); + return __r; +} + +template +template +typename map<_Key, _Tp, _Compare, _Allocator>::iterator +map<_Key, _Tp, _Compare, _Allocator>::emplace_hint(const_iterator __p, + _Args&& ...__args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + iterator __r = __tree_.__node_insert_unique(__p.__i_, __h.get()); + if (__r.__i_.__ptr_ == __h.get()) + __h.release(); + return __r; +} + +#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x, + const map<_Key, _Tp, _Compare, _Allocator>& __y) +{ + return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator< (const map<_Key, _Tp, _Compare, _Allocator>& __x, + const map<_Key, _Tp, _Compare, _Allocator>& __y) +{ + return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __x, + const map<_Key, _Tp, _Compare, _Allocator>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator> (const map<_Key, _Tp, _Compare, _Allocator>& __x, + const map<_Key, _Tp, _Compare, _Allocator>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __x, + const map<_Key, _Tp, _Compare, _Allocator>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x, + const map<_Key, _Tp, _Compare, _Allocator>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(map<_Key, _Tp, _Compare, _Allocator>& __x, + map<_Key, _Tp, _Compare, _Allocator>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + +template , + class _Allocator = allocator > > +class _LIBCPP_TYPE_VIS_ONLY multimap +{ +public: + // types: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef pair __nc_value_type; + typedef _Compare key_compare; + typedef _Allocator allocator_type; + typedef value_type& reference; + typedef const value_type& const_reference; + + class _LIBCPP_TYPE_VIS_ONLY value_compare + : public binary_function + { + friend class multimap; + protected: + key_compare comp; + + _LIBCPP_INLINE_VISIBILITY + value_compare(key_compare c) : comp(c) {} + public: + _LIBCPP_INLINE_VISIBILITY + bool operator()(const value_type& __x, const value_type& __y) const + {return comp(__x.first, __y.first);} + }; + +private: + + typedef _VSTD::__value_type __value_type; + typedef __map_value_compare __vc; + typedef typename __rebind_alloc_helper, + __value_type>::type __allocator_type; + typedef __tree<__value_type, __vc, __allocator_type> __base; + typedef typename __base::__node_traits __node_traits; + typedef allocator_traits __alloc_traits; + + __base __tree_; + +public: + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; + typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::difference_type difference_type; + typedef __map_iterator iterator; + typedef __map_const_iterator const_iterator; + typedef _VSTD::reverse_iterator reverse_iterator; + typedef _VSTD::reverse_iterator const_reverse_iterator; + + _LIBCPP_INLINE_VISIBILITY + multimap() + _NOEXCEPT_( + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value && + is_nothrow_copy_constructible::value) + : __tree_(__vc(key_compare())) {} + + _LIBCPP_INLINE_VISIBILITY + explicit multimap(const key_compare& __comp) + _NOEXCEPT_( + is_nothrow_default_constructible::value && + is_nothrow_copy_constructible::value) + : __tree_(__vc(__comp)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit multimap(const key_compare& __comp, const allocator_type& __a) + : __tree_(__vc(__comp), __a) {} + + template + _LIBCPP_INLINE_VISIBILITY + multimap(_InputIterator __f, _InputIterator __l, + const key_compare& __comp = key_compare()) + : __tree_(__vc(__comp)) + { + insert(__f, __l); + } + + template + _LIBCPP_INLINE_VISIBILITY + multimap(_InputIterator __f, _InputIterator __l, + const key_compare& __comp, const allocator_type& __a) + : __tree_(__vc(__comp), __a) + { + insert(__f, __l); + } + +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a) + : multimap(__f, __l, key_compare(), __a) {} +#endif + + _LIBCPP_INLINE_VISIBILITY + multimap(const multimap& __m) + : __tree_(__m.__tree_.value_comp(), + __alloc_traits::select_on_container_copy_construction(__m.__tree_.__alloc())) + { + insert(__m.begin(), __m.end()); + } + + _LIBCPP_INLINE_VISIBILITY + multimap& operator=(const multimap& __m) + { +#if __cplusplus >= 201103L + __tree_ = __m.__tree_; +#else + if (this != &__m) { + __tree_.clear(); + __tree_.value_comp() = __m.__tree_.value_comp(); + __tree_.__copy_assign_alloc(__m.__tree_); + insert(__m.begin(), __m.end()); + } +#endif + return *this; + } + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + + _LIBCPP_INLINE_VISIBILITY + multimap(multimap&& __m) + _NOEXCEPT_(is_nothrow_move_constructible<__base>::value) + : __tree_(_VSTD::move(__m.__tree_)) + { + } + + multimap(multimap&& __m, const allocator_type& __a); + + _LIBCPP_INLINE_VISIBILITY + multimap& operator=(multimap&& __m) + _NOEXCEPT_(is_nothrow_move_assignable<__base>::value) + { + __tree_ = _VSTD::move(__m.__tree_); + return *this; + } + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + _LIBCPP_INLINE_VISIBILITY + multimap(initializer_list __il, const key_compare& __comp = key_compare()) + : __tree_(__vc(__comp)) + { + insert(__il.begin(), __il.end()); + } + + _LIBCPP_INLINE_VISIBILITY + multimap(initializer_list __il, const key_compare& __comp, const allocator_type& __a) + : __tree_(__vc(__comp), __a) + { + insert(__il.begin(), __il.end()); + } + +#if _LIBCPP_STD_VER > 11 + _LIBCPP_INLINE_VISIBILITY + multimap(initializer_list __il, const allocator_type& __a) + : multimap(__il, key_compare(), __a) {} +#endif + + _LIBCPP_INLINE_VISIBILITY + multimap& operator=(initializer_list __il) + { + __tree_.__assign_multi(__il.begin(), __il.end()); + return *this; + } + +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + _LIBCPP_INLINE_VISIBILITY + explicit multimap(const allocator_type& __a) + : __tree_(__a) + { + } + + _LIBCPP_INLINE_VISIBILITY + multimap(const multimap& __m, const allocator_type& __a) + : __tree_(__m.__tree_.value_comp(), __a) + { + insert(__m.begin(), __m.end()); + } + + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT {return __tree_.begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT {return __tree_.begin();} + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT {return __tree_.end();} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT {return __tree_.end();} + + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rbegin() const _NOEXCEPT + {return const_reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rend() const _NOEXCEPT + {return const_reverse_iterator(begin());} + + _LIBCPP_INLINE_VISIBILITY + const_iterator cbegin() const _NOEXCEPT {return begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator cend() const _NOEXCEPT {return end();} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crend() const _NOEXCEPT {return rend();} + + _LIBCPP_INLINE_VISIBILITY + bool empty() const _NOEXCEPT {return __tree_.size() == 0;} + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT {return __tree_.size();} + _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT {return __tree_.max_size();} + + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();} + _LIBCPP_INLINE_VISIBILITY + key_compare key_comp() const {return __tree_.value_comp().key_comp();} + _LIBCPP_INLINE_VISIBILITY + value_compare value_comp() const + {return value_compare(__tree_.value_comp().key_comp());} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + + template + iterator + emplace(_Args&& ...__args); + + template + iterator + emplace_hint(const_iterator __p, _Args&& ...__args); + +#endif // _LIBCPP_HAS_NO_VARIADICS + + template ::value>::type> + _LIBCPP_INLINE_VISIBILITY + iterator insert(_Pp&& __p) + {return __tree_.__insert_multi(_VSTD::forward<_Pp>(__p));} + + template ::value>::type> + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __pos, _Pp&& __p) + {return __tree_.__insert_multi(__pos.__i_, _VSTD::forward<_Pp>(__p));} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + + _LIBCPP_INLINE_VISIBILITY + iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);} + + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __p, const value_type& __v) + {return __tree_.__insert_multi(__p.__i_, __v);} + + template + _LIBCPP_INLINE_VISIBILITY + void insert(_InputIterator __f, _InputIterator __l) + { + for (const_iterator __e = cend(); __f != __l; ++__f) + __tree_.__insert_multi(__e.__i_, *__f); + } + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + _LIBCPP_INLINE_VISIBILITY + void insert(initializer_list __il) + {insert(__il.begin(), __il.end());} + +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + _LIBCPP_INLINE_VISIBILITY + iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);} + _LIBCPP_INLINE_VISIBILITY + iterator erase(iterator __p) {return __tree_.erase(__p.__i_);} + _LIBCPP_INLINE_VISIBILITY + size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);} + _LIBCPP_INLINE_VISIBILITY + iterator erase(const_iterator __f, const_iterator __l) + {return __tree_.erase(__f.__i_, __l.__i_);} + _LIBCPP_INLINE_VISIBILITY + void clear() {__tree_.clear();} + + _LIBCPP_INLINE_VISIBILITY + void swap(multimap& __m) + _NOEXCEPT_(__is_nothrow_swappable<__base>::value) + {__tree_.swap(__m.__tree_);} + + _LIBCPP_INLINE_VISIBILITY + iterator find(const key_type& __k) {return __tree_.find(__k);} + _LIBCPP_INLINE_VISIBILITY + const_iterator find(const key_type& __k) const {return __tree_.find(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type + find(const _K2& __k) {return __tree_.find(__k);} + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type + find(const _K2& __k) const {return __tree_.find(__k);} +#endif + + _LIBCPP_INLINE_VISIBILITY + size_type count(const key_type& __k) const + {return __tree_.__count_multi(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type + count(const _K2& __k) const {return __tree_.__count_multi(__k);} +#endif + _LIBCPP_INLINE_VISIBILITY + iterator lower_bound(const key_type& __k) + {return __tree_.lower_bound(__k);} + _LIBCPP_INLINE_VISIBILITY + const_iterator lower_bound(const key_type& __k) const + {return __tree_.lower_bound(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type + lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);} + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type + lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);} +#endif + + _LIBCPP_INLINE_VISIBILITY + iterator upper_bound(const key_type& __k) + {return __tree_.upper_bound(__k);} + _LIBCPP_INLINE_VISIBILITY + const_iterator upper_bound(const key_type& __k) const + {return __tree_.upper_bound(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type + upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);} + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type + upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);} +#endif + + _LIBCPP_INLINE_VISIBILITY + pair equal_range(const key_type& __k) + {return __tree_.__equal_range_multi(__k);} + _LIBCPP_INLINE_VISIBILITY + pair equal_range(const key_type& __k) const + {return __tree_.__equal_range_multi(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,pair>::type + equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);} + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,pair>::type + equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);} +#endif + +private: + typedef typename __base::__node __node; + typedef typename __base::__node_allocator __node_allocator; + typedef typename __base::__node_pointer __node_pointer; + typedef typename __base::__node_const_pointer __node_const_pointer; + typedef __map_node_destructor<__node_allocator> _Dp; + typedef unique_ptr<__node, _Dp> __node_holder; + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + __node_holder __construct_node(); + template + __node_holder + __construct_node(_A0&& __a0); +#ifndef _LIBCPP_HAS_NO_VARIADICS + template + __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args); +#endif // _LIBCPP_HAS_NO_VARIADICS +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +}; + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a) + : __tree_(_VSTD::move(__m.__tree_), __a) +{ + if (__a != __m.get_allocator()) + { + const_iterator __e = cend(); + while (!__m.empty()) + __tree_.__insert_multi(__e.__i_, + _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_)); + } +} + +template +typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder +multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node() +{ + __node_allocator& __na = __tree_.__node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first)); + __h.get_deleter().__first_constructed = true; + __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); + __h.get_deleter().__second_constructed = true; + return __h; +} + +template +template +typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder +multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0) +{ + __node_allocator& __na = __tree_.__node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_A0>(__a0)); + __h.get_deleter().__first_constructed = true; + __h.get_deleter().__second_constructed = true; + return __h; +} + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +template +template +typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder +multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args) +{ + __node_allocator& __na = __tree_.__node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_), + _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1), + _VSTD::forward<_Args>(__args)...); + __h.get_deleter().__first_constructed = true; + __h.get_deleter().__second_constructed = true; + return __h; +} + +#endif // _LIBCPP_HAS_NO_VARIADICS +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) + +template +template +typename multimap<_Key, _Tp, _Compare, _Allocator>::iterator +multimap<_Key, _Tp, _Compare, _Allocator>::emplace(_Args&& ...__args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + iterator __r = __tree_.__node_insert_multi(__h.get()); + __h.release(); + return __r; +} + +template +template +typename multimap<_Key, _Tp, _Compare, _Allocator>::iterator +multimap<_Key, _Tp, _Compare, _Allocator>::emplace_hint(const_iterator __p, + _Args&& ...__args) +{ + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); + iterator __r = __tree_.__node_insert_multi(__p.__i_, __h.get()); + __h.release(); + return __r; +} + +#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, + const multimap<_Key, _Tp, _Compare, _Allocator>& __y) +{ + return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator< (const multimap<_Key, _Tp, _Compare, _Allocator>& __x, + const multimap<_Key, _Tp, _Compare, _Allocator>& __y) +{ + return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, + const multimap<_Key, _Tp, _Compare, _Allocator>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator> (const multimap<_Key, _Tp, _Compare, _Allocator>& __x, + const multimap<_Key, _Tp, _Compare, _Allocator>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, + const multimap<_Key, _Tp, _Compare, _Allocator>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, + const multimap<_Key, _Tp, _Compare, _Allocator>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x, + multimap<_Key, _Tp, _Compare, _Allocator>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_MAP diff --git a/headers/libs/libc++/math.h b/headers/libs/libc++/math.h new file mode 100644 index 0000000000..20205544d5 --- /dev/null +++ b/headers/libs/libc++/math.h @@ -0,0 +1,1419 @@ +// -*- C++ -*- +//===---------------------------- math.h ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_MATH_H +#define _LIBCPP_MATH_H + +/* + math.h synopsis + +Macros: + + HUGE_VAL + HUGE_VALF // C99 + HUGE_VALL // C99 + INFINITY // C99 + NAN // C99 + FP_INFINITE // C99 + FP_NAN // C99 + FP_NORMAL // C99 + FP_SUBNORMAL // C99 + FP_ZERO // C99 + FP_FAST_FMA // C99 + FP_FAST_FMAF // C99 + FP_FAST_FMAL // C99 + FP_ILOGB0 // C99 + FP_ILOGBNAN // C99 + MATH_ERRNO // C99 + MATH_ERREXCEPT // C99 + math_errhandling // C99 + +Types: + + float_t // C99 + double_t // C99 + +// C90 + +floating_point abs(floating_point x); + +floating_point acos (arithmetic x); +float acosf(float x); +long double acosl(long double x); + +floating_point asin (arithmetic x); +float asinf(float x); +long double asinl(long double x); + +floating_point atan (arithmetic x); +float atanf(float x); +long double atanl(long double x); + +floating_point atan2 (arithmetic y, arithmetic x); +float atan2f(float y, float x); +long double atan2l(long double y, long double x); + +floating_point ceil (arithmetic x); +float ceilf(float x); +long double ceill(long double x); + +floating_point cos (arithmetic x); +float cosf(float x); +long double cosl(long double x); + +floating_point cosh (arithmetic x); +float coshf(float x); +long double coshl(long double x); + +floating_point exp (arithmetic x); +float expf(float x); +long double expl(long double x); + +floating_point fabs (arithmetic x); +float fabsf(float x); +long double fabsl(long double x); + +floating_point floor (arithmetic x); +float floorf(float x); +long double floorl(long double x); + +floating_point fmod (arithmetic x, arithmetic y); +float fmodf(float x, float y); +long double fmodl(long double x, long double y); + +floating_point frexp (arithmetic value, int* exp); +float frexpf(float value, int* exp); +long double frexpl(long double value, int* exp); + +floating_point ldexp (arithmetic value, int exp); +float ldexpf(float value, int exp); +long double ldexpl(long double value, int exp); + +floating_point log (arithmetic x); +float logf(float x); +long double logl(long double x); + +floating_point log10 (arithmetic x); +float log10f(float x); +long double log10l(long double x); + +floating_point modf (floating_point value, floating_point* iptr); +float modff(float value, float* iptr); +long double modfl(long double value, long double* iptr); + +floating_point pow (arithmetic x, arithmetic y); +float powf(float x, float y); +long double powl(long double x, long double y); + +floating_point sin (arithmetic x); +float sinf(float x); +long double sinl(long double x); + +floating_point sinh (arithmetic x); +float sinhf(float x); +long double sinhl(long double x); + +floating_point sqrt (arithmetic x); +float sqrtf(float x); +long double sqrtl(long double x); + +floating_point tan (arithmetic x); +float tanf(float x); +long double tanl(long double x); + +floating_point tanh (arithmetic x); +float tanhf(float x); +long double tanhl(long double x); + +// C99 + +bool signbit(arithmetic x); + +int fpclassify(arithmetic x); + +bool isfinite(arithmetic x); +bool isinf(arithmetic x); +bool isnan(arithmetic x); +bool isnormal(arithmetic x); + +bool isgreater(arithmetic x, arithmetic y); +bool isgreaterequal(arithmetic x, arithmetic y); +bool isless(arithmetic x, arithmetic y); +bool islessequal(arithmetic x, arithmetic y); +bool islessgreater(arithmetic x, arithmetic y); +bool isunordered(arithmetic x, arithmetic y); + +floating_point acosh (arithmetic x); +float acoshf(float x); +long double acoshl(long double x); + +floating_point asinh (arithmetic x); +float asinhf(float x); +long double asinhl(long double x); + +floating_point atanh (arithmetic x); +float atanhf(float x); +long double atanhl(long double x); + +floating_point cbrt (arithmetic x); +float cbrtf(float x); +long double cbrtl(long double x); + +floating_point copysign (arithmetic x, arithmetic y); +float copysignf(float x, float y); +long double copysignl(long double x, long double y); + +floating_point erf (arithmetic x); +float erff(float x); +long double erfl(long double x); + +floating_point erfc (arithmetic x); +float erfcf(float x); +long double erfcl(long double x); + +floating_point exp2 (arithmetic x); +float exp2f(float x); +long double exp2l(long double x); + +floating_point expm1 (arithmetic x); +float expm1f(float x); +long double expm1l(long double x); + +floating_point fdim (arithmetic x, arithmetic y); +float fdimf(float x, float y); +long double fdiml(long double x, long double y); + +floating_point fma (arithmetic x, arithmetic y, arithmetic z); +float fmaf(float x, float y, float z); +long double fmal(long double x, long double y, long double z); + +floating_point fmax (arithmetic x, arithmetic y); +float fmaxf(float x, float y); +long double fmaxl(long double x, long double y); + +floating_point fmin (arithmetic x, arithmetic y); +float fminf(float x, float y); +long double fminl(long double x, long double y); + +floating_point hypot (arithmetic x, arithmetic y); +float hypotf(float x, float y); +long double hypotl(long double x, long double y); + +int ilogb (arithmetic x); +int ilogbf(float x); +int ilogbl(long double x); + +floating_point lgamma (arithmetic x); +float lgammaf(float x); +long double lgammal(long double x); + +long long llrint (arithmetic x); +long long llrintf(float x); +long long llrintl(long double x); + +long long llround (arithmetic x); +long long llroundf(float x); +long long llroundl(long double x); + +floating_point log1p (arithmetic x); +float log1pf(float x); +long double log1pl(long double x); + +floating_point log2 (arithmetic x); +float log2f(float x); +long double log2l(long double x); + +floating_point logb (arithmetic x); +float logbf(float x); +long double logbl(long double x); + +long lrint (arithmetic x); +long lrintf(float x); +long lrintl(long double x); + +long lround (arithmetic x); +long lroundf(float x); +long lroundl(long double x); + +double nan (const char* str); +float nanf(const char* str); +long double nanl(const char* str); + +floating_point nearbyint (arithmetic x); +float nearbyintf(float x); +long double nearbyintl(long double x); + +floating_point nextafter (arithmetic x, arithmetic y); +float nextafterf(float x, float y); +long double nextafterl(long double x, long double y); + +floating_point nexttoward (arithmetic x, long double y); +float nexttowardf(float x, long double y); +long double nexttowardl(long double x, long double y); + +floating_point remainder (arithmetic x, arithmetic y); +float remainderf(float x, float y); +long double remainderl(long double x, long double y); + +floating_point remquo (arithmetic x, arithmetic y, int* pquo); +float remquof(float x, float y, int* pquo); +long double remquol(long double x, long double y, int* pquo); + +floating_point rint (arithmetic x); +float rintf(float x); +long double rintl(long double x); + +floating_point round (arithmetic x); +float roundf(float x); +long double roundl(long double x); + +floating_point scalbln (arithmetic x, long ex); +float scalblnf(float x, long ex); +long double scalblnl(long double x, long ex); + +floating_point scalbn (arithmetic x, int ex); +float scalbnf(float x, int ex); +long double scalbnl(long double x, int ex); + +floating_point tgamma (arithmetic x); +float tgammaf(float x); +long double tgammal(long double x); + +floating_point trunc (arithmetic x); +float truncf(float x); +long double truncl(long double x); + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#include_next + +#ifdef __cplusplus + +// We support including .h headers inside 'extern "C"' contexts, so switch +// back to C++ linkage before including these C++ headers. +extern "C++" { + +#include + +#ifdef _LIBCPP_MSVCRT +#include "support/win32/math_win32.h" +#endif + +// signbit + +#ifdef signbit + +template +_LIBCPP_ALWAYS_INLINE +bool +__libcpp_signbit(_A1 __lcpp_x) _NOEXCEPT +{ + return signbit(__lcpp_x); +} + +#undef signbit + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, bool>::type +signbit(_A1 __lcpp_x) _NOEXCEPT +{ + return __libcpp_signbit((typename std::__promote<_A1>::type)__lcpp_x); +} + +#endif // signbit + +// fpclassify + +#ifdef fpclassify + +template +_LIBCPP_ALWAYS_INLINE +int +__libcpp_fpclassify(_A1 __lcpp_x) _NOEXCEPT +{ + return fpclassify(__lcpp_x); +} + +#undef fpclassify + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, int>::type +fpclassify(_A1 __lcpp_x) _NOEXCEPT +{ + return __libcpp_fpclassify((typename std::__promote<_A1>::type)__lcpp_x); +} + +#endif // fpclassify + +// isfinite + +#ifdef isfinite + +template +_LIBCPP_ALWAYS_INLINE +bool +__libcpp_isfinite(_A1 __lcpp_x) _NOEXCEPT +{ + return isfinite(__lcpp_x); +} + +#undef isfinite + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, bool>::type +isfinite(_A1 __lcpp_x) _NOEXCEPT +{ + return __libcpp_isfinite((typename std::__promote<_A1>::type)__lcpp_x); +} + +#endif // isfinite + +// isinf + +#ifdef isinf + +template +_LIBCPP_ALWAYS_INLINE +bool +__libcpp_isinf(_A1 __lcpp_x) _NOEXCEPT +{ + return isinf(__lcpp_x); +} + +#undef isinf + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, bool>::type +isinf(_A1 __lcpp_x) _NOEXCEPT +{ + return __libcpp_isinf((typename std::__promote<_A1>::type)__lcpp_x); +} + +#endif // isinf + +// isnan + +#ifdef isnan + +template +_LIBCPP_ALWAYS_INLINE +bool +__libcpp_isnan(_A1 __lcpp_x) _NOEXCEPT +{ + return isnan(__lcpp_x); +} + +#undef isnan + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, bool>::type +isnan(_A1 __lcpp_x) _NOEXCEPT +{ + return __libcpp_isnan((typename std::__promote<_A1>::type)__lcpp_x); +} + +#endif // isnan + +// isnormal + +#ifdef isnormal + +template +_LIBCPP_ALWAYS_INLINE +bool +__libcpp_isnormal(_A1 __lcpp_x) _NOEXCEPT +{ + return isnormal(__lcpp_x); +} + +#undef isnormal + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, bool>::type +isnormal(_A1 __lcpp_x) _NOEXCEPT +{ + return __libcpp_isnormal((typename std::__promote<_A1>::type)__lcpp_x); +} + +#endif // isnormal + +// isgreater + +#ifdef isgreater + +template +_LIBCPP_ALWAYS_INLINE +bool +__libcpp_isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + return isgreater(__lcpp_x, __lcpp_y); +} + +#undef isgreater + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + bool +>::type +isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type type; + return __libcpp_isgreater((type)__lcpp_x, (type)__lcpp_y); +} + +#endif // isgreater + +// isgreaterequal + +#ifdef isgreaterequal + +template +_LIBCPP_ALWAYS_INLINE +bool +__libcpp_isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + return isgreaterequal(__lcpp_x, __lcpp_y); +} + +#undef isgreaterequal + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + bool +>::type +isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type type; + return __libcpp_isgreaterequal((type)__lcpp_x, (type)__lcpp_y); +} + +#endif // isgreaterequal + +// isless + +#ifdef isless + +template +_LIBCPP_ALWAYS_INLINE +bool +__libcpp_isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + return isless(__lcpp_x, __lcpp_y); +} + +#undef isless + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + bool +>::type +isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type type; + return __libcpp_isless((type)__lcpp_x, (type)__lcpp_y); +} + +#endif // isless + +// islessequal + +#ifdef islessequal + +template +_LIBCPP_ALWAYS_INLINE +bool +__libcpp_islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + return islessequal(__lcpp_x, __lcpp_y); +} + +#undef islessequal + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + bool +>::type +islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type type; + return __libcpp_islessequal((type)__lcpp_x, (type)__lcpp_y); +} + +#endif // islessequal + +// islessgreater + +#ifdef islessgreater + +template +_LIBCPP_ALWAYS_INLINE +bool +__libcpp_islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + return islessgreater(__lcpp_x, __lcpp_y); +} + +#undef islessgreater + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + bool +>::type +islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type type; + return __libcpp_islessgreater((type)__lcpp_x, (type)__lcpp_y); +} + +#endif // islessgreater + +// isunordered + +#ifdef isunordered + +template +_LIBCPP_ALWAYS_INLINE +bool +__libcpp_isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + return isunordered(__lcpp_x, __lcpp_y); +} + +#undef isunordered + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + bool +>::type +isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type type; + return __libcpp_isunordered((type)__lcpp_x, (type)__lcpp_y); +} + +#endif // isunordered + +#ifndef __sun__ + +// abs + +#if !defined(_AIX) +inline _LIBCPP_INLINE_VISIBILITY +float +abs(float __lcpp_x) _NOEXCEPT {return fabsf(__lcpp_x);} + +inline _LIBCPP_INLINE_VISIBILITY +double +abs(double __lcpp_x) _NOEXCEPT {return fabs(__lcpp_x);} + +inline _LIBCPP_INLINE_VISIBILITY +long double +abs(long double __lcpp_x) _NOEXCEPT {return fabsl(__lcpp_x);} +#endif // !defined(_AIX) + +// acos + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float acos(float __lcpp_x) _NOEXCEPT {return acosf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double acos(long double __lcpp_x) _NOEXCEPT {return acosl(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +acos(_A1 __lcpp_x) _NOEXCEPT {return acos((double)__lcpp_x);} + +// asin + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float asin(float __lcpp_x) _NOEXCEPT {return asinf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double asin(long double __lcpp_x) _NOEXCEPT {return asinl(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +asin(_A1 __lcpp_x) _NOEXCEPT {return asin((double)__lcpp_x);} + +// atan + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float atan(float __lcpp_x) _NOEXCEPT {return atanf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double atan(long double __lcpp_x) _NOEXCEPT {return atanl(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +atan(_A1 __lcpp_x) _NOEXCEPT {return atan((double)__lcpp_x);} + +// atan2 + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float atan2(float __lcpp_y, float __lcpp_x) _NOEXCEPT {return atan2f(__lcpp_y, __lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double atan2(long double __lcpp_y, long double __lcpp_x) _NOEXCEPT {return atan2l(__lcpp_y, __lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::__lazy_enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + std::__promote<_A1, _A2> +>::type +atan2(_A1 __lcpp_y, _A2 __lcpp_x) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type __result_type; + static_assert((!(std::is_same<_A1, __result_type>::value && + std::is_same<_A2, __result_type>::value)), ""); + return atan2((__result_type)__lcpp_y, (__result_type)__lcpp_x); +} + +// ceil + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float ceil(float __lcpp_x) _NOEXCEPT {return ceilf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double ceil(long double __lcpp_x) _NOEXCEPT {return ceill(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +ceil(_A1 __lcpp_x) _NOEXCEPT {return ceil((double)__lcpp_x);} + +// cos + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float cos(float __lcpp_x) _NOEXCEPT {return cosf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double cos(long double __lcpp_x) _NOEXCEPT {return cosl(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +cos(_A1 __lcpp_x) _NOEXCEPT {return cos((double)__lcpp_x);} + +// cosh + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float cosh(float __lcpp_x) _NOEXCEPT {return coshf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double cosh(long double __lcpp_x) _NOEXCEPT {return coshl(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +cosh(_A1 __lcpp_x) _NOEXCEPT {return cosh((double)__lcpp_x);} + +// exp + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float exp(float __lcpp_x) _NOEXCEPT {return expf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double exp(long double __lcpp_x) _NOEXCEPT {return expl(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +exp(_A1 __lcpp_x) _NOEXCEPT {return exp((double)__lcpp_x);} + +// fabs + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float fabs(float __lcpp_x) _NOEXCEPT {return fabsf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double fabs(long double __lcpp_x) _NOEXCEPT {return fabsl(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +fabs(_A1 __lcpp_x) _NOEXCEPT {return fabs((double)__lcpp_x);} + +// floor + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float floor(float __lcpp_x) _NOEXCEPT {return floorf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double floor(long double __lcpp_x) _NOEXCEPT {return floorl(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +floor(_A1 __lcpp_x) _NOEXCEPT {return floor((double)__lcpp_x);} + +// fmod + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float fmod(float __lcpp_x, float __lcpp_y) _NOEXCEPT {return fmodf(__lcpp_x, __lcpp_y);} +inline _LIBCPP_INLINE_VISIBILITY long double fmod(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fmodl(__lcpp_x, __lcpp_y);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::__lazy_enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + std::__promote<_A1, _A2> +>::type +fmod(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type __result_type; + static_assert((!(std::is_same<_A1, __result_type>::value && + std::is_same<_A2, __result_type>::value)), ""); + return fmod((__result_type)__lcpp_x, (__result_type)__lcpp_y); +} + +// frexp + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float frexp(float __lcpp_x, int* __lcpp_e) _NOEXCEPT {return frexpf(__lcpp_x, __lcpp_e);} +inline _LIBCPP_INLINE_VISIBILITY long double frexp(long double __lcpp_x, int* __lcpp_e) _NOEXCEPT {return frexpl(__lcpp_x, __lcpp_e);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +frexp(_A1 __lcpp_x, int* __lcpp_e) _NOEXCEPT {return frexp((double)__lcpp_x, __lcpp_e);} + +// ldexp + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float ldexp(float __lcpp_x, int __lcpp_e) _NOEXCEPT {return ldexpf(__lcpp_x, __lcpp_e);} +inline _LIBCPP_INLINE_VISIBILITY long double ldexp(long double __lcpp_x, int __lcpp_e) _NOEXCEPT {return ldexpl(__lcpp_x, __lcpp_e);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +ldexp(_A1 __lcpp_x, int __lcpp_e) _NOEXCEPT {return ldexp((double)__lcpp_x, __lcpp_e);} + +// log + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float log(float __lcpp_x) _NOEXCEPT {return logf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double log(long double __lcpp_x) _NOEXCEPT {return logl(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +log(_A1 __lcpp_x) _NOEXCEPT {return log((double)__lcpp_x);} + +// log10 + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float log10(float __lcpp_x) _NOEXCEPT {return log10f(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double log10(long double __lcpp_x) _NOEXCEPT {return log10l(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +log10(_A1 __lcpp_x) _NOEXCEPT {return log10((double)__lcpp_x);} + +// modf + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float modf(float __lcpp_x, float* __lcpp_y) _NOEXCEPT {return modff(__lcpp_x, __lcpp_y);} +inline _LIBCPP_INLINE_VISIBILITY long double modf(long double __lcpp_x, long double* __lcpp_y) _NOEXCEPT {return modfl(__lcpp_x, __lcpp_y);} +#endif + +// pow + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float pow(float __lcpp_x, float __lcpp_y) _NOEXCEPT {return powf(__lcpp_x, __lcpp_y);} +inline _LIBCPP_INLINE_VISIBILITY long double pow(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return powl(__lcpp_x, __lcpp_y);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::__lazy_enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + std::__promote<_A1, _A2> +>::type +pow(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type __result_type; + static_assert((!(std::is_same<_A1, __result_type>::value && + std::is_same<_A2, __result_type>::value)), ""); + return pow((__result_type)__lcpp_x, (__result_type)__lcpp_y); +} + +// sin + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float sin(float __lcpp_x) _NOEXCEPT {return sinf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double sin(long double __lcpp_x) _NOEXCEPT {return sinl(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +sin(_A1 __lcpp_x) _NOEXCEPT {return sin((double)__lcpp_x);} + +// sinh + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float sinh(float __lcpp_x) _NOEXCEPT {return sinhf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double sinh(long double __lcpp_x) _NOEXCEPT {return sinhl(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +sinh(_A1 __lcpp_x) _NOEXCEPT {return sinh((double)__lcpp_x);} + +// sqrt + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float sqrt(float __lcpp_x) _NOEXCEPT {return sqrtf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double sqrt(long double __lcpp_x) _NOEXCEPT {return sqrtl(__lcpp_x);} +#endif + +#endif // __sun__ +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +sqrt(_A1 __lcpp_x) _NOEXCEPT {return sqrt((double)__lcpp_x);} +#ifndef __sun__ + +// tan + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float tan(float __lcpp_x) _NOEXCEPT {return tanf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double tan(long double __lcpp_x) _NOEXCEPT {return tanl(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +tan(_A1 __lcpp_x) _NOEXCEPT {return tan((double)__lcpp_x);} + +// tanh + +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +inline _LIBCPP_INLINE_VISIBILITY float tanh(float __lcpp_x) _NOEXCEPT {return tanhf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double tanh(long double __lcpp_x) _NOEXCEPT {return tanhl(__lcpp_x);} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +tanh(_A1 __lcpp_x) _NOEXCEPT {return tanh((double)__lcpp_x);} + +// acosh + +#ifndef _LIBCPP_MSVCRT +inline _LIBCPP_INLINE_VISIBILITY float acosh(float __lcpp_x) _NOEXCEPT {return acoshf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double acosh(long double __lcpp_x) _NOEXCEPT {return acoshl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +acosh(_A1 __lcpp_x) _NOEXCEPT {return acosh((double)__lcpp_x);} +#endif + +// asinh + +#ifndef _LIBCPP_MSVCRT +inline _LIBCPP_INLINE_VISIBILITY float asinh(float __lcpp_x) _NOEXCEPT {return asinhf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double asinh(long double __lcpp_x) _NOEXCEPT {return asinhl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +asinh(_A1 __lcpp_x) _NOEXCEPT {return asinh((double)__lcpp_x);} +#endif + +// atanh + +#ifndef _LIBCPP_MSVCRT +inline _LIBCPP_INLINE_VISIBILITY float atanh(float __lcpp_x) _NOEXCEPT {return atanhf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double atanh(long double __lcpp_x) _NOEXCEPT {return atanhl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +atanh(_A1 __lcpp_x) _NOEXCEPT {return atanh((double)__lcpp_x);} +#endif + +// cbrt + +#ifndef _LIBCPP_MSVCRT +inline _LIBCPP_INLINE_VISIBILITY float cbrt(float __lcpp_x) _NOEXCEPT {return cbrtf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double cbrt(long double __lcpp_x) _NOEXCEPT {return cbrtl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +cbrt(_A1 __lcpp_x) _NOEXCEPT {return cbrt((double)__lcpp_x);} +#endif + +// copysign + +#if !defined(_VC_CRT_MAJOR_VERSION) || (_VC_CRT_MAJOR_VERSION < 12) +inline _LIBCPP_INLINE_VISIBILITY float copysign(float __lcpp_x, + float __lcpp_y) _NOEXCEPT { + return copysignf(__lcpp_x, __lcpp_y); +} +inline _LIBCPP_INLINE_VISIBILITY long double +copysign(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT { + return copysignl(__lcpp_x, __lcpp_y); +} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::__lazy_enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + std::__promote<_A1, _A2> +>::type +copysign(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type __result_type; + static_assert((!(std::is_same<_A1, __result_type>::value && + std::is_same<_A2, __result_type>::value)), ""); + return copysign((__result_type)__lcpp_x, (__result_type)__lcpp_y); +} + +#ifndef _LIBCPP_MSVCRT + +// erf + +inline _LIBCPP_INLINE_VISIBILITY float erf(float __lcpp_x) _NOEXCEPT {return erff(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double erf(long double __lcpp_x) _NOEXCEPT {return erfl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +erf(_A1 __lcpp_x) _NOEXCEPT {return erf((double)__lcpp_x);} + +// erfc + +inline _LIBCPP_INLINE_VISIBILITY float erfc(float __lcpp_x) _NOEXCEPT {return erfcf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double erfc(long double __lcpp_x) _NOEXCEPT {return erfcl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +erfc(_A1 __lcpp_x) _NOEXCEPT {return erfc((double)__lcpp_x);} + +// exp2 + +inline _LIBCPP_INLINE_VISIBILITY float exp2(float __lcpp_x) _NOEXCEPT {return exp2f(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double exp2(long double __lcpp_x) _NOEXCEPT {return exp2l(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +exp2(_A1 __lcpp_x) _NOEXCEPT {return exp2((double)__lcpp_x);} + +// expm1 + +inline _LIBCPP_INLINE_VISIBILITY float expm1(float __lcpp_x) _NOEXCEPT {return expm1f(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double expm1(long double __lcpp_x) _NOEXCEPT {return expm1l(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +expm1(_A1 __lcpp_x) _NOEXCEPT {return expm1((double)__lcpp_x);} + +// fdim + +inline _LIBCPP_INLINE_VISIBILITY float fdim(float __lcpp_x, float __lcpp_y) _NOEXCEPT {return fdimf(__lcpp_x, __lcpp_y);} +inline _LIBCPP_INLINE_VISIBILITY long double fdim(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fdiml(__lcpp_x, __lcpp_y);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::__lazy_enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + std::__promote<_A1, _A2> +>::type +fdim(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type __result_type; + static_assert((!(std::is_same<_A1, __result_type>::value && + std::is_same<_A2, __result_type>::value)), ""); + return fdim((__result_type)__lcpp_x, (__result_type)__lcpp_y); +} + +// fma + +inline _LIBCPP_INLINE_VISIBILITY float fma(float __lcpp_x, float __lcpp_y, float __lcpp_z) _NOEXCEPT {return fmaf(__lcpp_x, __lcpp_y, __lcpp_z);} +inline _LIBCPP_INLINE_VISIBILITY long double fma(long double __lcpp_x, long double __lcpp_y, long double __lcpp_z) _NOEXCEPT {return fmal(__lcpp_x, __lcpp_y, __lcpp_z);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::__lazy_enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value && + std::is_arithmetic<_A3>::value, + std::__promote<_A1, _A2, _A3> +>::type +fma(_A1 __lcpp_x, _A2 __lcpp_y, _A3 __lcpp_z) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2, _A3>::type __result_type; + static_assert((!(std::is_same<_A1, __result_type>::value && + std::is_same<_A2, __result_type>::value && + std::is_same<_A3, __result_type>::value)), ""); + return fma((__result_type)__lcpp_x, (__result_type)__lcpp_y, (__result_type)__lcpp_z); +} + +// fmax + +inline _LIBCPP_INLINE_VISIBILITY float fmax(float __lcpp_x, float __lcpp_y) _NOEXCEPT {return fmaxf(__lcpp_x, __lcpp_y);} +inline _LIBCPP_INLINE_VISIBILITY long double fmax(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fmaxl(__lcpp_x, __lcpp_y);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::__lazy_enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + std::__promote<_A1, _A2> +>::type +fmax(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type __result_type; + static_assert((!(std::is_same<_A1, __result_type>::value && + std::is_same<_A2, __result_type>::value)), ""); + return fmax((__result_type)__lcpp_x, (__result_type)__lcpp_y); +} + +// fmin + +inline _LIBCPP_INLINE_VISIBILITY float fmin(float __lcpp_x, float __lcpp_y) _NOEXCEPT {return fminf(__lcpp_x, __lcpp_y);} +inline _LIBCPP_INLINE_VISIBILITY long double fmin(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fminl(__lcpp_x, __lcpp_y);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::__lazy_enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + std::__promote<_A1, _A2> +>::type +fmin(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type __result_type; + static_assert((!(std::is_same<_A1, __result_type>::value && + std::is_same<_A2, __result_type>::value)), ""); + return fmin((__result_type)__lcpp_x, (__result_type)__lcpp_y); +} + +// hypot + +inline _LIBCPP_INLINE_VISIBILITY float hypot(float __lcpp_x, float __lcpp_y) _NOEXCEPT {return hypotf(__lcpp_x, __lcpp_y);} +inline _LIBCPP_INLINE_VISIBILITY long double hypot(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return hypotl(__lcpp_x, __lcpp_y);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::__lazy_enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + std::__promote<_A1, _A2> +>::type +hypot(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type __result_type; + static_assert((!(std::is_same<_A1, __result_type>::value && + std::is_same<_A2, __result_type>::value)), ""); + return hypot((__result_type)__lcpp_x, (__result_type)__lcpp_y); +} + +// ilogb + +inline _LIBCPP_INLINE_VISIBILITY int ilogb(float __lcpp_x) _NOEXCEPT {return ilogbf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY int ilogb(long double __lcpp_x) _NOEXCEPT {return ilogbl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, int>::type +ilogb(_A1 __lcpp_x) _NOEXCEPT {return ilogb((double)__lcpp_x);} + +// lgamma + +inline _LIBCPP_INLINE_VISIBILITY float lgamma(float __lcpp_x) _NOEXCEPT {return lgammaf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double lgamma(long double __lcpp_x) _NOEXCEPT {return lgammal(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +lgamma(_A1 __lcpp_x) _NOEXCEPT {return lgamma((double)__lcpp_x);} + +// llrint + +inline _LIBCPP_INLINE_VISIBILITY long long llrint(float __lcpp_x) _NOEXCEPT {return llrintf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long long llrint(long double __lcpp_x) _NOEXCEPT {return llrintl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, long long>::type +llrint(_A1 __lcpp_x) _NOEXCEPT {return llrint((double)__lcpp_x);} + +// llround + +inline _LIBCPP_INLINE_VISIBILITY long long llround(float __lcpp_x) _NOEXCEPT {return llroundf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long long llround(long double __lcpp_x) _NOEXCEPT {return llroundl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, long long>::type +llround(_A1 __lcpp_x) _NOEXCEPT {return llround((double)__lcpp_x);} + +// log1p + +inline _LIBCPP_INLINE_VISIBILITY float log1p(float __lcpp_x) _NOEXCEPT {return log1pf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double log1p(long double __lcpp_x) _NOEXCEPT {return log1pl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +log1p(_A1 __lcpp_x) _NOEXCEPT {return log1p((double)__lcpp_x);} + +// log2 + +inline _LIBCPP_INLINE_VISIBILITY float log2(float __lcpp_x) _NOEXCEPT {return log2f(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double log2(long double __lcpp_x) _NOEXCEPT {return log2l(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +log2(_A1 __lcpp_x) _NOEXCEPT {return log2((double)__lcpp_x);} + +// logb + +inline _LIBCPP_INLINE_VISIBILITY float logb(float __lcpp_x) _NOEXCEPT {return logbf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double logb(long double __lcpp_x) _NOEXCEPT {return logbl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +logb(_A1 __lcpp_x) _NOEXCEPT {return logb((double)__lcpp_x);} + +// lrint + +inline _LIBCPP_INLINE_VISIBILITY long lrint(float __lcpp_x) _NOEXCEPT {return lrintf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long lrint(long double __lcpp_x) _NOEXCEPT {return lrintl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, long>::type +lrint(_A1 __lcpp_x) _NOEXCEPT {return lrint((double)__lcpp_x);} + +// lround + +inline _LIBCPP_INLINE_VISIBILITY long lround(float __lcpp_x) _NOEXCEPT {return lroundf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long lround(long double __lcpp_x) _NOEXCEPT {return lroundl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, long>::type +lround(_A1 __lcpp_x) _NOEXCEPT {return lround((double)__lcpp_x);} + +// nan + +// nearbyint + +inline _LIBCPP_INLINE_VISIBILITY float nearbyint(float __lcpp_x) _NOEXCEPT {return nearbyintf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double nearbyint(long double __lcpp_x) _NOEXCEPT {return nearbyintl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +nearbyint(_A1 __lcpp_x) _NOEXCEPT {return nearbyint((double)__lcpp_x);} + +// nextafter + +inline _LIBCPP_INLINE_VISIBILITY float nextafter(float __lcpp_x, float __lcpp_y) _NOEXCEPT {return nextafterf(__lcpp_x, __lcpp_y);} +inline _LIBCPP_INLINE_VISIBILITY long double nextafter(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nextafterl(__lcpp_x, __lcpp_y);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::__lazy_enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + std::__promote<_A1, _A2> +>::type +nextafter(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type __result_type; + static_assert((!(std::is_same<_A1, __result_type>::value && + std::is_same<_A2, __result_type>::value)), ""); + return nextafter((__result_type)__lcpp_x, (__result_type)__lcpp_y); +} + +// nexttoward + +inline _LIBCPP_INLINE_VISIBILITY float nexttoward(float __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nexttowardf(__lcpp_x, __lcpp_y);} +inline _LIBCPP_INLINE_VISIBILITY long double nexttoward(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nexttowardl(__lcpp_x, __lcpp_y);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +nexttoward(_A1 __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nexttoward((double)__lcpp_x, __lcpp_y);} + +// remainder + +inline _LIBCPP_INLINE_VISIBILITY float remainder(float __lcpp_x, float __lcpp_y) _NOEXCEPT {return remainderf(__lcpp_x, __lcpp_y);} +inline _LIBCPP_INLINE_VISIBILITY long double remainder(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return remainderl(__lcpp_x, __lcpp_y);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::__lazy_enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + std::__promote<_A1, _A2> +>::type +remainder(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type __result_type; + static_assert((!(std::is_same<_A1, __result_type>::value && + std::is_same<_A2, __result_type>::value)), ""); + return remainder((__result_type)__lcpp_x, (__result_type)__lcpp_y); +} + +// remquo + +inline _LIBCPP_INLINE_VISIBILITY float remquo(float __lcpp_x, float __lcpp_y, int* __lcpp_z) _NOEXCEPT {return remquof(__lcpp_x, __lcpp_y, __lcpp_z);} +inline _LIBCPP_INLINE_VISIBILITY long double remquo(long double __lcpp_x, long double __lcpp_y, int* __lcpp_z) _NOEXCEPT {return remquol(__lcpp_x, __lcpp_y, __lcpp_z);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::__lazy_enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, + std::__promote<_A1, _A2> +>::type +remquo(_A1 __lcpp_x, _A2 __lcpp_y, int* __lcpp_z) _NOEXCEPT +{ + typedef typename std::__promote<_A1, _A2>::type __result_type; + static_assert((!(std::is_same<_A1, __result_type>::value && + std::is_same<_A2, __result_type>::value)), ""); + return remquo((__result_type)__lcpp_x, (__result_type)__lcpp_y, __lcpp_z); +} + +// rint + +inline _LIBCPP_INLINE_VISIBILITY float rint(float __lcpp_x) _NOEXCEPT {return rintf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double rint(long double __lcpp_x) _NOEXCEPT {return rintl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +rint(_A1 __lcpp_x) _NOEXCEPT {return rint((double)__lcpp_x);} + +// round + +inline _LIBCPP_INLINE_VISIBILITY float round(float __lcpp_x) _NOEXCEPT {return roundf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double round(long double __lcpp_x) _NOEXCEPT {return roundl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +round(_A1 __lcpp_x) _NOEXCEPT {return round((double)__lcpp_x);} + +// scalbln + +inline _LIBCPP_INLINE_VISIBILITY float scalbln(float __lcpp_x, long __lcpp_y) _NOEXCEPT {return scalblnf(__lcpp_x, __lcpp_y);} +inline _LIBCPP_INLINE_VISIBILITY long double scalbln(long double __lcpp_x, long __lcpp_y) _NOEXCEPT {return scalblnl(__lcpp_x, __lcpp_y);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +scalbln(_A1 __lcpp_x, long __lcpp_y) _NOEXCEPT {return scalbln((double)__lcpp_x, __lcpp_y);} + +// scalbn + +inline _LIBCPP_INLINE_VISIBILITY float scalbn(float __lcpp_x, int __lcpp_y) _NOEXCEPT {return scalbnf(__lcpp_x, __lcpp_y);} +inline _LIBCPP_INLINE_VISIBILITY long double scalbn(long double __lcpp_x, int __lcpp_y) _NOEXCEPT {return scalbnl(__lcpp_x, __lcpp_y);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +scalbn(_A1 __lcpp_x, int __lcpp_y) _NOEXCEPT {return scalbn((double)__lcpp_x, __lcpp_y);} + +// tgamma + +inline _LIBCPP_INLINE_VISIBILITY float tgamma(float __lcpp_x) _NOEXCEPT {return tgammaf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double tgamma(long double __lcpp_x) _NOEXCEPT {return tgammal(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +tgamma(_A1 __lcpp_x) _NOEXCEPT {return tgamma((double)__lcpp_x);} + +// trunc + +inline _LIBCPP_INLINE_VISIBILITY float trunc(float __lcpp_x) _NOEXCEPT {return truncf(__lcpp_x);} +inline _LIBCPP_INLINE_VISIBILITY long double trunc(long double __lcpp_x) _NOEXCEPT {return truncl(__lcpp_x);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename std::enable_if::value, double>::type +trunc(_A1 __lcpp_x) _NOEXCEPT {return trunc((double)__lcpp_x);} + +#endif // !_LIBCPP_MSVCRT +#endif // __sun__ + +} // extern "C++" + +#endif // __cplusplus + +#endif // _LIBCPP_MATH_H diff --git a/headers/libs/libc++/memory b/headers/libs/libc++/memory new file mode 100644 index 0000000000..a162eafe67 --- /dev/null +++ b/headers/libs/libc++/memory @@ -0,0 +1,5637 @@ +// -*- C++ -*- +//===-------------------------- memory ------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_MEMORY +#define _LIBCPP_MEMORY + +/* + memory synopsis + +namespace std +{ + +struct allocator_arg_t { }; +constexpr allocator_arg_t allocator_arg = allocator_arg_t(); + +template struct uses_allocator; + +template +struct pointer_traits +{ + typedef Ptr pointer; + typedef
element_type; + typedef
difference_type; + + template using rebind =
; + + static pointer pointer_to(
); +}; + +template +struct pointer_traits +{ + typedef T* pointer; + typedef T element_type; + typedef ptrdiff_t difference_type; + + template using rebind = U*; + + static pointer pointer_to(
) noexcept; +}; + +template +struct allocator_traits +{ + typedef Alloc allocator_type; + typedef typename allocator_type::value_type + value_type; + + typedef Alloc::pointer | value_type* pointer; + typedef Alloc::const_pointer + | pointer_traits::rebind + const_pointer; + typedef Alloc::void_pointer + | pointer_traits::rebind + void_pointer; + typedef Alloc::const_void_pointer + | pointer_traits::rebind + const_void_pointer; + typedef Alloc::difference_type + | pointer_traits::difference_type + difference_type; + typedef Alloc::size_type + | make_unsigned::type + size_type; + typedef Alloc::propagate_on_container_copy_assignment + | false_type propagate_on_container_copy_assignment; + typedef Alloc::propagate_on_container_move_assignment + | false_type propagate_on_container_move_assignment; + typedef Alloc::propagate_on_container_swap + | false_type propagate_on_container_swap; + typedef Alloc::is_always_equal + | is_empty is_always_equal; + + template using rebind_alloc = Alloc::rebind::other | Alloc; + template using rebind_traits = allocator_traits>; + + static pointer allocate(allocator_type& a, size_type n); + static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint); + + static void deallocate(allocator_type& a, pointer p, size_type n) noexcept; + + template + static void construct(allocator_type& a, T* p, Args&&... args); + + template + static void destroy(allocator_type& a, T* p); + + static size_type max_size(const allocator_type& a); // noexcept in C++14 + + static allocator_type + select_on_container_copy_construction(const allocator_type& a); +}; + +template <> +class allocator +{ +public: + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template struct rebind {typedef allocator<_Up> other;}; +}; + +template +class allocator +{ +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef typename add_lvalue_reference::type reference; + typedef typename add_lvalue_reference::type const_reference; + typedef T value_type; + + template struct rebind {typedef allocator other;}; + + allocator() noexcept; + allocator(const allocator&) noexcept; + template allocator(const allocator&) noexcept; + ~allocator(); + pointer address(reference x) const noexcept; + const_pointer address(const_reference x) const noexcept; + pointer allocate(size_type, allocator::const_pointer hint = 0); + void deallocate(pointer p, size_type n) noexcept; + size_type max_size() const noexcept; + template + void construct(U* p, Args&&... args); + template + void destroy(U* p); +}; + +template +bool operator==(const allocator&, const allocator&) noexcept; + +template +bool operator!=(const allocator&, const allocator&) noexcept; + +template +class raw_storage_iterator + : public iterator // purposefully not C++03 +{ +public: + explicit raw_storage_iterator(OutputIterator x); + raw_storage_iterator& operator*(); + raw_storage_iterator& operator=(const T& element); + raw_storage_iterator& operator++(); + raw_storage_iterator operator++(int); +}; + +template pair get_temporary_buffer(ptrdiff_t n) noexcept; +template void return_temporary_buffer(T* p) noexcept; + +template T* addressof(T& r) noexcept; + +template +ForwardIterator +uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result); + +template +ForwardIterator +uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result); + +template +void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x); + +template +ForwardIterator +uninitialized_fill_n(ForwardIterator first, Size n, const T& x); + +template struct auto_ptr_ref {}; + +template +class auto_ptr +{ +public: + typedef X element_type; + + explicit auto_ptr(X* p =0) throw(); + auto_ptr(auto_ptr&) throw(); + template auto_ptr(auto_ptr&) throw(); + auto_ptr& operator=(auto_ptr&) throw(); + template auto_ptr& operator=(auto_ptr&) throw(); + auto_ptr& operator=(auto_ptr_ref r) throw(); + ~auto_ptr() throw(); + + typename add_lvalue_reference::type operator*() const throw(); + X* operator->() const throw(); + X* get() const throw(); + X* release() throw(); + void reset(X* p =0) throw(); + + auto_ptr(auto_ptr_ref) throw(); + template operator auto_ptr_ref() throw(); + template operator auto_ptr() throw(); +}; + +template +struct default_delete +{ + constexpr default_delete() noexcept = default; + template default_delete(const default_delete&) noexcept; + + void operator()(T*) const noexcept; +}; + +template +struct default_delete +{ + constexpr default_delete() noexcept = default; + void operator()(T*) const noexcept; + template void operator()(U*) const = delete; +}; + +template > +class unique_ptr +{ +public: + typedef see below pointer; + typedef T element_type; + typedef D deleter_type; + + // constructors + constexpr unique_ptr() noexcept; + explicit unique_ptr(pointer p) noexcept; + unique_ptr(pointer p, see below d1) noexcept; + unique_ptr(pointer p, see below d2) noexcept; + unique_ptr(unique_ptr&& u) noexcept; + unique_ptr(nullptr_t) noexcept : unique_ptr() { } + template + unique_ptr(unique_ptr&& u) noexcept; + template + unique_ptr(auto_ptr&& u) noexcept; + + // destructor + ~unique_ptr(); + + // assignment + unique_ptr& operator=(unique_ptr&& u) noexcept; + template unique_ptr& operator=(unique_ptr&& u) noexcept; + unique_ptr& operator=(nullptr_t) noexcept; + + // observers + typename add_lvalue_reference::type operator*() const; + pointer operator->() const noexcept; + pointer get() const noexcept; + deleter_type& get_deleter() noexcept; + const deleter_type& get_deleter() const noexcept; + explicit operator bool() const noexcept; + + // modifiers + pointer release() noexcept; + void reset(pointer p = pointer()) noexcept; + void swap(unique_ptr& u) noexcept; +}; + +template +class unique_ptr +{ +public: + typedef implementation-defined pointer; + typedef T element_type; + typedef D deleter_type; + + // constructors + constexpr unique_ptr() noexcept; + explicit unique_ptr(pointer p) noexcept; + unique_ptr(pointer p, see below d) noexcept; + unique_ptr(pointer p, see below d) noexcept; + unique_ptr(unique_ptr&& u) noexcept; + unique_ptr(nullptr_t) noexcept : unique_ptr() { } + + // destructor + ~unique_ptr(); + + // assignment + unique_ptr& operator=(unique_ptr&& u) noexcept; + unique_ptr& operator=(nullptr_t) noexcept; + + // observers + T& operator[](size_t i) const; + pointer get() const noexcept; + deleter_type& get_deleter() noexcept; + const deleter_type& get_deleter() const noexcept; + explicit operator bool() const noexcept; + + // modifiers + pointer release() noexcept; + void reset(pointer p = pointer()) noexcept; + void reset(nullptr_t) noexcept; + template void reset(U) = delete; + void swap(unique_ptr& u) noexcept; +}; + +template + void swap(unique_ptr& x, unique_ptr& y) noexcept; + +template + bool operator==(const unique_ptr& x, const unique_ptr& y); +template + bool operator!=(const unique_ptr& x, const unique_ptr& y); +template + bool operator<(const unique_ptr& x, const unique_ptr& y); +template + bool operator<=(const unique_ptr& x, const unique_ptr& y); +template + bool operator>(const unique_ptr& x, const unique_ptr& y); +template + bool operator>=(const unique_ptr& x, const unique_ptr& y); + +template + bool operator==(const unique_ptr& x, nullptr_t) noexcept; +template + bool operator==(nullptr_t, const unique_ptr& y) noexcept; +template + bool operator!=(const unique_ptr& x, nullptr_t) noexcept; +template + bool operator!=(nullptr_t, const unique_ptr& y) noexcept; + +template + bool operator<(const unique_ptr& x, nullptr_t); +template + bool operator<(nullptr_t, const unique_ptr& y); +template + bool operator<=(const unique_ptr& x, nullptr_t); +template + bool operator<=(nullptr_t, const unique_ptr& y); +template + bool operator>(const unique_ptr& x, nullptr_t); +template + bool operator>(nullptr_t, const unique_ptr& y); +template + bool operator>=(const unique_ptr& x, nullptr_t); +template + bool operator>=(nullptr_t, const unique_ptr& y); + +class bad_weak_ptr + : public std::exception +{ + bad_weak_ptr() noexcept; +}; + +template unique_ptr make_unique(Args&&... args); // C++14 +template unique_ptr make_unique(size_t n); // C++14 +template unspecified make_unique(Args&&...) = delete; // C++14, T == U[N] + +template +class shared_ptr +{ +public: + typedef T element_type; + + // constructors: + constexpr shared_ptr() noexcept; + template explicit shared_ptr(Y* p); + template shared_ptr(Y* p, D d); + template shared_ptr(Y* p, D d, A a); + template shared_ptr(nullptr_t p, D d); + template shared_ptr(nullptr_t p, D d, A a); + template shared_ptr(const shared_ptr& r, T *p) noexcept; + shared_ptr(const shared_ptr& r) noexcept; + template shared_ptr(const shared_ptr& r) noexcept; + shared_ptr(shared_ptr&& r) noexcept; + template shared_ptr(shared_ptr&& r) noexcept; + template explicit shared_ptr(const weak_ptr& r); + template shared_ptr(auto_ptr&& r); + template shared_ptr(unique_ptr&& r); + shared_ptr(nullptr_t) : shared_ptr() { } + + // destructor: + ~shared_ptr(); + + // assignment: + shared_ptr& operator=(const shared_ptr& r) noexcept; + template shared_ptr& operator=(const shared_ptr& r) noexcept; + shared_ptr& operator=(shared_ptr&& r) noexcept; + template shared_ptr& operator=(shared_ptr&& r); + template shared_ptr& operator=(auto_ptr&& r); + template shared_ptr& operator=(unique_ptr&& r); + + // modifiers: + void swap(shared_ptr& r) noexcept; + void reset() noexcept; + template void reset(Y* p); + template void reset(Y* p, D d); + template void reset(Y* p, D d, A a); + + // observers: + T* get() const noexcept; + T& operator*() const noexcept; + T* operator->() const noexcept; + long use_count() const noexcept; + bool unique() const noexcept; + explicit operator bool() const noexcept; + template bool owner_before(shared_ptr const& b) const; + template bool owner_before(weak_ptr const& b) const; +}; + +// shared_ptr comparisons: +template + bool operator==(shared_ptr const& a, shared_ptr const& b) noexcept; +template + bool operator!=(shared_ptr const& a, shared_ptr const& b) noexcept; +template + bool operator<(shared_ptr const& a, shared_ptr const& b) noexcept; +template + bool operator>(shared_ptr const& a, shared_ptr const& b) noexcept; +template + bool operator<=(shared_ptr const& a, shared_ptr const& b) noexcept; +template + bool operator>=(shared_ptr const& a, shared_ptr const& b) noexcept; + +template + bool operator==(const shared_ptr& x, nullptr_t) noexcept; +template + bool operator==(nullptr_t, const shared_ptr& y) noexcept; +template + bool operator!=(const shared_ptr& x, nullptr_t) noexcept; +template + bool operator!=(nullptr_t, const shared_ptr& y) noexcept; +template + bool operator<(const shared_ptr& x, nullptr_t) noexcept; +template +bool operator<(nullptr_t, const shared_ptr& y) noexcept; +template + bool operator<=(const shared_ptr& x, nullptr_t) noexcept; +template + bool operator<=(nullptr_t, const shared_ptr& y) noexcept; +template + bool operator>(const shared_ptr& x, nullptr_t) noexcept; +template + bool operator>(nullptr_t, const shared_ptr& y) noexcept; +template + bool operator>=(const shared_ptr& x, nullptr_t) noexcept; +template + bool operator>=(nullptr_t, const shared_ptr& y) noexcept; + +// shared_ptr specialized algorithms: +template void swap(shared_ptr& a, shared_ptr& b) noexcept; + +// shared_ptr casts: +template + shared_ptr static_pointer_cast(shared_ptr const& r) noexcept; +template + shared_ptr dynamic_pointer_cast(shared_ptr const& r) noexcept; +template + shared_ptr const_pointer_cast(shared_ptr const& r) noexcept; + +// shared_ptr I/O: +template + basic_ostream& operator<< (basic_ostream& os, shared_ptr const& p); + +// shared_ptr get_deleter: +template D* get_deleter(shared_ptr const& p) noexcept; + +template + shared_ptr make_shared(Args&&... args); +template + shared_ptr allocate_shared(const A& a, Args&&... args); + +template +class weak_ptr +{ +public: + typedef T element_type; + + // constructors + constexpr weak_ptr() noexcept; + template weak_ptr(shared_ptr const& r) noexcept; + weak_ptr(weak_ptr const& r) noexcept; + template weak_ptr(weak_ptr const& r) noexcept; + weak_ptr(weak_ptr&& r) noexcept; // C++14 + template weak_ptr(weak_ptr&& r) noexcept; // C++14 + + // destructor + ~weak_ptr(); + + // assignment + weak_ptr& operator=(weak_ptr const& r) noexcept; + template weak_ptr& operator=(weak_ptr const& r) noexcept; + template weak_ptr& operator=(shared_ptr const& r) noexcept; + weak_ptr& operator=(weak_ptr&& r) noexcept; // C++14 + template weak_ptr& operator=(weak_ptr&& r) noexcept; // C++14 + + // modifiers + void swap(weak_ptr& r) noexcept; + void reset() noexcept; + + // observers + long use_count() const noexcept; + bool expired() const noexcept; + shared_ptr lock() const noexcept; + template bool owner_before(shared_ptr const& b) const; + template bool owner_before(weak_ptr const& b) const; +}; + +// weak_ptr specialized algorithms: +template void swap(weak_ptr& a, weak_ptr& b) noexcept; + +// class owner_less: +template struct owner_less; + +template +struct owner_less> + : binary_function, shared_ptr, bool> +{ + typedef bool result_type; + bool operator()(shared_ptr const&, shared_ptr const&) const; + bool operator()(shared_ptr const&, weak_ptr const&) const; + bool operator()(weak_ptr const&, shared_ptr const&) const; +}; + +template +struct owner_less> + : binary_function, weak_ptr, bool> +{ + typedef bool result_type; + bool operator()(weak_ptr const&, weak_ptr const&) const; + bool operator()(shared_ptr const&, weak_ptr const&) const; + bool operator()(weak_ptr const&, shared_ptr const&) const; +}; + +template +class enable_shared_from_this +{ +protected: + constexpr enable_shared_from_this() noexcept; + enable_shared_from_this(enable_shared_from_this const&) noexcept; + enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept; + ~enable_shared_from_this(); +public: + shared_ptr shared_from_this(); + shared_ptr shared_from_this() const; +}; + +template + bool atomic_is_lock_free(const shared_ptr* p); +template + shared_ptr atomic_load(const shared_ptr* p); +template + shared_ptr atomic_load_explicit(const shared_ptr* p, memory_order mo); +template + void atomic_store(shared_ptr* p, shared_ptr r); +template + void atomic_store_explicit(shared_ptr* p, shared_ptr r, memory_order mo); +template + shared_ptr atomic_exchange(shared_ptr* p, shared_ptr r); +template + shared_ptr + atomic_exchange_explicit(shared_ptr* p, shared_ptr r, memory_order mo); +template + bool + atomic_compare_exchange_weak(shared_ptr* p, shared_ptr* v, shared_ptr w); +template + bool + atomic_compare_exchange_strong( shared_ptr* p, shared_ptr* v, shared_ptr w); +template + bool + atomic_compare_exchange_weak_explicit(shared_ptr* p, shared_ptr* v, + shared_ptr w, memory_order success, + memory_order failure); +template + bool + atomic_compare_exchange_strong_explicit(shared_ptr* p, shared_ptr* v, + shared_ptr w, memory_order success, + memory_order failure); +// Hash support +template struct hash; +template struct hash >; +template struct hash >; + +// Pointer safety +enum class pointer_safety { relaxed, preferred, strict }; +void declare_reachable(void *p); +template T *undeclare_reachable(T *p); +void declare_no_pointers(char *p, size_t n); +void undeclare_no_pointers(char *p, size_t n); +pointer_safety get_pointer_safety() noexcept; + +void* align(size_t alignment, size_t size, void*& ptr, size_t& space); + +} // std + +*/ + +#include <__config> +#include +#include +#include +#include +#include +#include +#include +#include +#include <__functional_base> +#include +#include +#include +#if defined(_LIBCPP_NO_EXCEPTIONS) + #include +#endif + +#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) +# include +#endif + +#include <__undef_min_max> +#include <__undef___deallocate> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_ALWAYS_INLINE +_ValueType __libcpp_relaxed_load(_ValueType const* __value) { +#if !defined(_LIBCPP_HAS_NO_THREADS) && \ + defined(__ATOMIC_RELAXED) && \ + (__has_builtin(__atomic_load_n) || _GNUC_VER >= 407) + return __atomic_load_n(__value, __ATOMIC_RELAXED); +#else + return *__value; +#endif +} + +// addressof moved to <__functional_base> + +template class allocator; + +template <> +class _LIBCPP_TYPE_VIS_ONLY allocator +{ +public: + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template struct rebind {typedef allocator<_Up> other;}; +}; + +template <> +class _LIBCPP_TYPE_VIS_ONLY allocator +{ +public: + typedef const void* pointer; + typedef const void* const_pointer; + typedef const void value_type; + + template struct rebind {typedef allocator<_Up> other;}; +}; + +// pointer_traits + +template +struct __has_element_type +{ +private: + struct __two {char __lx; char __lxx;}; + template static __two __test(...); + template static char __test(typename _Up::element_type* = 0); +public: + static const bool value = sizeof(__test<_Tp>(0)) == 1; +}; + +template ::value> +struct __pointer_traits_element_type; + +template +struct __pointer_traits_element_type<_Ptr, true> +{ + typedef typename _Ptr::element_type type; +}; + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +template