dawn: Make ASSERT() breakpoint on all supported platforms.

This moves the implementation of DAWN_BREAKPOINT() in the only file
that uses it and completes it for all supported architectures. If in
the future breakpoints are needed in other places, it would be possible
to expose the function in a header.

Add DAWN_PLATFORM_IS macros for all supported architectures so they can
be used for implementing Breakpoint() and add support for RISCV.

Bug: dawn:1506
Change-Id: Ib1b92c2d0c119cfc1b348fe905029fe366f5ad04
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/98121
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2022-08-07 11:01:49 +00:00 committed by Dawn LUCI CQ
parent 66fbd2c1ec
commit af908a3267
3 changed files with 175 additions and 28 deletions

View File

@ -17,6 +17,38 @@
#include <cstdlib> #include <cstdlib>
#include "dawn/common/Log.h" #include "dawn/common/Log.h"
#include "dawn/common/Platform.h"
#if DAWN_COMPILER_IS(CLANG) || DAWN_COMPILER_IS(GCC)
void BreakPoint() {
#if DAWN_PLATFORM_IS(X86)
__asm__ __volatile__("int $3\n\t");
#elif DAWN_PLATFORM_IS(ARM32)
__asm__ __volatile__("bkpt 0");
#elif DAWN_PLATFORM_IS(ARM64)
__asm__ __volatile__("brk 0");
#elif DAWN_PLATFORM_IS(RISCV)
__asm__ __volatile__("ebreak");
#elif DAWN_PLATFORM_IS(MIPS)
__asm__ __volatile__("break");
#elif DAWN_PLATFORM_IS(S390) || DAWN_PLATFORM_IS_(S390X)
__asm__ __volatile__(".word 0x0001");
#elif DAWN_PLATFORM_IS(PPC) || DAWN_PLATFORM_IS_(PPC64)
__asm__ __volatile__("twge 2,2");
#else
#error "Unsupported platform"
#endif
}
#elif DAWN_COMPILER_IS(MSVC)
extern void __cdecl __debugbreak(void);
void BreakPoint() {
__debugbreak();
}
#else
#error "Unsupported compiler"
#endif
void HandleAssertionFailure(const char* file, void HandleAssertionFailure(const char* file,
const char* function, const char* function,
@ -27,6 +59,6 @@ void HandleAssertionFailure(const char* file,
#if defined(DAWN_ABORT_ON_ASSERT) #if defined(DAWN_ABORT_ON_ASSERT)
abort(); abort();
#else #else
DAWN_BREAKPOINT(); BreakPoint();
#endif #endif
} }

View File

@ -17,7 +17,6 @@
// Defines macros for compiler-specific functionality // Defines macros for compiler-specific functionality
// - DAWN_COMPILER_IS(CLANG|GCC|MSVC): Compiler detection // - DAWN_COMPILER_IS(CLANG|GCC|MSVC): Compiler detection
// - DAWN_BREAKPOINT(): Raises an exception and breaks in the debugger
// - DAWN_BUILTIN_UNREACHABLE(): Hints the compiler that a code path is unreachable // - DAWN_BUILTIN_UNREACHABLE(): Hints the compiler that a code path is unreachable
// - DAWN_(UN)?LIKELY(EXPR): Where available, hints the compiler that the expression will be true // - DAWN_(UN)?LIKELY(EXPR): Where available, hints the compiler that the expression will be true
// (resp. false) to help it generate code that leads to better branch prediction. // (resp. false) to help it generate code that leads to better branch prediction.
@ -35,13 +34,6 @@
#define DAWN_COMPILER_IS_GCC 1 #define DAWN_COMPILER_IS_GCC 1
#endif #endif
#if defined(__i386__) || defined(__x86_64__)
#define DAWN_BREAKPOINT() __asm__ __volatile__("int $3\n\t")
#else
// TODO(cwallez@chromium.org): Implement breakpoint on all supported architectures
#define DAWN_BREAKPOINT()
#endif
#define DAWN_BUILTIN_UNREACHABLE() __builtin_unreachable() #define DAWN_BUILTIN_UNREACHABLE() __builtin_unreachable()
#define DAWN_LIKELY(x) __builtin_expect(!!(x), 1) #define DAWN_LIKELY(x) __builtin_expect(!!(x), 1)
#define DAWN_UNLIKELY(x) __builtin_expect(!!(x), 0) #define DAWN_UNLIKELY(x) __builtin_expect(!!(x), 0)
@ -60,9 +52,6 @@
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define DAWN_COMPILER_IS_MSVC 1 #define DAWN_COMPILER_IS_MSVC 1
extern void __cdecl __debugbreak(void);
#define DAWN_BREAKPOINT() __debugbreak()
#define DAWN_BUILTIN_UNREACHABLE() __assume(false) #define DAWN_BUILTIN_UNREACHABLE() __assume(false)
#define DAWN_DECLARE_UNUSED #define DAWN_DECLARE_UNUSED

View File

@ -15,6 +15,25 @@
#ifndef SRC_DAWN_COMMON_PLATFORM_H_ #ifndef SRC_DAWN_COMMON_PLATFORM_H_
#define SRC_DAWN_COMMON_PLATFORM_H_ #define SRC_DAWN_COMMON_PLATFORM_H_
// Use #if DAWN_PLATFORM_IS(X) for platform specific code.
// Do not use #ifdef or the naked macro DAWN_PLATFORM_IS_X.
// This can help avoid common mistakes like not including "Platform.h" and falling into unwanted
// code block as usage of undefined macro "function" will be blocked by the compiler.
#define DAWN_PLATFORM_IS(X) (1 == DAWN_PLATFORM_IS_##X)
// Define platform macros for OSes:
//
// - WINDOWS
// - WIN32
// - WINUWP
// - POSIX
// - LINUX
// - ANDROID
// - APPLE
// - IOS
// - MACOS
// - FUCHSIA
// - EMSCRIPTEN
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
#include <winapifamily.h> #include <winapifamily.h>
#define DAWN_PLATFORM_IS_WINDOWS 1 #define DAWN_PLATFORM_IS_WINDOWS 1
@ -57,22 +76,81 @@
#error "Unsupported platform." #error "Unsupported platform."
#endif #endif
// Distinguish mips32. // Define platform macros for CPU architectures:
#if defined(__mips__) && (_MIPS_SIM == _ABIO32) && !defined(__mips32__) //
#define __mips32__ // - X86
// - I386
// - X86_64
// - ARM
// - ARM32
// - ARM64
// - RISCV
// - RISCV32
// - RISCV64
// - MIPS
// - MIPS32
// - MIPS64
// - S390
// - S390X
// - PPC
// - PPC64
#if defined(__i386__) || defined(_M_IX86)
#define DAWN_PLATFORM_IS_X86 1
#define DAWN_PLATFORM_IS_I386 1
#elif defined(__x86_64__) || defined(_M_X64)
#define DAWN_PLATFORM_IS_X86 1
#define DAWN_PLATFORM_IS_X86_64 1
#elif defined(__arm__) || defined(_M_ARM)
#define DAWN_PLATFORM_IS_ARM 1
#define DAWN_PLATFORM_IS_ARM32 1
#elif defined(__aarch64__) || defined(_M_ARM64)
#define DAWN_PLATFORM_IS_ARM 1
#define DAWN_PLATFORM_IS_ARM64 1
#elif defined(__riscv)
#define DAWN_PLATFORM_IS_RISCV 1
#if __riscv_xlen == 32
#define DAWN_PLATFORM_IS_RISCV32 1
#else
#define DAWN_PLATFORM_IS_RISCV64 1
#endif #endif
// Distinguish mips64. #elif defined(__mips__)
#if defined(__mips__) && (_MIPS_SIM == _ABI64) && !defined(__mips64__) #define DAWN_PLATFORM_IS_MIPS 1
#define __mips64__ #if _MIPS_SIM == _ABIO32
#define DAWN_PLATFORM_IS_MIPS32 1
#else
#define DAWN_PLATFORM_IS_MIPS64 1
#endif #endif
#if defined(_WIN64) || defined(__aarch64__) || defined(__x86_64__) || defined(__mips64__) || \ #elif defiend(__s390__)
defined(__s390x__) || defined(__PPC64__) #define DAWN_PLATFORM_IS_S390 1
#elif defiend(__s390x__)
#define DAWN_PLATFORM_IS_S390X 1
#elif defined(__PPC__)
#define DAWN_PLATFORM_IS_PPC 1
#elif defined(__PPC64__)
#define DAWN_PLATFORM_IS_PPC64 1
#else
#error "Unsupported platform."
#endif
// Define platform macros for pointer width:
//
// - 64_BIT
// - 32_BIT
#if defined(DAWN_PLATFORM_IS_X86_64) || defined(DAWN_PLATFORM_IS_ARM64) || \
defined(DAWN_PLATFORM_IS_RISCV64) || defined(DAWN_PLATFORM_IS_MIPS64) || \
defined(DAWN_PLATFORM_IS_S390X) || defined(DAWN_PLATFORM_IS_PPC64)
#define DAWN_PLATFORM_IS_64_BIT 1 #define DAWN_PLATFORM_IS_64_BIT 1
static_assert(sizeof(sizeof(char)) == 8, "Expect sizeof(size_t) == 8"); static_assert(sizeof(sizeof(char)) == 8, "Expect sizeof(size_t) == 8");
#elif defined(_WIN32) || defined(__arm__) || defined(__i386__) || defined(__mips32__) || \ #elif defined(DAWN_PLATFORM_IS_I386) || defined(DAWN_PLATFORM_IS_ARM32) || \
defined(__s390__) || defined(__EMSCRIPTEN__) defined(DAWN_PLATFORM_IS_RISCV32) || defined(DAWN_PLATFORM_IS_MIPS32) || \
defined(DAWN_PLATFORM_IS_S390) || defined(DAWN_PLATFORM_IS_PPC32) || \
defined(DAWN_PLATFORM_IS_EMSCRIPTEN)
#define DAWN_PLATFORM_IS_32_BIT 1 #define DAWN_PLATFORM_IS_32_BIT 1
static_assert(sizeof(sizeof(char)) == 4, "Expect sizeof(size_t) == 4"); static_assert(sizeof(sizeof(char)) == 4, "Expect sizeof(size_t) == 4");
#else #else
@ -118,6 +196,60 @@ static_assert(sizeof(sizeof(char)) == 4, "Expect sizeof(size_t) == 4");
#define DAWN_PLATFORM_IS_EMSCRIPTEN 0 #define DAWN_PLATFORM_IS_EMSCRIPTEN 0
#endif #endif
#if !defined(DAWN_PLATFORM_IS_X86)
#define DAWN_PLATFORM_IS_X86 0
#endif
#if !defined(DAWN_PLATFORM_IS_I386)
#define DAWN_PLATFORM_IS_I386 0
#endif
#if !defined(DAWN_PLATFORM_IS_X86_64)
#define DAWN_PLATFORM_IS_X86_64 0
#endif
#if !defined(DAWN_PLATFORM_IS_ARM)
#define DAWN_PLATFORM_IS_ARM 0
#endif
#if !defined(DAWN_PLATFORM_IS_ARM32)
#define DAWN_PLATFORM_IS_ARM32 0
#endif
#if !defined(DAWN_PLATFORM_IS_ARM64)
#define DAWN_PLATFORM_IS_ARM64 0
#endif
#if !defined(DAWN_PLATFORM_IS_RISCV)
#define DAWN_PLATFORM_IS_RISCV 0
#endif
#if !defined(DAWN_PLATFORM_IS_RISCV32)
#define DAWN_PLATFORM_IS_RISCV32 0
#endif
#if !defined(DAWN_PLATFORM_IS_RISCV64)
#define DAWN_PLATFORM_IS_RISCV64 0
#endif
#if !defined(DAWN_PLATFORM_IS_MIPS)
#define DAWN_PLATFORM_IS_MIPS 0
#endif
#if !defined(DAWN_PLATFORM_IS_MIPS32)
#define DAWN_PLATFORM_IS_MIPS32 0
#endif
#if !defined(DAWN_PLATFORM_IS_MIPS64)
#define DAWN_PLATFORM_IS_MIPS64 0
#endif
#if !defined(DAWN_PLATFORM_IS_S390)
#define DAWN_PLATFORM_IS_S390 0
#endif
#if !defined(DAWN_PLATFORM_IS_S390X)
#define DAWN_PLATFORM_IS_S390X 0
#endif
#if !defined(DAWN_PLATFORM_IS_PPC)
#define DAWN_PLATFORM_IS_PPC 0
#endif
#if !defined(DAWN_PLATFORM_IS_PPC64)
#define DAWN_PLATFORM_IS_PPC64 0
#endif
#if !defined(DAWN_PLATFORM_IS_64_BIT) #if !defined(DAWN_PLATFORM_IS_64_BIT)
#define DAWN_PLATFORM_IS_64_BIT 0 #define DAWN_PLATFORM_IS_64_BIT 0
#endif #endif
@ -125,10 +257,4 @@ static_assert(sizeof(sizeof(char)) == 4, "Expect sizeof(size_t) == 4");
#define DAWN_PLATFORM_IS_32_BIT 0 #define DAWN_PLATFORM_IS_32_BIT 0
#endif #endif
// Use #if DAWN_PLATFORM_IS(XXX) for platform specific code.
// Do not use #ifdef or the naked macro DAWN_PLATFORM_IS_XXX.
// This can help avoid common mistakes like not including "Platform.h" and falling into unwanted
// code block as usage of undefined macro "function" will be blocked by the compiler.
#define DAWN_PLATFORM_IS(X) (1 == DAWN_PLATFORM_IS_##X)
#endif // SRC_DAWN_COMMON_PLATFORM_H_ #endif // SRC_DAWN_COMMON_PLATFORM_H_