Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ jobs:
matrix:
image:
- "clang:13"
- "gcc:11"
build_type: [Debug, Release]

runs-on: ubuntu-latest
Expand Down
1 change: 0 additions & 1 deletion include/lauf/asm/builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,4 +308,3 @@ void lauf_asm_inst_store_field(lauf_asm_builder* b, lauf_asm_type type, size_t f
LAUF_HEADER_END

#endif // LAUF_ASM_BUILDER_H_INCLUDED

1 change: 0 additions & 1 deletion include/lauf/asm/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,3 @@ bool lauf_asm_chunk_is_empty(const lauf_asm_chunk* chunk);
LAUF_HEADER_END

#endif // LAUF_ASM_MODULE_H_INCLUDED

44 changes: 33 additions & 11 deletions include/lauf/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,44 @@ typedef uint64_t lauf_uint;
# error "lauf assumes 8 bit bytes"
#endif

#if !defined(__clang__)
# error "lauf currently requires clang"
#endif

//=== optimizations ===//
#define LAUF_LIKELY(Cond) __builtin_expect((Cond), 1)
#define LAUF_UNLIKELY(Cond) __builtin_expect((Cond), 0)
#define LAUF_TAIL_CALL [[clang::musttail]]
#define LAUF_NOINLINE [[gnu::noinline]]
#define LAUF_FORCE_INLINE [[gnu::always_inline]]
#define LAUF_UNREACHABLE __builtin_unreachable()
#if defined(__GNUC__) || defined(__GNUG__)
# define LAUF_LIKELY(Cond) __builtin_expect((Cond), 1)
# define LAUF_UNLIKELY(Cond) __builtin_expect((Cond), 0)
# if defined(__has_cpp_attribute)
# if __has_cpp_attribute(clang::musttail)
# define LAUF_TAIL_CALL [[clang::musttail]]
# elif defined(__clang__)
# define LAUF_TAIL_CALL [[clang::musttail]]
# else
# define LAUF_TAIL_CALL
# endif
# endif
# define LAUF_NOINLINE [[gnu::noinline]]
# define LAUF_FORCE_INLINE [[gnu::always_inline]] inline
# define LAUF_UNREACHABLE __builtin_unreachable()
#endif

//=== configurations ===//
#ifndef LAUF_CONFIG_DISPATCH_JUMP_TABLE
# define LAUF_CONFIG_DISPATCH_JUMP_TABLE 1
#endif

#endif // LAUF_CONFIG_H_INCLUDED
#if defined(__has_cpp_attribute)
# if __has_cpp_attribute(clang::musttail)
# define LAUF_HAS_TAIL_CALL_ELIMINATION 1
# endif
#endif

//=== warnings ===//
#if !defined(__clang__) && (defined(__GNUC__) || defined(__GNUG__))
# define LAUF_BITFIELD_CONVERSION(...) \
_Pragma("GCC diagnostic push"); \
_Pragma("GCC diagnostic ignored \"-Wconversion\""); \
__VA_ARGS__; \
_Pragma("GCC diagnostic pop")
#else
# define LAUF_BITFIELD_CONVERSION(...) __VA_ARGS__
#endif

#endif // LAUF_CONFIG_H_INCLUDED
13 changes: 11 additions & 2 deletions include/lauf/runtime/builtin.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,17 @@

LAUF_HEADER_START

#define LAUF_RUNTIME_BUILTIN_IMPL __attribute__((section("text.lauf_builtin"), aligned(8)))
#if defined(__clang__)
# if defined(__APPLE__) && defined(__MACH__)
# define LAUF_RUNTIME_BUILTIN_IMPL __attribute__((section(".text,lauf_builtin"), aligned(8)))
# else
# define LAUF_RUNTIME_BUILTIN_IMPL __attribute__((section("text.lauf_builtin"), aligned(8)))
# endif
#elif defined(__GNUC__) || defined(__GNUG__)
# define LAUF_RUNTIME_BUILTIN_IMPL __attribute__((section(".text.lauf_builtin"), aligned(8)))
#else
# define LAUF_RUNTIME_BUILTIN_IMPL
#endif

typedef union lauf_asm_inst lauf_asm_inst;
typedef struct lauf_asm_type lauf_asm_type;
Expand Down Expand Up @@ -92,4 +102,3 @@ typedef struct lauf_runtime_builtin_library
LAUF_HEADER_END

#endif // LAUF_RUNTIME_BUILTIN_H_INCLUDED

19 changes: 10 additions & 9 deletions src/lauf/asm/builder.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (C) 2022-2023 Jonathan Müller and lauf contributors
// SPDX-License-Identifier: BSL-1.0

#include <algorithm>
#include <lauf/asm/builder.hpp>

#include <cstdio>
Expand Down Expand Up @@ -372,7 +373,7 @@ LAUF_NOINLINE lauf_asm_inst* emit_body(lauf_asm_inst* ip, lauf_asm_builder* b,
assert(insts[dest->offset].op() == lauf::asm_op::block);
auto dest_offset = dest->offset + 1;

jump->jump.offset = std::int32_t(dest_offset - cur_offset);
LAUF_BITFIELD_CONVERSION(jump->jump.offset = std::int32_t(dest_offset - cur_offset));
}

return ip;
Expand Down Expand Up @@ -437,7 +438,7 @@ void emit_debug_location(lauf_asm_builder* b)
for (auto loc : block.debug_locations)
{
// We also have the initial block instruction that affects the inst_idx.
loc.inst_idx += block.offset + 1;
loc.inst_idx += static_cast<uint16_t>(block.offset + 1);
cont.push_back(arena, loc);
}
}
Expand Down Expand Up @@ -489,8 +490,7 @@ bool lauf_asm_build_finish(lauf_asm_builder* b)
auto result = std::size_t(0);

for (auto& block : b->blocks)
if (block.vstack.max_size() > result)
result = block.vstack.max_size();
result = std::max(block.vstack.max_size(), result);

if (result > UINT16_MAX)
b->error(context, "per-function vstack size limit exceeded");
Expand Down Expand Up @@ -541,7 +541,7 @@ lauf_asm_local* lauf_asm_build_local(lauf_asm_builder* b, lauf_asm_layout layout

// The offset is the current size, we don't need to worry about alignment.
offset = std::uint16_t(b->local_allocation_size + sizeof(lauf_runtime_stack_frame));
b->local_allocation_size += layout.size;
b->local_allocation_size += static_cast<uint16_t>(layout.size);
}
else
{
Expand All @@ -553,7 +553,7 @@ lauf_asm_local* lauf_asm_build_local(lauf_asm_builder* b, lauf_asm_layout layout
// for a pointer.
// Since `layout.alignment` is a multiple of it (as a power of two bigger than it), and
// size a multiple of alignment, `layout.alignment + layout.size` is as well.
b->local_allocation_size += layout.alignment + layout.size;
b->local_allocation_size += static_cast<uint16_t>(layout.alignment + layout.size);
// Since we don't know the exact alignment offset, we can't compute it statically.
offset = UINT16_MAX;
}
Expand Down Expand Up @@ -708,6 +708,8 @@ const lauf_asm_block* lauf_asm_inst_branch(lauf_asm_builder* b, const lauf_asm_b
b->cur->next[0] = if_false;
b->cur->next[1] = if_true;
break;
default:
LAUF_UNREACHABLE;
}
}
else
Expand Down Expand Up @@ -1006,7 +1008,7 @@ void lauf_asm_inst_global_addr(lauf_asm_builder* b, const lauf_asm_global* globa
b->cur->insts.push_back(*b, LAUF_BUILD_INST_VALUE(global_addr, global->allocation_idx));
b->cur->vstack.push_constant(*b, [&] {
lauf_runtime_value result;
result.as_address.allocation = global->allocation_idx;
LAUF_BITFIELD_CONVERSION(result.as_address.allocation = global->allocation_idx);
result.as_address.offset = 0;
result.as_address.generation = 0; // Always true for globals.
return result;
Expand Down Expand Up @@ -1240,7 +1242,7 @@ void lauf_asm_inst_aggregate_member(lauf_asm_builder* b, size_t member_index,

namespace
{
enum load_store_constant
enum load_store_constant : uint8_t
{
load_store_dynamic,
load_store_local,
Expand Down Expand Up @@ -1381,4 +1383,3 @@ void lauf_asm_inst_store_field(lauf_asm_builder* b, lauf_asm_type type, size_t f
lauf_asm_inst_call_builtin(b, builtin);
}
}

17 changes: 8 additions & 9 deletions src/lauf/asm/builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#ifndef SRC_LAUF_ASM_BUILDER_HPP_INCLUDED
#define SRC_LAUF_ASM_BUILDER_HPP_INCLUDED

#include <algorithm>
#include <lauf/asm/builder.h>
#include <lauf/asm/instruction.hpp>
#include <lauf/asm/module.hpp>
Expand Down Expand Up @@ -32,7 +33,7 @@ class builder_vstack
public:
struct value
{
enum type_t
enum type_t : uint8_t
{
unknown,
constant,
Expand Down Expand Up @@ -66,8 +67,7 @@ class builder_vstack
void push(arena_base& arena, value v)
{
_stack.push_back(arena, v);
if (size() > _max)
_max = size();
_max = std::max(size(), _max);
}
void push_output(arena_base& arena, std::size_t n)
{
Expand Down Expand Up @@ -176,7 +176,7 @@ struct lauf_asm_block
lauf::array_list<lauf_asm_inst> insts;
lauf::array_list<lauf::inst_debug_location> debug_locations;

enum
enum : uint8_t
{
unterminated,
terminated,
Expand Down Expand Up @@ -262,14 +262,14 @@ struct lauf_asm_builder : lauf::intrinsic_arena<lauf_asm_builder>
{ \
if (LAUF_UNLIKELY(!(Cond))) \
b->error(LAUF_BUILD_ASSERT_CONTEXT, Msg); \
} while (0)
} while (false)

#define LAUF_BUILD_CHECK_CUR \
do \
{ \
if (LAUF_UNLIKELY(b->cur == nullptr)) \
return; \
} while (0)
} while (false)

//=== instruction building ===//
#define LAUF_BUILD_INST_NONE(Name) \
Expand All @@ -282,7 +282,7 @@ struct lauf_asm_builder : lauf::intrinsic_arena<lauf_asm_builder>
#define LAUF_BUILD_INST_OFFSET(Name, Offset) \
[&](const char* context, std::ptrdiff_t offset) { \
lauf_asm_inst result; \
result.Name = {lauf::asm_op::Name, std::int32_t(offset)}; \
LAUF_BITFIELD_CONVERSION(result.Name = {lauf::asm_op::Name, std::int32_t(offset)}); \
if (result.Name.offset != offset) \
b->error(context, "offset too big"); \
return result; \
Expand Down Expand Up @@ -315,7 +315,7 @@ struct lauf_asm_builder : lauf::intrinsic_arena<lauf_asm_builder>
#define LAUF_BUILD_INST_VALUE(Name, Value) \
[&](const char* context, std::size_t value) { \
lauf_asm_inst result; \
result.Name = {lauf::asm_op::Name, std::uint32_t(value)}; \
LAUF_BITFIELD_CONVERSION(result.Name = {lauf::asm_op::Name, std::uint32_t(value)}); \
if (value != result.Name.value) \
b->error(context, "invalid value"); \
return result; \
Expand All @@ -331,4 +331,3 @@ struct lauf_asm_builder : lauf::intrinsic_arena<lauf_asm_builder>
}(LAUF_BUILD_ASSERT_CONTEXT, Index)

#endif // SRC_LAUF_ASM_BUILDER_HPP_INCLUDED

19 changes: 10 additions & 9 deletions src/lauf/backend/qbe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@

namespace lauf
{
enum class qbe_type
enum class qbe_type : uint8_t
{
word,
long_,
single,
double_,
byte,
halfword,
word = 0,
long_ = 1,
single = 2,
double_ = 3,
byte = 4,
halfword = 5,

value = long_,
};
Expand Down Expand Up @@ -62,7 +62,7 @@ enum class qbe_block : std::size_t
{
};

enum class qbe_cc
enum class qbe_cc : uint8_t
{
ieq,
ine,
Expand Down Expand Up @@ -426,6 +426,7 @@ class qbe_writer
case qbe_type::halfword:
return "h";
}
LAUF_UNREACHABLE;
}

const char* cc_name(qbe_cc cc)
Expand Down Expand Up @@ -453,6 +454,7 @@ class qbe_writer
case qbe_cc::ugt:
return "ugt";
}
LAUF_UNREACHABLE;
}

lauf_writer* _writer;
Expand All @@ -462,4 +464,3 @@ class qbe_writer
} // namespace lauf

#endif // SRC_LAUF_BACKEND_QBE_HPP_INCLUDED

Loading