/** * forspll - LLVM-based Forsp compiler * Copyright (C) 2024 Clyne Sullivan * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ #include "llvm.hpp" LLVMState::LLVMState(): ctx(), modul("forsp", ctx), builder(ctx), inttype(llvm::Type::getInt32Ty(ctx)), stacktype(llvm::VectorType::get(inttype, 12, false)), ftype(llvm::FunctionType::get(llvm::Type::getVoidTy(ctx), {}, false)), one(llvm::ConstantInt::get(inttype, 1)), zero(llvm::ConstantInt::get(inttype, 0)) { auto zerovec = llvm::ConstantVector::get(llvm::ArrayRef(zero)); llvmSp = new llvm::GlobalVariable(modul, inttype, false, llvm::GlobalValue::ExternalLinkage, zero, "sp"); llvmStack = new llvm::GlobalVariable(modul, stacktype, false, llvm::GlobalValue::ExternalLinkage, zerovec, "stack"); } llvm::Value *LLVMState::createPush() { auto dspval = builder.CreateLoad(inttype, llvmSp); auto inc = builder.CreateAdd(dspval, one); builder.CreateStore(inc, llvmSp, false); return builder.CreateGEP(stacktype, llvmStack, {zero, dspval}); } llvm::Value *LLVMState::createPop() { auto dspval = builder.CreateLoad(inttype, llvmSp); auto dec = builder.CreateSub(dspval, one); builder.CreateStore(dec, llvmSp, false); return builder.CreateGEP(stacktype, llvmStack, {zero, dec}); } llvm::Function *LLVMState::createFunction(const std::string& name) { return llvm::Function::Create(ftype, llvm::Function::ExternalLinkage, name.c_str(), modul); } llvm::BasicBlock *LLVMState::createEntry(llvm::Function *func) { return llvm::BasicBlock::Create(ctx, "entry", func); } llvm::Value *LLVMState::createVariable(const std::string& name) { return new llvm::GlobalVariable(modul, inttype, false, llvm::GlobalValue::InternalLinkage, zero, name); } llvm::Constant *LLVMState::createInt(int n) { return llvm::ConstantInt::get(ctx, llvm::APInt(32, n, true)); } void LLVMState::output() { modul.print(llvm::outs(), nullptr); }