Skip to content
Merged
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
6 changes: 0 additions & 6 deletions .github/workflows/common-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,6 @@ jobs:
git -C third_party clone --depth 1 --branch v2.5.0 https://github.com/CLIUtils/CLI11.git || true
git -C third_party clone --depth 1 --branch v1.17.0 https://github.com/google/googletest.git || true

- name: Save third_party cache
uses: actions/cache@v3
with:
path: third_party
key: ${{ inputs.os }}-third_party

- name: ccache
uses: hendrikmuhs/ccache-action@v1.2

Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ output/
third_party/

# Default names
output.o
*.o
a.out
.python-version
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(boost)


# CLI11
FetchContent_Declare(
cli11
Expand Down Expand Up @@ -132,7 +131,7 @@ target_link_libraries(rcc PRIVATE
enable_testing()
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

add_executable(abi_test unittests/CodeGen/ABITest.cpp)
add_executable(abi_test unittests/CodeGen/X86_64ABITest.cpp)
target_link_libraries(abi_test PRIVATE GTest::gtest_main CodeGen ${llvm_libs})

include(GoogleTest)
Expand Down
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
Reaver C Compiler (`rcc`) is a C99 compiler. It features a lexer, parser,
preprocessor, AST, and compiles to LLVM IR. It supports both x86 and AArch64.


## Why?

For fun! We started [`v1.0`](https://github.com/saturn691/ReaverCompiler/tree/v1.0)
Expand Down Expand Up @@ -97,6 +96,23 @@ cd build
ctest
```

### Running Integration Tests

To run the provided integration tests, run the following command:

```bash
./test.py
```

To run the additional integration tests, run the following commands:

```bash
# Only run this once
git submodule update --init --recursive
# More options available. Does not pass all tests yet
./writing-a-c-compiler-tests/test_compiler --chapter 18 --skip-invaliid build/rcc
```

## Credits

- [William Huynh](https://www.linkedin.com/in/wh691/)
Expand Down
4 changes: 3 additions & 1 deletion include/AST/Type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ class FnType final : public Type<FnType>
bool operator<(const BaseType &other) const override;

bool isComplete() const noexcept override;
std::string getParamName(size_t i) const noexcept;
const BaseType *getParamType(size_t i) const noexcept;

Ptr<ParamType> params_;
Ptr<BaseType> retType_;
Expand All @@ -255,7 +257,7 @@ class ParamType final : public Type<ParamType>

bool isComplete() const noexcept override;

size_t size() const;
size_t size() const noexcept;
const BaseType *at(size_t i) const;

Params types_;
Expand Down
31 changes: 31 additions & 0 deletions include/CodeGen/AArch64ABI.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include "CodeGen/ABI.hpp"

namespace CodeGen
{

class AArch64ABI : public ABI
{
public:
AArch64ABI(llvm::Module &module);

FunctionParamsInfo getFunctionParams(
llvm::Type *retType,
std::vector<llvm::Type *> &paramTypes) const override;
llvm::FunctionType *getFunctionType(
llvm::Type *retType,
std::vector<llvm::Type *> &paramTypes) const override;
std::vector<llvm::Type *> getParamType(llvm::Type *type) const override;
llvm::Align getTypeAlign(llvm::Type *type) const override;
unsigned getTypeSize(AST::Types type) const override;

bool useByVal() const override
{
return false;
}

private:
llvm::Module &module_;
};
} // namespace CodeGen
41 changes: 1 addition & 40 deletions include/CodeGen/ABI.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,47 +38,8 @@ class ABI
virtual std::vector<llvm::Type *> getParamType(llvm::Type *type) const = 0;
virtual llvm::Align getTypeAlign(llvm::Type *type) const = 0;
virtual unsigned getTypeSize(AST::Types type) const = 0;
virtual bool useByVal() const = 0;
};

class X86_64ABI : public ABI
{
public:
enum class ArgClass
{
INTEGER, // Integral types that fit in one of the GP registers
SSE, // Types that fit into a vector register
SSEUP, // Tail part of SSE
X87, // 80-bit (rarely used in modern code), returned via x87 FPU
X87UP, // Tail part of X87
COMPLEX_X87, // Complex long double
MEMORY, // Passed by memory via the stack
NO_CLASS // Types that don't fit into any of the above
};

struct ArgClassInfo
{
ArgClass cls = ArgClass::NO_CLASS;
unsigned size = 0;
unsigned align = 0;
bool multiple = false;
};
using ArgClasses = std::vector<ArgClassInfo>;

X86_64ABI(llvm::Module &module);

FunctionParamsInfo getFunctionParams(
llvm::Type *retType,
std::vector<llvm::Type *> &paramTypes) const override;
llvm::FunctionType *getFunctionType(
llvm::Type *retType,
std::vector<llvm::Type *> &paramTypes) const override;
std::vector<llvm::Type *> getParamType(llvm::Type *type) const override;
llvm::Align getTypeAlign(llvm::Type *type) const override;
unsigned getTypeSize(AST::Types type) const override;

private:
ArgClasses getArgClassification(llvm::Type *type) const;
ArgClassInfo mergeClassifications(ArgClassInfo lhs, ArgClassInfo rhs) const;
llvm::Module &module_;
};
} // namespace CodeGen
6 changes: 4 additions & 2 deletions include/CodeGen/CodeGenModule.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
#include <unordered_map>

#include "AST/Visitor.hpp"
#include "CodeGen/ABI.hpp"
#include "CodeGen/AArch64ABI.hpp"
#include "CodeGen/TypeChecker.hpp"
#include "CodeGen/X86_64ABI.hpp"

#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
Expand All @@ -31,7 +32,8 @@ class CodeGenModule : public Visitor
CodeGenModule(
std::string sourceFile,
std::string outputFile,
TypeMap &typeMap);
TypeMap &typeMap,
std::string targetTriple);
void emitLLVM();
void emitObject();
void optimize();
Expand Down
54 changes: 54 additions & 0 deletions include/CodeGen/X86_64ABI.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#pragma once

#include "CodeGen/ABI.hpp"

namespace CodeGen
{

class X86_64ABI : public ABI
{
public:
enum class ArgClass
{
INTEGER, // Integral types that fit in one of the GP registers
SSE, // Types that fit into a vector register
SSEUP, // Tail part of SSE
X87, // 80-bit (rarely used in modern code), returned via x87 FPU
X87UP, // Tail part of X87
COMPLEX_X87, // Complex long double
MEMORY, // Passed by memory via the stack
NO_CLASS // Types that don't fit into any of the above
};

struct ArgClassInfo
{
ArgClass cls = ArgClass::NO_CLASS;
unsigned size = 0;
unsigned align = 0;
bool multiple = false;
};
using ArgClasses = std::vector<ArgClassInfo>;

X86_64ABI(llvm::Module &module);

FunctionParamsInfo getFunctionParams(
llvm::Type *retType,
std::vector<llvm::Type *> &paramTypes) const override;
llvm::FunctionType *getFunctionType(
llvm::Type *retType,
std::vector<llvm::Type *> &paramTypes) const override;
std::vector<llvm::Type *> getParamType(llvm::Type *type) const override;
llvm::Align getTypeAlign(llvm::Type *type) const override;
unsigned getTypeSize(AST::Types type) const override;

bool useByVal() const override
{
return true;
}

private:
ArgClasses getArgClassification(llvm::Type *type) const;
ArgClassInfo mergeClassifications(ArgClassInfo lhs, ArgClassInfo rhs) const;
llvm::Module &module_;
};
} // namespace CodeGen
12 changes: 11 additions & 1 deletion src/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,16 @@ bool FnType::isComplete() const noexcept
return retType_->isComplete() && params_->isComplete();
}

std::string FnType::getParamName(size_t i) const noexcept
{
return params_->types_.at(i).first;
}

const BaseType *FnType::getParamType(size_t i) const noexcept
{
return params_->types_.at(i).second.get();
}

ParamType::ParamType(Params types) : types_(std::move(types))
{
}
Expand Down Expand Up @@ -267,7 +277,7 @@ bool ParamType::isComplete() const noexcept
return true;
}

size_t ParamType::size() const
size_t ParamType::size() const noexcept
{
return types_.size();
}
Expand Down
Loading
Loading